Skip to content

Commit

Permalink
Make clip() available to all models in the kernel header.
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Kienzle committed Sep 3, 2024
1 parent f2405b3 commit 3023920
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 20 deletions.
2 changes: 2 additions & 0 deletions doc/guide/plugin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,8 @@ Some non-standard constants and functions are also provided:
$x^2$
cube(x):
$x^3$
clip(a, a_min, a_max):
$\min(\max(a, a_\text{min}), a_\text{max})$, or NaN if $a$ is NaN.
sas_sinx_x(x):
$\sin(x)/x$, with limit $\sin(0)/0 = 1$.
powr(x, y):
Expand Down
5 changes: 5 additions & 0 deletions sasmodels/kernel_header.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@
#endif
inline double square(double x) { return x*x; }
inline double cube(double x) { return x*x*x; }
// clip() follows numpy.clip() semantics, returning (x < low ? low : x > high ? high : x)
// OpenCL/CUDA clamp() returns fmin(fmax(x, low), high)
// C++(17) clamp() matches numpy.clip()
// If x is NaN numpy.clip() returns NaN but OpenCL clamp() returns low.
inline double clip(double x, double low, double high) { return x < low ? low : x > high ? high : x; }
inline double sas_sinx_x(double x) { return x==0 ? 1.0 : sin(x)/x; }

// CRUFT: support old style models with orientation received qx, qy and angles
Expand Down
6 changes: 0 additions & 6 deletions sasmodels/kernel_iq.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,6 @@ void ORTH_VEC(double *result_vec, double *vec1, double *vec2)
}


// Return value restricted between low and high
static double clip(double value, double low, double high)
{
return (value < low ? low : (value > high ? high : value));
}

// Compute spin cross sections given in_spin and out_spin
// To convert spin cross sections to sld b:
// uu * (sld - m_perp_x);
Expand Down
14 changes: 2 additions & 12 deletions sasmodels/models/lib/magnetic_functions.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
static double clipp(double value, double low, double high) //from kernel_iq.c
{
return (value < low ? low : (value > high ? high : value));
}

static double length(double x, double y)
{
return sqrt(x*x + y*y);
}

static double fq_core_shell(double q, double sld_core, double radius,
double sld_solvent, double fp_n, double sld[], double thickness[])
{
Expand Down Expand Up @@ -56,8 +46,8 @@ static void set_weights(double in_spin, double out_spin, double weight[8]) //fro
double norm=out_spin;


in_spin = clipp(sqrt(square(in_spin)), 0.0, 1.0);//opencl has ambiguities for abs()
out_spin = clipp(sqrt(square(out_spin)), 0.0, 1.0);
in_spin = clip(sqrt(square(in_spin)), 0.0, 1.0);//opencl has ambiguities for abs()
out_spin = clip(sqrt(square(out_spin)), 0.0, 1.0);

if (out_spin < 0.5){norm=1-out_spin;}

Expand Down
16 changes: 15 additions & 1 deletion sasmodels/models/sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
have_Fq = True
radius_effective_modes = ["radius"]
#single = False

def random():
"""Return a random parameter set for the model."""
radius = 10**np.random.uniform(1.3, 4)
Expand Down Expand Up @@ -106,6 +105,21 @@ def random():
0.1, 482.93824329, 29763977.79867414, 120.0, 8087664.122641933, 1.0],
[{"radius": 120., "radius_pd": 0.2, "radius_pd_n": 45},
0.2, 1.23330406, 1850806.1197361, 120.0, 8087664.122641933, 1.0],

# For 2-D data use (qx, qy) pairs. Since sphere is radial, just need the
# correct |q| value for the test, so use 3-4-5 triangle. The test code
# looks for tuples to detect 2-D data, so can't use simple numpy cheats.
[{"scale": 1., "background": 0., "sld": 6., "sld_solvent": 1.,
"radius": 120.},
[(0.006, 0.008), (0.06,0.08), (0.12, 0.16)],
[1.34836265e+04, 6.20114062e+00, 1.04733914e-01]],

# TODO: magnetism smoke test. Values not validated.
[dict(radius=120, sld_M0=4, sld_mphi=20, sld_mtheta=60,
up_frac_i=0.05, up_frac_f=0.1, up_theta=-15, up_phi=10),
[(0.0, 0.01), (0.0, 0.1), (0.0, 0.2)],
[20247.206006297125, 9.312720770235483, 0.15826993186001856]],

# But note P(Q) = F2/volume
# F and F^2 are "unscaled", with for n <F F*>S(q) or for beta approx
# I(q) = n [<F F*> + <F><F*> (S(q) - 1)]
Expand Down
5 changes: 4 additions & 1 deletion sasmodels/special.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
cube(x):
$x^3$
clip(a, a_min, a_max):
$\min(\max(a, a_\text{min}), a_\text{max})$, or NaN if $a$ is NaN.
sas_sinx_x(x):
$\sin(x)/x$, with limit $\sin(0)/0 = 1$.
Expand Down Expand Up @@ -215,7 +218,7 @@
from numpy import sin, cos, tan, arcsin as asin, arccos as acos, arctan as atan
from numpy import sinh, cosh, tanh, arcsinh as asinh, arccosh as acosh, arctanh as atanh
from numpy import arctan2 as atan2
from numpy import fabs, fmin, fmax, trunc, rint
from numpy import fabs, fmin, fmax, clip, trunc, rint
from numpy import pi, nan, inf
from scipy.special import gamma as sas_gamma
from scipy.special import gammaln as sas_gammaln
Expand Down

0 comments on commit 3023920

Please sign in to comment.