Skip to content

Commit

Permalink
added pow(interval, interval)
Browse files Browse the repository at this point in the history
  • Loading branch information
neilkichler committed Feb 28, 2024
1 parent 13d47ab commit ae3d7fe
Show file tree
Hide file tree
Showing 5 changed files with 4,155 additions and 1 deletion.
48 changes: 48 additions & 0 deletions include/cuinterval/arithmetic/basic.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,54 @@ __device__ interval<T> pown(interval<T> x, std::integral auto n)
}
}

template<typename T>
__device__ interval<T> pow_(interval<T> x, T y)
{
assert(inf(x) >= 0);

using intrinsic::next_floating;
using intrinsic::prev_floating;

if (sup(x) == 0) {
if (y > 0) {
return { 0, 0 };
} else {
return empty<T>();
}
} else {
if (rint(y) == y) {
return pown(x, lrint(y));
} else if (y == 0.5) {
return sqrt(x);
} else {
interval<T> lb { prev_floating(pow(inf(x), y)), next_floating(pow(inf(x), y))};
interval<T> ub { prev_floating(pow(sup(x), y)), next_floating(pow(sup(x), y))};
return convex_hull(lb, ub);
}
}

return {};
}

template<typename T>
__device__ interval<T> pow(interval<T> x, interval<T> y)
{
if (empty(y)) {
return empty<T>();
}

interval<T> domain { static_cast<T>(0), intrinsic::pos_inf<T>() };
x = intersection(x, domain);

if (empty(x)) {
return empty<T>();
} else if (y.lb == y.ub) {
return pow_(x, y.ub);
} else {
return convex_hull(pow_(x, y.lb), pow_(x, y.ub));
}
}

template<typename T>
__device__ unsigned int quadrant(T v) {
int quotient;
Expand Down
1 change: 1 addition & 0 deletions tests/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def convert_to_test(file_path):
"sinpi": {"args": [I], "ret": I, "ulp_error": 3},
"cospi": {"args": [I], "ret": I, "ulp_error": 3},
"pown": {"args": [I, N], "ret": I, "ulp_error": 1},
"pow": {"args": [I, I], "ret": I, "ulp_error": 1},
# "cot": {"args": [I], "ret": I, "ulp_error": 4},
}

Expand Down
9 changes: 9 additions & 0 deletions tests/test_ops.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -634,4 +634,13 @@ __global__ void test_pown(int n, interval<T> *x, int *n_pow, interval<T> *res)
}
}

template<typename T>
__global__ void test_pow(int n, interval<T> *x, interval<T> *y, interval<T> *res)
{
int i = threadIdx.x + blockIdx.x * blockDim.x;
if (i < n) {
res[i] = pow(x[i], y[i]);
}
}

#endif // TEST_OPS_CUH
35 changes: 35 additions & 0 deletions tests/tests_c_xsc.cu
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,41 @@ void tests_c_xsc() {
}
};

"cxsc.intervalstdfunc_pow"_test = [&] {
constexpr int n = 2;
std::array<I, n> h_xs {{
{2.0,2.0},
{4.0,4.0},
}};

std::array<I, n> h_ys {{
{2.0,2.0},
{5.0,5.0},
}};

std::array<I, n> h_res{};
I *d_res = (I *)d_res_;
I *d_xs = (I *)d_xs_;
I *d_ys = (I *)d_ys_;
int n_result_bytes = n * sizeof(I);
std::array<I, n> h_ref {{
{4.0,4.0},
{1024.0,1024.0},
}};

CUDA_CHECK(cudaMemcpy(d_xs, h_xs.data(), n_bytes, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaMemcpy(d_ys, h_ys.data(), n_bytes, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaMemcpy(d_res, h_res.data(), n_result_bytes, cudaMemcpyHostToDevice));
test_pow<<<numBlocks, blockSize>>>(n, d_xs, d_ys, d_res);
CUDA_CHECK(cudaMemcpy(h_res.data(), d_res, n_result_bytes, cudaMemcpyDeviceToHost));
int max_ulp_diff = 1;
auto failed = check_all_equal<I, n>(h_res, h_ref, max_ulp_diff);
for (auto fail_id : failed) {
printf("failed at case %zu:\n", fail_id);
printf("x = [%a, %a]\ny = [%a, %a]\n", h_xs[fail_id].lb, h_xs[fail_id].ub, h_ys[fail_id].lb, h_ys[fail_id].ub);
}
};

"cxsc.intervalstdfunc_sqr"_test = [&] {
constexpr int n = 3;
std::array<I, n> h_xs {{
Expand Down
Loading

0 comments on commit ae3d7fe

Please sign in to comment.