20 #ifndef __MATHEMATICS_H_
21 #define __MATHEMATICS_H_
32 #ifndef _USE_MATH_DEFINES
33 #define _USE_MATH_DEFINES
39 #include <sys/types.h>
54 #define cygwin_log2 log2
59 #define M_PI 3.14159265358979323846
68 #define isfinite _isfinite
73 #define RNG_SEED_SIZE 256
76 #define RADIX_STACK_SIZE 512
79 #define radix_push(a, n, i) sp->sa = a, sp->sn = n, (sp++)->si = i
80 #define radix_pop(a, n, i) a = (--sp)->sa, n = sp->sn, i = sp->si
82 #ifndef DOXYGEN_SHOULD_SKIP_THIS
84 template <
class T>
struct radix_stack_t
97 template <
class T1,
class T2>
struct thread_qsort
107 int32_t* qsort_threads;
113 #endif // DOXYGEN_SHOULD_SKIP_THIS
115 #define COMPLEX128_ERROR_ONEARG(function) \
116 static inline complex128_t function(complex128_t a) \
118 SG_SERROR("CMath::%s():: Not supported for complex128_t\n",\
120 return complex128_t(0.0, 0.0); \
123 #define COMPLEX128_STDMATH(function) \
124 static inline complex128_t function(complex128_t a) \
126 return std::function(a); \
156 static inline T
min(T a, T b)
158 return (a<=b) ? a : b;
163 static inline T
max(T a, T b)
165 return (a>=b) ? a : b;
171 static T
min(T* vec, int32_t len)
176 for (int32_t i=1; i<len; i++)
177 minv=
min(vec[i], minv);
185 static T
max(T* vec, int32_t len)
190 for (int32_t i=1; i<len; i++)
191 maxv=
max(vec[i], maxv);
198 static inline T
clamp(T value, T lb, T ub)
233 static int32_t
arg_max(T * vec, int32_t inc, int32_t len, T * maxv_ptr = NULL)
235 ASSERT(len > 0 || inc > 0)
240 for (int32_t i = 1, j = inc ; i < len ; i++, j += inc)
243 maxv = vec[j], maxIdx = i;
246 if (maxv_ptr != NULL)
255 static int32_t
arg_min(T * vec, int32_t inc, int32_t len, T * minv_ptr = NULL)
257 ASSERT(len > 0 || inc > 0)
262 for (int32_t i = 1, j = inc ; i < len ; i++, j += inc)
265 minv = vec[j], minIdx = i;
268 if (minv_ptr != NULL)
287 const T diff = CMath::abs<T>((a-b));
301 static inline bool fequals(
const T& a,
const T& b,
302 const float64_t eps,
bool tolerant=
false)
304 const T absA = CMath::abs<T>(a);
305 const T absB = CMath::abs<T>(b);
306 const T diff = CMath::abs<T>((a-b));
315 return CMath::fequals_abs<T>(a, b, eps);
328 else if ( (a==0) || (b==0) || (diff < comp) )
329 return (diff<(eps * comp));
334 T check = ((diff/(absA + absB)) > diff)?
335 (diff/(absA + absB)):diff;
336 return (check < eps);
362 return ::floor(d+0.5);
381 else return (a<0) ? (-1) : (+1);
386 static inline void swap(T &a,T &b)
395 static inline T
sq(T x)
442 tmp.i = 0x5f3759d5 - (tmp.i >> 1);
444 x = x*(1.5f - xhalf*x*x);
454 return ::powl((
long double) x, (
long double) n);
456 return ::pow((
double) x, (
double) n);
460 static inline int32_t
pow(
bool x, int32_t n)
465 static inline int32_t
pow(int32_t x, int32_t n)
486 return ::pow((
double)x, (
double)n);
491 return ::pow((
double) x, (
double) n);
497 return std::pow(x, n);
502 return std::pow(x, n);
507 return std::pow(x, n);
512 return std::pow(x, n);
517 return ::exp((
double) x);
526 return ::tan((
double) x);
535 return ::atan((
double) x);
544 return ::atan2((
double) x, (
double) y);
553 return ::tanh((
double) x);
561 return ::log(v)/
::log(10.0);
572 return ::log(v)/
::log(2.0);
587 for (i = 0; n != 0; i++)
649 for (
int i=1; i<len; i++)
650 area += 0.5*(xy[2*i]-xy[2*(i-1)])*(xy[2*i+1]+xy[2*(i-1)+1]);
654 for (
int i=1; i<len; i++)
655 area += 0.5*(xy[2*i+1]-xy[2*(i-1)+1])*(xy[2*i]+xy[2*(i-1)]);
668 for (
int i=2; i<=n; i++)
680 sg_rand->set_seed(
seed);
685 return sg_rand->random_64();
688 static inline uint64_t
random(uint64_t min_value, uint64_t max_value)
690 return sg_rand->random(min_value, max_value);
693 static inline int64_t
random(int64_t min_value, int64_t max_value)
695 return sg_rand->random(min_value, max_value);
698 static inline uint32_t
random(uint32_t min_value, uint32_t max_value)
700 return sg_rand->random(min_value, max_value);
703 static inline int32_t
random(int32_t min_value, int32_t max_value)
705 return sg_rand->random(min_value, max_value);
710 return sg_rand->random(min_value, max_value);
715 return sg_rand->random(min_value, max_value);
720 return sg_rand->random(min_value, max_value);
737 rand_s = rand_u*rand_u + rand_v*rand_v;
738 }
while ((rand_s == 0) || (rand_s >= 1));
741 ret = rand_u*
sqrt(-2.0*
log(rand_s)/rand_s);
742 ret = std_dev*ret + mean;
751 return sg_rand->normal_distrib(mean, std_dev);
765 return sg_rand->std_normal_distrib();
780 swap(v[i], v[rand->random(i, v.
vlen-1)]);
807 static inline int64_t
nchoosek(int32_t n, int32_t k)
811 for (int32_t i=n-k+1; i<=n; i++)
865 REQUIRE(values.
vlen>0,
"number of values supplied is 0\n");
886 for (from_idx=0; from_idx<values.
vlen; ++from_idx)
888 if (from_idx!=min_index)
890 values_without_X0[to_idx]=
exp(values[from_idx]-X0);
913 static void sort(int32_t *a, int32_t cols, int32_t sort_col=0);
919 static void qsort(T* output, int32_t size)
926 if (output[0] > output [1])
931 T
split=output[size/2];
934 int32_t right=size-1;
938 while (output[left] < split)
940 while (output[right] > split)
952 qsort(output,right+1);
955 qsort(&output[left],size-left);
963 for (int32_t i=0; i<size-1; i++)
967 while (j >= 0 && output[j] > value)
969 output[j+1] = output[j];
989 static inline uint8_t
byte(T word, uint16_t p)
991 return (word >> (
sizeof(T)-p-1) * 8) & 0xff;
997 SG_SERROR(
"CMath::byte():: Not supported for complex128_t\n");
1004 static size_t count[256], nc, cmin;
1008 T *an, *aj, *pile[256];
1023 for (ak = array; ak < an; ak++) {
1026 if (count[c] == 1) {
1051 for (cp = count + cmin; nc > 0; cp++) {
1063 if (i <
sizeof(T)-1)
1066 pile[cp - count] = ak += *cp;
1090 for (r = *aj; aj < (ak = --pile[c =
byte(r, i)]);)
1103 SG_SERROR(
"CMath::radix_sort_helper():: Not supported for complex128_t\n");
1123 if (*vector[0]>*vector[1])
1124 swap(vector[0],vector[1]);
1127 T*
split=vector[length/2];
1130 int32_t right=length-1;
1134 while (*vector[left]<*split)
1136 while (*vector[right]>*split)
1141 swap(vector[left],vector[right]);
1148 qsort(vector,right+1);
1151 qsort(&vector[left],length-left);
1157 SG_SERROR(
"CMath::qsort():: Not supported for complex128_t\n");
1161 template <
class T>
static void display_bits(T word, int32_t width=8*
sizeof(T))
1164 for (
int i=0; i<width; i++)
1166 T mask = ((T) 1)<<(
sizeof(T)*8-1);
1183 SG_SERROR(
"CMath::display_bits():: Not supported for complex128_t\n");
1191 template <
class T1,
class T2>
1192 static void qsort_index(T1* output, T2* index, uint32_t size);
1198 SG_SERROR(
"CMath::qsort_index():: Not supported for complex128_t\n");
1206 template <
class T1,
class T2>
1208 T1* output, T2* index, int32_t size);
1215 SG_SERROR(
"CMath::qsort_backword_index():: \
1216 Not supported for complex128_t\n");
1226 template <
class T1,
class T2>
1227 inline static void parallel_qsort_index(T1* output, T2* index, uint32_t size, int32_t n_threads, int32_t limit=262144)
1230 thread_qsort<T1,T2> t;
1236 t.num_threads=n_threads;
1237 parallel_qsort_index<T1,T2>(&t);
1243 uint32_t size, int32_t n_threads, int32_t limit=0)
1245 SG_SERROR(
"CMath::parallel_qsort_index():: Not supported for complex128_t\n");
1249 template <
class T1,
class T2>
1256 static void min(
float64_t* output, T* index, int32_t size);
1261 SG_SERROR(
"CMath::min():: Not supported for complex128_t\n");
1268 float64_t* output, T* index, int32_t size, int32_t n);
1272 int32_t size, int32_t n)
1274 SG_SERROR(
"CMath::nmin():: Not supported for complex128_t\n");
1292 int32_t middle=(start+end)/2;
1294 if (output[middle]>elem)
1296 else if (output[middle]<elem)
1308 SG_SERROR(
"CMath::binary_search_helper():: Not supported for complex128_t\n");
1318 if (ind >= 0 && output[ind] == elem)
1326 SG_SERROR(
"CMath::binary_search():: Not supported for complex128_t\n");
1343 int32_t end=length-1;
1350 int32_t middle=(start+end)/2;
1352 if (*vector[middle]>*elem)
1354 else if (*vector[middle]<*elem)
1363 if (start>=0&&*vector[start]==*elem)
1372 SG_SERROR(
"CMath::binary_search():: Not supported for complex128_t\n");
1378 T* output, int32_t size, T elem)
1382 if (output[ind]<=elem)
1384 if (ind>0 && output[ind-1] <= elem)
1393 SG_SERROR(
"CMath::binary_search_max_lower_equal():: \
1394 Not supported for complex128_t\n");
1401 char * seq1,
char* seq2, int32_t l1, int32_t l2,
float64_t gapCost);
1431 inline static uint32_t get_log_accuracy()
1434 return CMath::LOGACCURACY;
1445 static int is_nan(
double f);
1467 SG_SWARNING(
"INVALID second operand to logsum(%f,%f) expect undefined results\n", p, q)
1472 return diff >
LOGRANGE? p : p + logtable[(
int)(diff * LOGACCURACY)];
1473 return -diff >
LOGRANGE? q : q + logtable[(
int)(-diff * LOGACCURACY)];
1477 static
void init_log_table();
1480 static int32_t determine_logrange();
1483 static int32_t determine_logaccuracy(int32_t range);
1500 #ifdef USE_LOGSUMARRAY
1506 static inline float64_t logarithmic_sum_array(
1520 if (len%2==1) pp++ ;
1521 for (int32_t j=0; j < len>>1; j++)
1524 return logarithmic_sum_array(p,len%2 + (len>>1)) ;
1526 #endif //USE_LOGSUMARRAY
1530 virtual const char*
get_name()
const {
return "Math"; }
1573 static int32_t LOGACCURACY;
1581 template <
class T1,
class T2>
1584 struct thread_qsort<T1,T2>* ps=(thread_qsort<T1,T2>*) p;
1585 T1* output=ps->output;
1586 T2* index=ps->index;
1587 int32_t size=ps->size;
1588 int32_t* qsort_threads=ps->qsort_threads;
1589 int32_t sort_limit=ps->sort_limit;
1590 int32_t num_threads=ps->num_threads;
1599 if (output[0] > output [1])
1601 swap(output[0], output[1]);
1602 swap(index[0], index[1]);
1607 T1
split=output[size/2];
1610 int32_t right=size-1;
1614 while (output[left] < split)
1616 while (output[right] > split)
1621 swap(output[left], output[right]);
1622 swap(index[left], index[right]);
1627 bool lthread_start=
false;
1628 bool rthread_start=
false;
1631 struct thread_qsort<T1,T2> t1;
1632 struct thread_qsort<T1,T2> t2;
1634 if (right+1> 1 && (right+1< sort_limit || *qsort_threads >= num_threads-1))
1636 else if (right+1> 1)
1643 t1.qsort_threads=qsort_threads;
1644 t1.sort_limit=sort_limit;
1645 t1.num_threads=num_threads;
1646 if (pthread_create(<hread, NULL, parallel_qsort_index<T1,T2>, &t1) != 0)
1648 lthread_start=
false;
1655 if (size-left> 1 && (size-left< sort_limit || *qsort_threads >= num_threads-1))
1656 qsort_index(&output[left],&index[left], size-left);
1657 else if (size-left> 1)
1661 t2.output=&output[left];
1662 t2.index=&index[left];
1664 t2.qsort_threads=qsort_threads;
1665 t2.sort_limit=sort_limit;
1666 t2.num_threads=num_threads;
1667 if (pthread_create(&rthread, NULL, parallel_qsort_index<T1,T2>, &t2) != 0)
1669 rthread_start=
false;
1671 qsort_index(&output[left],&index[left], size-left);
1677 pthread_join(lthread, NULL);
1683 pthread_join(rthread, NULL);
1690 template <
class T1,
class T2>
1698 if (output[0] > output [1])
1700 swap(output[0],output[1]);
1701 swap(index[0],index[1]);
1706 T1
split=output[size/2];
1709 int32_t right=size-1;
1713 while (output[left] < split)
1715 while (output[right] > split)
1720 swap(output[left],output[right]);
1721 swap(index[left],index[right]);
1731 qsort_index(&output[left],&index[left], size-left);
1734 template <
class T1,
class T2>
1742 if (output[0] < output [1])
1744 swap(output[0],output[1]);
1745 swap(index[0],index[1]);
1751 T1
split=output[size/2];
1754 int32_t right=size-1;
1758 while (output[left] > split)
1760 while (output[right] < split)
1765 swap(output[left],output[right]);
1766 swap(index[left],index[right]);
1783 for (int32_t i=0; i<n; i++)
1784 min(&output[i], &index[i], size-i);
1796 int32_t min_index=0;
1797 for (int32_t i=1; i<size; i++)
1799 if (output[i]<min_elem)
1805 swap(output[0], output[min_index]);
1806 swap(index[0], index[min_index]);
1812 SG_SERROR(
"SGVector::linspace():: Not supported for complex128_t\n");
1816 #define COMPLEX128_ERROR_ONEARG_T(function) \
1818 inline complex128_t CMath::function<complex128_t>(complex128_t a) \
1820 SG_SERROR("CMath::%s():: Not supported for complex128_t\n",\
1822 return complex128_t(0.0, 0.0); \
1825 #define COMPLEX128_ERROR_TWOARGS_T(function) \
1827 inline complex128_t CMath::function<complex128_t>(complex128_t a, complex128_t b) \
1829 SG_SERROR("CMath::%s():: Not supported for complex128_t\n",\
1831 return complex128_t(0.0, 0.0); \
1834 #define COMPLEX128_ERROR_THREEARGS_T(function) \
1836 inline complex128_t CMath::function<complex128_t>(complex128_t a, complex128_t b, complex128_t c) \
1838 SG_SERROR("CMath::%s():: Not supported for complex128_t\n",\
1840 return complex128_t(0.0, 0.0); \
1843 #define COMPLEX128_ERROR_SORT_T(function) \
1845 inline void CMath::function<complex128_t>(complex128_t* output, int32_t b) \
1847 SG_SERROR("CMath::%s():: Not supported for complex128_t\n",\
1851 #define COMPLEX128_ERROR_ARG_MAX_MIN(function) \
1853 inline int32_t CMath::function<complex128_t>(complex128_t * a, int32_t b, int32_t c, complex128_t * d) \
1856 SG_SERROR("CMath::%s():: Not supported for complex128_t\n",\
1889 #undef COMPLEX128_ERROR_ONEARG
1890 #undef COMPLEX128_ERROR_ONEARG_T
1891 #undef COMPLEX128_ERROR_TWOARGS_T
1892 #undef COMPLEX128_ERROR_THREEARGS_T
1893 #undef COMPLEX128_STDMATH
1894 #undef COMPLEX128_ERROR_SORT_T
static float64_t sin(float64_t x)
static float64_t normal_random(float64_t mean, float64_t std_dev)
static const float32_t F_MAX_VAL32
static const float64_t MACHINE_EPSILON
static bool strtof(const char *str, float32_t *float_result)
static void permute(SGVector< T > v, CRandom *rand=NULL)
static int32_t binary_search(complex128_t *output, int32_t size, complex128_t elem)
binary_search not implemented for complex128_t
static void parallel_qsort_index(T1 *output, T2 *index, uint32_t size, int32_t n_threads, int32_t limit=262144)
static uint32_t seed
random generator seed
std::complex< float64_t > complex128_t
static int is_finite(double f)
checks whether a float is finite
static float64_t Align(char *seq1, char *seq2, int32_t l1, int32_t l2, float64_t gapCost)
static int32_t arg_max(T *vec, int32_t inc, int32_t len, T *maxv_ptr=NULL)
static float64_t sqrt(float64_t x)
x^0.5
static floatmax_t random(floatmax_t min_value, floatmax_t max_value)
static floatmax_t sqrt(floatmax_t x)
x^0.5
static void linspace(float64_t *output, float64_t start, float64_t end, int32_t n=100)
static float64_t ceil(float64_t d)
static bool strtod(const char *str, float64_t *double_result)
static complex128_t pow(complex128_t x, int32_t n)
x^n, x or n being a complex128_t
virtual ~CMath()
Destructor - frees logtable.
static const float64_t INFTY
infinity
static SGVector< float64_t > linspace_vec(T start, T end, int32_t n)
static int32_t binary_search_helper(T *output, int32_t size, T elem)
#define COMPLEX128_ERROR_THREEARGS_T(function)
static void nmin(float64_t *output, T *index, int32_t size, int32_t n)
static void qsort_index(T1 *output, T2 *index, uint32_t size)
static void qsort_index(complex128_t *output, T *index, uint32_t size)
qsort_index not implemented for complex128_t
static float64_t log10(float64_t v)
tanh(x), x being a complex128_t
#define COMPLEX128_ERROR_TWOARGS_T(function)
static float32_t normal_random(float32_t mean, float32_t std_dev)
static float64_t random(float64_t min_value, float64_t max_value)
static int32_t binary_search(T *output, int32_t size, T elem)
static uint32_t get_seed()
returns number generator seed
#define COMPLEX128_ERROR_ARG_MAX_MIN(function)
static float32_t randn_float()
static const float64_t MIN_REAL_NUMBER
static float64_t randn_double()
static int32_t binary_search_max_lower_equal(T *output, int32_t size, T elem)
static float64_t atan(float64_t x)
tan(x), x being a complex128_t
static const float64_t F_MAX_VAL64
static float64_t cosh(float64_t x)
acos(x), x being a complex128_t not implemented
static uint32_t get_log_range()
returns range of logtable
void split(v_array< ds_node< P > > &point_set, v_array< ds_node< P > > &far_set, int max_scale)
static float32_t random(float32_t min_value, float32_t max_value)
static const float32_t F_MIN_VAL32
static bool fequals_abs(const T &a, const T &b, const float64_t eps)
static float64_t get_abs_tolorance(float64_t true_value, float64_t rel_tolorance)
static float64_t imag(complex128_t c)
returns imag part of a complex128_t number
static float64_t floor(float64_t d)
static float64_t * linspace(T start, T end, int32_t n)
static int32_t get_num_nonzero(complex128_t *vec, int32_t len)
static const float32_t F_MIN_NORM_VAL32
static float64_t real(complex128_t c)
returns real part of a complex128_t number
static uint8_t byte(complex128_t word, uint16_t p)
byte not implemented for complex128_t
static void qsort(T *output, int32_t size)
static int32_t LOGRANGE
range for logtable: log(1+exp(x)) -LOGRANGE <= x <= 0
static const float64_t ALMOST_NEG_INFTY
almost neg (log) infinity
static bool fequals(const T &a, const T &b, const float64_t eps, bool tolerant=false)
static complex128_t pow(complex128_t x, complex128_t n)
static float32_t invsqrt(float32_t x)
x^0.5, x being a complex128_t
static uint8_t byte(T word, uint16_t p)
static complex128_t pow(float64_t x, complex128_t n)
CMath()
Constructor - initializes log-table.
static float64_t pow(float64_t x, int32_t n)
Class SGObject is the base class of all shogun objects.
static int32_t random(int32_t min_value, int32_t max_value)
static float64_t pow(float64_t x, float64_t n)
static void qsort(T **vector, index_t length)
static void init_random(uint32_t initseed=0)
static int32_t pow(int32_t x, int32_t n)
#define radix_pop(a, n, i)
static void parallel_qsort_index(complex128_t *output, T *index, uint32_t size, int32_t n_threads, int32_t limit=0)
parallel_qsort_index not implemented for complex128_t
static void min(float64_t *output, complex128_t *index, int32_t size)
complex128_t cannot be used as index
#define COMPLEX128_ERROR_ONEARG(function)
static float64_t cos(float64_t x)
sinh(x), x being a complex128_t
static void qsort_backword_index(complex128_t *output, T *index, uint32_t size)
qsort_backword_index not implemented for complex128_t
static int32_t get_num_nonzero(T *vec, int32_t len)
static T log_sum_exp(SGVector< T > values)
static T max(T a, T b)
return the maximum of two integers
static float64_t area_under_curve(float64_t *xy, int32_t len, bool reversed)
cosh(x), x being a complex128_t
static void display_bits(T word, int32_t width=8 *sizeof(T))
display bits (useful for debugging)
static uint64_t random(uint64_t min_value, uint64_t max_value)
static int64_t factorial(int32_t n)
static void qsort(complex128_t **vector, index_t length)
qsort not implemented for complex128_t
static float64_t atan2(float64_t x, float64_t y)
atan(x), x being a complex128_t not implemented
static int32_t arg_min(T *vec, int32_t inc, int32_t len, T *minv_ptr=NULL)
return arg_min(vec)
static float64_t tan(float64_t x)
exp(x), x being a complex128_t
static int32_t binary_search_max_lower_equal(complex128_t *output, int32_t size, complex128_t elem)
binary_search_max_lower_equal not implemented for complex128_t
static float64_t sinh(float64_t x)
asin(x), x being a complex128_t not implemented
: Pseudo random number geneartor
static int64_t nchoosek(int32_t n, int32_t k)
static T min(T *vec, int32_t len)
return the smallest element in a vector.
all of classes and functions are contained in the shogun namespace
static int32_t binary_search(T **vector, index_t length, T *elem)
static int is_infinity(double f)
checks whether a float is infinity
static float64_t acos(float64_t x)
cos(x), x being a complex128_t
static float64_t abs(complex128_t a)
return the absolute value of a complex number
static float64_t log2(float64_t v)
log10(x), x being a complex128_t
static void display_bits(complex128_t word, int32_t width=8 *sizeof(complex128_t))
disply_bits not implemented for complex128_t
#define COMPLEX128_STDMATH(function)
static void radix_sort_helper(T *array, int32_t size, uint16_t i)
static T sign(T a)
signum of type T variable a
static float64_t tanh(float64_t x)
atan2(x), x being a complex128_t not implemented
static int is_nan(double f)
checks whether a float is nan
virtual const char * get_name() const
static float64_t asin(float64_t x)
sin(x), x being a complex128_t
static T min(T a, T b)
return the minimum of two integers
static float64_t exp(float64_t x)
static const float64_t F_MIN_VAL64
static const float64_t F_MIN_NORM_VAL64
static float64_t log(float64_t v)
static void radix_sort_helper(complex128_t *array, int32_t size, uint16_t i)
radix_sort_helper not implemented for complex128_t
static const float64_t ALMOST_INFTY
Class which collects generic mathematical functions.
static T log_mean_exp(SGVector< T > values)
static void insertion_sort(T *output, int32_t size)
static void swap(T &a, T &b)
swap e.g. floats a and b
static complex128_t pow(complex128_t x, float64_t n)
static void sort(int32_t *a, int32_t cols, int32_t sort_col=0)
static T max(T *vec, int32_t len)
return the greatest element in a vector.
static int32_t binary_search_helper(complex128_t *output, int32_t size, complex128_t elem)
binary_search_helper not implemented for complex128_t
static float64_t round(float64_t d)
static float32_t sqrt(float32_t x)
x^0.5
static uint32_t generate_seed()
static index_t floor_log(index_t n)
log(x), x being a complex128_t
static void radix_sort(T *array, int32_t size)
static uint32_t random(uint32_t min_value, uint32_t max_value)
static floatmax_t powl(floatmax_t x, floatmax_t n)
x^n
static float64_t logarithmic_sum(float64_t p, float64_t q)
#define radix_push(a, n, i)
static T clamp(T value, T lb, T ub)
return the value clamped to interval [lb,ub]
static int32_t binary_search(complex128_t **vector, index_t length, complex128_t *elem)
binary_search not implemented for complex128_t
#define COMPLEX128_ERROR_SORT_T(function)
static bool strtold(const char *str, floatmax_t *long_double_result)
static int32_t pow(bool x, int32_t n)
static const float64_t NOT_A_NUMBER
not a number
static void qsort_backward_index(T1 *output, T2 *index, int32_t size)
static const float64_t MAX_REAL_NUMBER
static T abs(T a)
return the absolute value of a number
static void nmin(float64_t *output, complex128_t *index, int32_t size, int32_t n)
complex128_t cannot be used as index
static int64_t random(int64_t min_value, int64_t max_value)
static const float64_t PI