/*
* Copyright (c) 2011-2024 Ross Cunniff
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* OADL libstd - most of the same functionality of C libm/libc, but handles
* vectors as well as scalars
*/
namespace math {
/******************************************************************************
* Math constants - single precision, to 10 significant digits
*****************************************************************************/
const E = 2.718281828; // e
const LOG2E = 1.442695041; // log[2](e)
const LOG10E = .4342944819; // log[10](e)
const LN2 = .6931471806; // log[e](2)
const LN10 = 2.302585093; // log[e](10)
const PI = 3.141592654; // pi
const PI_2 = 1.570796327; // pi/2
const PI_4 = .7853981634; // pi/4
const ONE_DIV_PI = .3183098862; // 1/pi
const TWO_DIV_PI = .6366197724; // 2/pi
const TWO_DIV_SQRTPI = 1.128379167; // 2/sqrt(pi)
const SQRT2 = 1.414213562; // sqrt(2)
const SQRT1_2 = .7071067812; // 1/sqrt(2)
const EPSILON = 2.384185791e-07; // Minimum increment of 1.0
/******************************************************************************
* Math constants - double precision, to 18 significant digits
*****************************************************************************/
const D_E = 2.71828182845904524D; // e
const D_LOG2E = 1.44269504088896341D; // log[2](e)
const D_LOG10E = .434294481903251828D; // log[10](e)
const D_LN2 = .693147180559945309D; // log[e](2)
const D_LN10 = 2.30258509299404568D; // log[e](10)
const D_PI = 3.14159265358979324D; // pi
const D_PI_2 = 1.57079632679489662D; // pi/2
const D_PI_4 = .785398163397448310D; // pi/4
const D_1_PI = .318309886183790672D; // 1/pi
const D_2_PI = .636619772367581343D; // 2/pi
const D_2_SQRTPI = 1.12837916709551257D; // 2/sqrt(pi)
const D_SQRT2 = 1.41421356237309505D; // sqrt(2)
const D_SQRT1_2 = .707106781186547524D; // 1/sqrt(2)
const D_EPSILON = 4.4408920985006261617e-16D; // Minimum increment of 1.0
/******************************************************************************
* Math constants - half precision, to 4 significant digits
*****************************************************************************/
const H_EPSILON = 9.766e-4h; // Minimum increment of 1.0h
/******************************************************************************
* Math functions
*
* Note that all arguments may be array-valued, but all must contain only
* floating point data (Float, Half, or Double), except for ldexp which
* requires integral data for the exponent
*****************************************************************************/
extern acos; // r = acos(x) inverse cosine
extern asin; // r = asin(x) inverse sine
extern atan; // r = atan(x) one-parameter inverse tangent
extern atan2; // r = atan2(y,x) two-parameter inverse tangent
extern ceil; // r = ceil(x) smallest integer not less than x
extern cos; // r = cos(x) cosine
extern cosh; // r = cosh(x) hyperbolic cosine
extern exp; // r = exp(x) exponential function
extern fabs; // r = fabs(x) absolute value
extern floor; // r = floor(x) largest integer not greater than x
extern fmod; // r = fmod(x,y) floating-point remainder: x - y*(int)(x/y)
extern frexp; // [m,e] = frexp(x) break number into mantissa and exponent
extern ldexp; // r = ldexp([m,e]) compose number from mantissa and exponent
extern log; // r = log(x) natural logarithm
extern log10; // r = log10(x) base-10 logarithm
extern modf; // [f,i] = modf(x) integral and fractional parts of x
extern pow; // r = pow(x,y) raise x to the power of y, x**y
extern round; // r = round(x) round x to the nearest whole number
extern sin; // r = sin(x) sine
extern sinh; // r = sinh(x) hyperbolic sine
extern sqrt; // r = sqrt(x) square root
extern tan; // r = tan(x) tangent
extern tanh; // r = tanh(x) hyperbolic tangent
extern isinf; // r = isinf(x) true if IEEE Inf, false otherwise
extern isnan; // r = isnan(x) true if IEE NaN, false otherwise
extern isint; // r = isint(x) true if no fractional bits, else false
extern gamma; // r = gamma(x) calculate the real gamma of x
extern factorial; // r = factorail(x) calculate the real factorial of x
extern binomial; // r = binomial(x,y) returns x!/(y!*(x-y)!)
extern hypot; // r = hypot(v1,v2) returns ((v1-v2)*2).reduce(`+)**0.5
extern vlen; // r = vlen(vec) returns (vec*vec).reduce(`+)**0.5
extern polar; // r = polar(vec) returns [rad,ang], etc.
extern cartesian; // r = cartesian(vec) returns rad*[ang.sin(),ang.cos()] etc.
}
namespace linalg {
/******************************************************************************
* linear algebra functions
*****************************************************************************/
extern matinv; // r = matinv(m) mat must be a 2D packed array
extern svd; // {UDV} = svd(m) Singular Value Decomposition of 2D m
extern solve; // x = solve(udv,b) Solve (udv)x=b for x
extern dot; // r = dot(v1,v2) returns (v1*v2).reduce(`+)
extern cross; // r = cross(v1,v2) returns 3-dimensional cross product
extern unitize; // r = unitize(vec) returns (v1**2).reduce(`+)**0.5
extern ucross; // r = ucross(v1,v2) returns unit 3-dimensional cross product
}
namespace std {
/******************************************************************************
* ctype functions
*****************************************************************************/
extern isalnum; // r = isalnum(c)
extern isalpha; // r = isalpha(c)
extern iscntrl; // r = iscntrl(c)
extern isdigit; // r = isdigit(c)
extern isgraph; // r = isgraph(c)
extern islower; // r = islower(c)
extern isprint; // r = isprint(c)
extern ispunct; // r = ispunct(c)
extern isspace; // r = isspace(c)
extern isupper; // r = isupper(c)
extern isxdigit; // r = isxdigit(c)
extern tolower; // r = tolower(c)
extern toupper; // r = toupper(c)
/******************************************************************************
* string functions
*****************************************************************************/
extern strstr; // r = strstr(big,little) find little in big
extern strtok; // r = strtok(str, sepchars) tokenize a string
}
// Public versions of the calls
default public
acos = math::acos, // r = x.acos() inverse cosine
asin = math::asin, // r = x.asin() inverse sine
atan = math::atan, // r = x.atan() one-parameter inverse tangent
atan2 = math::atan2, // r = y.atan2(x) two-parameter inverse tangent
ceil = math::ceil, // r = x.ceil() smallest integer not less than x
cos = math::cos, // r = x.cos() cosine
cosh = math::cosh, // r = x.cosh() hyperbolic cosine
exp = math::exp, // r = x.exp() exponential function
fabs = math::fabs, // r = x.fabs() absolute value
floor = math::floor,// r = x.floor() largest integer not greater than x
fmod = math::fmod, // r = x.fmod(y) float remainder: x-y*(int)(x/y)
frexp = math::frexp, // {m,e} = x.frexp() break number into mant. and expon.
ldexp = math::ldexp, // r = m.ldexp(e) make number from mant. and expon.
log = math::log, // r = x.log() natural logarithm
log10 = math::log10, // r = x.log10() base-10 logarithm
modf = math::modf, // {f,i} = x.modf() integral and fractional parts of x
pow = math::pow, // r = x.pow(y) raise x to the power of y, x**y
round = math::round, // r = x.round() round x to nearest whole number
sin = math::sin, // r = x.sin() sine
sinh = math::sinh, // r = x.sinh() hyperbolic sine
sqrt = math::sqrt, // r = x.sqrt() square root
tan = math::tan, // r = x.tan() tangent
tanh = math::tanh, // r = x.tanh() hyperbolic tangent
isinf = math::isinf,// r = x.isinf() true if IEEE Inf, false otherwise
isnan = math::isnan,// r = x.isnan() true if IEEE NaN, false otherwise
isint = math::isint,// r = x.isint() true if no frac. bits, else false
gamma = math::gamma,// r = x.gamma()
factorial = math::factorial, // r = x.factorial()
binomial = math::binomial, // r = x.binomial(y) returns x!/(y!*(x-y)!)
hypot = math::hypot, // r = v1.hypot(v2) returns ((v1-v2)*2).reduce(`+)**0.5
vlen = math::vlen, // r = vlen(vec) returns (vec*vec).reduce(`+)**0.5
polar = math::polar, // r = vec.polar() returns [rad,ang], etc.
cartesian = math::cartesian, // r = vec.cartesian() returns
// rad*[ang.sin(),ang.cos()] etc.
matinv = linalg::matinv, // r = m.matinv() mat must be a 2D packed array
svd = linalg::svd, // {UDV} = m.svd() Singular Value Decomposition
solve = linalg::solve, // x = udv.solve(b) Solve (udv)x=b for x
dot = linalg::dot, // r = dot(v1,v2) returns (v1*v2).reduce(`+)
cross = linalg::cross, // r = cross(v1,v2) returns n-dim cross product
unitize = linalg::unitize, // r = unitize(vec) returns vec/vec.vlen()
ucross = linalg::ucross, // r = ucross(v1,v2) returns unit n-dim cross prod
isalnum = std::isalnum, // r = c.isalnum()
isalpha = std::isalpha, // r = c.isalpha()
iscntrl = std::iscntrl, // r = c.iscntrl()
isdigit = std::isdigit, // r = c.isdigit()
isgraph = std::isgraph, // r = c.isgraph()
islower = std::islower, // r = c.islower()
isprint = std::isprint, // r = c.isprint()
ispunct = std::ispunct, // r = c.ispunct()
isspace = std::isspace, // r = c.isspace()
isupper = std::isupper, // r = c.isupper()
isxdigit = std::isxdigit, // r = c.isxdigit()
tolower = std::tolower, // r = c.tolower()
toupper = std::toupper, // r = c.toupper()
strstr = std::strstr, // r = big.strstr(little) find little in big
strtok = std::strtok; // r = str.strtok(seps) split str based on seps
using extern "libstd";