package SPVM::Math {
use SPVM::Complex_2f;
use SPVM::Complex_2d;
native sub HUGE_VALF : float ();
native sub INFINITYF : float ();
native sub NANF : float ();
native sub isinff : int($x : float);
native sub isfinitef : int($x : float);
native sub isnanf : int ($x : float);
native sub fpclassifyf : int ($x : float);
native sub signbitf : int ($x : float);
native sub HUGE_VAL : double ();
native sub INFINITY : double ();
native sub NAN : double ();
native sub isinf : int ($x : double);
native sub isfinite : int ($x : double);
native sub isnan : int ($x : double);
native sub fpclassify : int ($x : double);
native sub signbit : int ($x : double);
sub pi : double () { return 3.141592653589793115997963468544185161590576171875; }
native sub FE_DOWNWARD : int ();
native sub FE_TONEAREST : int ();
native sub FE_TOWARDZERO : int ();
native sub FE_UPWARD : int ();
native sub fesetround : int ($round : int);
native sub FP_INFINITE : int ();
native sub FP_NAN : int ();
native sub FP_ZERO : int ();
native sub FP_ILOGB0 : int ();
native sub FP_ILOGBNAN : int ();
# Trigonometric functions
native sub cos : double ($x : double);
native sub cosf : float ($x : float);
native sub sin : double ($x : double);
native sub sinf : float ($x : float);
native sub tan : double ($x : double);
native sub tanf : float ($x : float);
native sub acos : double ($x : double);
native sub acosf : float ($x : float);
native sub asin : double ($x : double);
native sub asinf : float ($x : float);
native sub atan : double ($x : double);
native sub atanf : float ($x : float);
native sub atan2 : double ($y : double, $x : double);
# Hyperbolic functions
native sub cosh : double ($x : double);
native sub coshf : float ($x : float);
native sub sinh : double ($x : double);
native sub sinhf : float ($x : float);
native sub tanh : double ($x : double);
native sub tanhf : float ($x : float);
native sub acosh : double ($x : double);
native sub acoshf : float ($x : float);
native sub asinh : double ($x : double);
native sub asinhf : float ($x : float);
native sub atanh : double ($x : double);
native sub atanhf : float ($x : float);
# Exponential functions and logarithmic functions
native sub exp : double ($x : double);
native sub expf : float ($x : float);
native sub exp2 : double ($x : double);
native sub exp2f : float ($x : float);
native sub expm1 : double ($x : double);
native sub expm1f : float ($x : float);
native sub frexp : double ($x : double, $exp : int&);
native sub frexpf : float ($x : float, $exp : int&);
native sub ilogb : int ($x : double);
native sub ilogbf : int ($x : float);
native sub ldexp : double ($x : double, $exp : int);
native sub ldexpf : float ($x : float, $exp : int);
native sub log : double ($x : double);
native sub logf : float ($x : float);
native sub log10 : double ($x : double);
native sub log10f : float ($x : float);
native sub log1p : double ($x : double);
native sub log1pf : float ($x : float);
native sub log2 : double ($x : double);
native sub log2f : float ($x : float);
native sub logb : double ($x : double);
native sub logbf : float ($x : float);
native sub modf : double ($x : double, $intpart : double&);
native sub modff : float ($x : float, $intpart : float&);
native sub scalbn : double ($x : double, $exp : int);
native sub scalbnf : float ($x : float, $exp : int);
native sub scalbln : double ($x : double, $exp : long);
native sub scalblnf : float ($x : float, $exp : long);
# Exponentiation functions and Absolute value functions
native sub cbrt : double ($x : double);
native sub cbrtf : float ($x : float);
native sub fabs : double ($x : double);
native sub fabsf : float ($x : float);
native sub hypot : double ($x : double, $y : double);
native sub hypotf : float ($x : float, $y : float);
native sub pow : double ($x : double, $y : double);
native sub powf : float ($x : float, $y : float);
native sub sqrt : double ($x : double);
native sub sqrtf : float ($x : float);
# Error function and Gamma function
native sub erf : double ($x : double);
native sub erff : float ($x : float);
native sub erfc : double ($x : double);
native sub erfcf : float ($x : float);
native sub lgamma : double ($x : double);
native sub lgammaf : float ($x : float);
native sub tgamma : double ($x : double);
native sub tgammaf : float ($x : float);
# Nearest integer function
native sub ceil : double ($x : double);
native sub ceilf : float ($x : float);
native sub floor : double ($x : double);
native sub floorf : float ($x : float);
native sub nearbyint : double ($x : double);
native sub nearbyintf : float ($x : float);
native sub round : double ($x : double);
native sub roundf : float ($x : float);
native sub lround : long ($x : double);
native sub lroundf : long ($x : float);
native sub trunc : double ($x : double);
native sub truncf : float ($x : float);
# Surplus functions
native sub fmod : double ($x1 : double, $x2 : double);
native sub fmodf : float ($x1 : float, $x2 : float);
native sub remainder : double ($x1 : double, $x2 : double);
native sub remainderf : float ($x1 : float, $x2 : float);
native sub remquo : double ($x1 : double, $x2 : double, $quo : int&);
native sub remquof : float ($x1 : float, $x2 : float, $quo : int&);
# Real number operation functions
native sub copysign : double ($x1 : double, $x2 : double);
native sub copysignf : float ($x1 : float, $x2 : float);
native sub nan : double ($str : string);
native sub nanf : float ($str : string);
native sub nextafter : double ($x1 : double, $x2 : double);
native sub nextafterf : float ($x1 : float, $x2 : float);
native sub nexttoward : double ($x1 : double, $x2 : double);
native sub nexttowardf : float ($x1 : float, $x2 : double);
# Maximum, minimum and positive difference functions
native sub fdim : double ($x1 : double, $x2 : double);
native sub fdimf : float ($x1 : float, $x2 : float);
native sub fmax : double ($x1 : double, $x2 : double);
native sub fmaxf : float ($x1 : float, $x2 : float);
native sub fmin : double ($x1 : double, $x2 : double);
native sub fminf : float ($x1 : float, $x2 : float);
# Floating point multiplication and additions
native sub fma : double ($x1 : double, $x2 : double, $x3 : double);
native sub fmaf : float ($x1 : float, $x2 : float, $x3 : float);
# Comparison
native sub isgreater : int ($x1 : double, $x2 : double);
native sub isgreaterf : int ($x1 : float, $x2 : float);
native sub isgreaterequal : int ($x1 : double, $x2 : double);
native sub isgreaterequalf : int ($x1 : float, $x2 : float);
native sub isless : int ($x1 : double, $x2 : double);
native sub islessf : int ($x1 : float, $x2 : float);
native sub islessequal : int ($x1 : double, $x2 : double);
native sub islessequalf : int ($x1 : float, $x2 : float);
native sub islessgreater : int ($x1 : double, $x2 : double);
native sub islessgreaterf : int ($x1 : float, $x2 : float);
native sub isunordered : int ($x1 : double, $x2 : double);
native sub isunorderedf : int ($x1 : float, $x2 : float);
sub complexf : SPVM::Complex_2f ($x : float, $y : float) {
my $z_out : SPVM::Complex_2f;
$z_out->{re} = $x;
$z_out->{im} = $y;
return $z_out;
}
sub complex : SPVM::Complex_2d ($x : double, $y : double) {
my $z_out : SPVM::Complex_2d;
$z_out->{re} = $x;
$z_out->{im} = $y;
return $z_out;
}
sub caddf : SPVM::Complex_2f ($z1 : SPVM::Complex_2f, $z2 : SPVM::Complex_2f) {
my $z_out : SPVM::Complex_2f;
$z_out->{re} = $z1->{re} + $z2->{re};
$z_out->{im} = $z1->{im} + $z2->{im};
return $z_out;
}
sub cadd : SPVM::Complex_2d ($z1 : SPVM::Complex_2d, $z2 : SPVM::Complex_2d) {
my $z_out : SPVM::Complex_2d;
$z_out->{re} = $z1->{re} + $z2->{re};
$z_out->{im} = $z1->{im} + $z2->{im};
return $z_out;
}
sub csubf : SPVM::Complex_2f ($z1 : SPVM::Complex_2f, $z2 : SPVM::Complex_2f) {
my $z_out : SPVM::Complex_2f;
$z_out->{re} = $z1->{re} - $z2->{re};
$z_out->{im} = $z1->{im} - $z2->{im};
return $z_out;
}
sub csub : SPVM::Complex_2d ($z1 : SPVM::Complex_2d, $z2 : SPVM::Complex_2d) {
my $z_out : SPVM::Complex_2d;
$z_out->{re} = $z1->{re} - $z2->{re};
$z_out->{im} = $z1->{im} - $z2->{im};
return $z_out;
}
sub cmulf : SPVM::Complex_2f ($z1 : SPVM::Complex_2f, $z2 : SPVM::Complex_2f) {
my $z_out : SPVM::Complex_2f;
$z_out->{re} = $z1->{re} * $z2->{re} - $z1->{im} * $z2->{im};
$z_out->{im} = $z1->{re} * $z2->{im} + $z1->{im} * $z2->{re};
return $z_out;
}
sub cmul : SPVM::Complex_2d ($z1 : SPVM::Complex_2d, $z2 : SPVM::Complex_2d) {
my $z_out : SPVM::Complex_2d;
$z_out->{re} = $z1->{re} * $z2->{re} - $z1->{im} * $z2->{im};
$z_out->{im} = $z1->{re} * $z2->{im} + $z1->{im} * $z2->{re};
return $z_out;
}
sub cscamulf : SPVM::Complex_2f ($c : float, $z : SPVM::Complex_2f) {
my $z_out : SPVM::Complex_2f;
$z_out->{re} = $c * $z->{re};
$z_out->{im} = $c * $z->{im};
return $z_out;
}
sub cscamul : SPVM::Complex_2d ($c : double, $z : SPVM::Complex_2d) {
my $z_out : SPVM::Complex_2d;
$z_out->{re} = $c * $z->{re};
$z_out->{im} = $c * $z->{im};
return $z_out;
}
sub cdivf : SPVM::Complex_2f ($z1 : SPVM::Complex_2f, $z2 : SPVM::Complex_2f) {
my $z_out : SPVM::Complex_2f;
$z_out->{re} = ($z1->{re} * $z2->{re} + $z1->{im} * $z2->{im}) / ($z2->{re} * $z2->{re} + $z2->{im} * $z2->{im});
$z_out->{im} = ($z1->{im} * $z2->{re} - $z1->{re} * $z2->{im}) / ($z2->{re} * $z2->{re} + $z2->{im} * $z2->{im});
return $z_out;
}
sub cdiv : SPVM::Complex_2d ($z1 : SPVM::Complex_2d, $z2 : SPVM::Complex_2d) {
my $z_out : SPVM::Complex_2d;
$z_out->{re} = ($z1->{re} * $z2->{re} + $z1->{im} * $z2->{im}) / ($z2->{re} * $z2->{re} + $z2->{im} * $z2->{im});
$z_out->{im} = ($z1->{im} * $z2->{re} - $z1->{re} * $z2->{im}) / ($z2->{re} * $z2->{re} + $z2->{im} * $z2->{im});
return $z_out;
}
native sub cacos : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub cacosf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub casin : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub casinf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub catan : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub catanf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub ccos : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub ccosf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub csin : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub csinf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub ctan : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub ctanf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub cacosh : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub cacoshf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub casinh : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub casinhf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub catanh : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub catanhf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub ccosh : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub ccoshf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub csinh : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub csinhf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub ctanh : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub ctanhf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub cexp : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub cexpf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub clog : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub clogf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub cabs : double ($z : SPVM::Complex_2d);
native sub cabsf : float ($z : SPVM::Complex_2f);
native sub cpow : SPVM::Complex_2d ($z1 : SPVM::Complex_2d, $z2 : SPVM::Complex_2d);
native sub cpowf : SPVM::Complex_2f ($z1 : SPVM::Complex_2f, $z2 : SPVM::Complex_2f);
native sub csqrt : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub csqrtf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
native sub carg : double ($z : SPVM::Complex_2d);
native sub cargf : float ($z : SPVM::Complex_2f);
native sub conj : SPVM::Complex_2d ($z : SPVM::Complex_2d);
native sub conjf : SPVM::Complex_2f ($z : SPVM::Complex_2f);
}