master
madrocketsci 1 week ago
parent f3b4801947
commit d658df27b3

Binary file not shown.

@ -9,6 +9,7 @@
#include <vector>
#include <thread>
#include <functional>
#include <mutex>
namespace ams
{

@ -6,6 +6,77 @@ namespace ams
namespace cmp
{
class complex
{
public:
double r,i;
complex();
complex(double _r, double _i);
complex(double _r);
complex(const complex &other);
complex& operator=(const complex& other);
complex& operator=(const double other);
friend complex operator-(const complex& z); //negation sign
complex operator+(const complex& z);
complex operator-(const complex& z);
complex operator*(const complex& z);
complex operator/(const complex& z);
complex operator+(const double & z);
complex operator-(const double & z);
complex operator*(const double & z);
complex operator/(const double & z);
double& operator[](int& ind);
const double& operator[](const int& ind) const;
//comparison operators
bool operator==(const complex& z);
bool operator!=(const complex& z);
bool operator>(const complex& z);
bool operator<(const complex& z);
bool operator>=(const complex& z);
bool operator<=(const complex& z);
bool isnan();
bool isinf();
bool isreal();
bool isimag();
bool iszero();
double arg();
double mag();
const complex conj();
};
double arg(ams::cmp::complex z);
double real(complex z);
double imag(complex z);
complex sin(complex z);
complex cos(complex z);
complex tan(complex z);
complex exp(complex z);
complex log(complex z);
double abs(complex z);
complex conj(complex z);
//need hyperbolic trig Functions
complex cosh(complex z);
complex sinh(complex z);
complex tanh(complex z);
complex pow(complex z1, complex z2);
//returns "complex sign" of complex number - 0, or a unit number with same argument
complex csgn(complex z);
typedef complex complex128;
}; //end namespace cmp
}; //end namespace ams

@ -6,6 +6,74 @@ namespace ams
namespace cmp
{
class complex64
{
public:
float r,i;
complex64();
complex64(float _r, float _i);
complex64(float _r);
complex64(const complex64 &other);
complex64& operator=(const complex64& other);
complex64& operator=(const float other);
friend complex64 operator-(const complex64& z); //negation sign
complex64 operator+(const complex64& z);
complex64 operator-(const complex64& z);
complex64 operator*(const complex64& z);
complex64 operator/(const complex64& z);
complex64 operator+(const float & z);
complex64 operator-(const float & z);
complex64 operator*(const float & z);
complex64 operator/(const float & z);
float& operator[](int& ind);
const float& operator[](const int& ind) const;
//comparison operators
bool operator==(const complex64& z);
bool operator!=(const complex64& z);
bool operator>(const complex64& z);
bool operator<(const complex64& z);
bool operator>=(const complex64& z);
bool operator<=(const complex64& z);
bool isnan();
bool isinf();
bool isreal();
bool isimag();
bool iszero();
float arg();
float mag();
const complex64 conj();
};
float arg(ams::cmp::complex64 z);
float real(complex64 z);
float imag(complex64 z);
complex64 sin(complex64 z);
complex64 cos(complex64 z);
complex64 tan(complex64 z);
complex64 exp(complex64 z);
complex64 log(complex64 z);
float abs(complex64 z);
complex64 conj(complex64 z);
//need hyperbolic trig Functions
complex64 cosh(complex64 z);
complex64 sinh(complex64 z);
complex64 tanh(complex64 z);
complex64 pow(complex64 z1, complex64 z2);
//returns "complex64 sign" of complex64 number - 0, or a unit number with same argument
complex64 csgn(complex64 z);
}; //end namespace cmp
}; //end namespace ams

@ -4,6 +4,22 @@
namespace ams
{
//OpenGL #defines a variable pi - the compiler doesn't like it if I #define a pi also...
static const double pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164L;
static const float pif = 3.1415926535897932384626433832795028841971693993751058209749445923078164;
//this implementation doesn't work on all complilers?
static const double nan = std::numeric_limits<double>::quiet_NaN();
static const double inf = std::numeric_limits<double>::infinity();
static const float fnan = std::numeric_limits<float>::quiet_NaN();
static const float finf = std::numeric_limits<float>::infinity();
static const double DLARGE = 1.0E300;
static const double DSMALL = 1.0E-300;
static const double vecmat_det_small = 1.0E-15;
}; //end namespace ams

@ -4,6 +4,71 @@
namespace ams
{
bool isnan(double d);
bool isinf(double d);
bool isinfnan(double d);
bool isnan(float f);
bool isinf(float f);
bool isinfnan(float f);
double arg(double x, double y);
float arg(float x, float y);
double sgn(double d);
float sgn(float f);
//It has come to my attention that the behavior of Cs
//fmod is odd: Negative numbers have negative moduli
//I need to fix this with a proper modular function, whose values are in [0,N)
double mod(double a, double b);
float mod(float a, float b);
int32_t mod(int32_t a, int32_t b);
int64_t mod(int64_t a, int64_t b);
int32_t truediv(int32_t x, int32_t y);
int64_t truediv(int64_t x, int64_t y);
double abs(double a);
float abs(float a);
int32_t abs(int32_t a);
int64_t abs(int64_t a);
template<typename T> T max(T a, T b);
template<typename T> T min(T a, T b);
template<typename T> T max(T a, T b, T c);
template<typename T> T min(T a, T b, T c);
//generic implementations
template<typename T> T max(T a, T b)
{
T ret = (a>b)? a : b;
return ret;
}
template<typename T> T min(T a, T b)
{
T ret = (a<b)? a : b;
return ret;
}
template<typename T> T max(T a, T b, T c)
{
T ret = a;
ret = (ret<b) ? b : ret;
ret = (ret<c) ? c : ret;
return ret;
}
template<typename T> T min(T a, T b, T c)
{
T ret = a;
ret = (ret>b) ? b : ret;
ret = (ret>c) ? c : ret;
return ret;
}
}; //end namespace ams

@ -12,24 +12,90 @@ public:
vec2();
vec2(double _x, double _y);
vec2 operator=(vec2 rhs);
vec2(const vec2 &rhs);
vec2& operator=(const vec2 &rhs);
bool operator==(vec2 rhs);
vec2 operator+(vec2 rhs) const;
vec2 operator-(vec2 rhs) const;
vec2 operator*(double rhs) const;
vec2 operator/(double rhs) const;
friend vec2 operator-(vec2 rhs);
double& operator[](int ind);
const double& operator[](int ind) const;
};
//vector operations
double vec2_dot(vec2 v1, vec2 v2);
double vec2_norm(vec2 v);
vec2 vec2_normalize(vec2 v);
double vec2_dist(vec2 v1, vec2 v2);
double vec2_cross(vec2 v1, vec2 v2);
vec2 vec2_proj(vec2 v1, vec2 v2);
vec2 vec2_hodgedual(vec2 v);
double vec2_arg(vec2 v);
//vector operations (old nomenclature)
double vdot(vec2 v1, vec2 v2);
double vnorm(vec2 v);
vec2 vnormalize(vec2 v);
double vdist(vec2 v1, vec2 v2);
double vcross(vec2 v1, vec2 v2);
vec2 vproj(vec2 v1, vec2 v2);
class mat2
{
public:
double data[4];
mat2();
mat2(double _xx, double _xy, double _yx, double _yy);
mat2(double _xx, double _yx, double _xy, double _yy);
mat2(const double *_data);
mat2(mat2 &rhs);
mat2(const mat2 &rhs);
mat2(const vec2 _col1, const vec2 _col2);
mat2& operator=(const mat2 rhs);
bool operator==(const mat2 rhs);
mat2 operator+(mat2 rhs) const;
mat2 operator-(mat2 rhs) const;
mat2 operator*(mat2 rhs) const;
mat2 operator/(mat2 rhs) const;
mat2 operator*(double rhs) const;
mat2 operator/(double rhs) const;
vec2 operator*(vec2 rhs) const;
double& operator()(int I, int J);
double& operator[](int I);
const double& operator()(int I, int J) const;
const double& operator[](int I) const;
double& at(int I, int J);
const double& at(int I, int J) const;
double det();
mat2 inverse();
void invert();
mat2 transpose();
void dotranspose();
};
//matrix operations
mat2 mat2_eye();
mat2 mat2_zeros();
mat2 mat2_ones();
mat2 mat2_mult(mat2 a, mat2 b);
vec2 mat2_mult(vec2 a, mat2 b);
vec2 mat2_mult(mat2 a, vec2 b);
double mat2_det(mat2 a);
mat2 mat2_inverse(mat2 a);
mat2 mat2_transpose(mat2 a);
}; //end namespace ams
#endif

@ -4,6 +4,97 @@
namespace ams
{
class vec2f
{
public:
float x;
float y;
vec2f();
vec2f(float _x, float _y);
vec2f(const vec2f &rhs);
vec2f& operator=(const vec2f &rhs);
bool operator==(vec2f rhs);
vec2f operator+(vec2f rhs) const;
vec2f operator-(vec2f rhs) const;
vec2f operator*(float rhs) const;
vec2f operator/(float rhs) const;
friend vec2f operator-(vec2f rhs);
float& operator[](int ind);
const float& operator[](int ind) const;
};
//vector operations
float vec2f_dot(vec2f v1, vec2f v2);
float vec2f_norm(vec2f v);
vec2f vec2f_normalize(vec2f v);
float vec2f_dist(vec2f v1, vec2f v2);
float vec2f_cross(vec2f v1, vec2f v2);
vec2f vec2f_proj(vec2f v1, vec2f v2);
vec2f vec2f_hodgedual(vec2f v);
float vec2f_arg(vec2f v);
//vector operations (old nomenclature)
float vdot(vec2f v1, vec2f v2);
float vnorm(vec2f v);
vec2f vnormalize(vec2f v);
float vdist(vec2f v1, vec2f v2);
float vcross(vec2f v1, vec2f v2);
vec2f vproj(vec2f v1, vec2f v2);
class mat2f
{
public:
float data[4];
mat2f();
mat2f(float _xx, float _yx, float _xy, float _yy);
mat2f(const float *_data);
mat2f(const mat2f &rhs);
mat2f(const vec2f _col1, const vec2f _col2);
mat2f& operator=(const mat2f rhs);
bool operator==(const mat2f rhs);
mat2f operator+(mat2f rhs) const;
mat2f operator-(mat2f rhs) const;
mat2f operator*(mat2f rhs) const;
mat2f operator/(mat2f rhs) const;
mat2f operator*(float rhs) const;
mat2f operator/(float rhs) const;
vec2f operator*(vec2f rhs) const;
float& operator()(int I, int J);
float& operator[](int I);
const float& operator()(int I, int J) const;
const float& operator[](int I) const;
float& at(int I, int J);
const float& at(int I, int J) const;
float det();
mat2f inverse();
void invert();
mat2f transpose();
void dotranspose();
};
//matrix operations
mat2f mat2f_eye();
mat2f mat2f_zeros();
mat2f mat2f_ones();
mat2f mat2f_mult(mat2f a, mat2f b);
vec2f mat2f_mult(vec2f a, mat2f b);
vec2f mat2f_mult(mat2f a, vec2f b);
float mat2f_det(mat2f a);
mat2f mat2f_inverse(mat2f a);
mat2f mat2f_transpose(mat2f a);
}; //end namespace ams

@ -5,6 +5,99 @@ namespace ams
{
class vec3;
class mat3;
class vec3
{
public:
double x;
double y;
double z;
vec3();
vec3(double _x, double _y, double _z);
vec3(const vec3 &rhs);
vec3& operator=(const vec3 &rhs);
bool operator==(vec3 rhs);
vec3 operator+(vec3 rhs) const;
vec3 operator-(vec3 rhs) const;
vec3 operator*(double rhs) const;
vec3 operator/(double rhs) const;
friend vec3 operator-(vec3 rhs);
double& operator[](int ind);
const double& operator[](int ind) const;
};
//vector operations
double vec3_dot(vec3 v1, vec3 v2);
double vec3_norm(vec3 v);
vec3 vec3_normalize(vec3 v);
double vec3_dist(vec3 v1, vec3 v2);
vec3 vec3_cross(vec3 v1, vec3 v2);
vec3 vec3_proj(vec3 v1, vec3 v2);
mat3 vec3_hodgedual(vec3 v);
//vector operations (old nomenclature)
double vdot(vec3 v1, vec3 v2);
double vnorm(vec3 v);
vec3 vnormalize(vec3 v);
double vdist(vec3 v1, vec3 v2);
vec3 vcross(vec3 v1, vec3 v2);
vec3 vproj(vec3 v1, vec3 v2);
class mat3
{
public:
double data[9];
mat3();
mat3(double _xx, double _yx, double _zx, double _xy, double _yy, double _zy, double _xz, double _yz, double _zz);
mat3(const double *_data);
mat3(const mat3 &rhs);
mat3(const vec3 _col1, const vec3 _col2, const vec3 _col3);
mat3& operator=(const mat3 rhs);
bool operator==(const mat3 rhs);
mat3 operator+(mat3 rhs) const;
mat3 operator-(mat3 rhs) const;
mat3 operator*(mat3 rhs) const;
mat3 operator/(mat3 rhs) const;
mat3 operator*(double rhs) const;
mat3 operator/(double rhs) const;
vec3 operator*(vec3 rhs) const;
double& operator()(int I, int J);
double& operator[](int I);
const double& operator()(int I, int J) const;
const double& operator[](int I) const;
double& at(int I, int J);
const double& at(int I, int J) const;
double det();
mat3 inverse();
void invert();
mat3 transpose();
void dotranspose();
};
//matrix operations
mat3 mat3_eye();
mat3 mat3_zeros();
mat3 mat3_ones();
mat3 mat3_mult(mat3 a, mat3 b);
vec3 mat3_mult(vec3 a, mat3 b);
vec3 mat3_mult(mat3 a, vec3 b);
double mat3_det(mat3 a);
mat3 mat3_inverse(mat3 a);
mat3 mat3_transpose(mat3 a);
}; //end namespace ams
#endif

@ -5,6 +5,99 @@ namespace ams
{
class vec3f;
class mat3f;
class vec3f
{
public:
float x;
float y;
float z;
vec3f();
vec3f(float _x, float _y, float _z);
vec3f(const vec3f &rhs);
vec3f& operator=(const vec3f &rhs);
bool operator==(vec3f rhs);
vec3f operator+(vec3f rhs) const;
vec3f operator-(vec3f rhs) const;
vec3f operator*(float rhs) const;
vec3f operator/(float rhs) const;
friend vec3f operator-(vec3f rhs);
float& operator[](int ind);
const float& operator[](int ind) const;
};
//vector operations
float vec3f_dot(vec3f v1, vec3f v2);
float vec3f_norm(vec3f v);
vec3f vec3f_normalize(vec3f v);
float vec3f_dist(vec3f v1, vec3f v2);
vec3f vec3f_cross(vec3f v1, vec3f v2);
vec3f vec3f_proj(vec3f v1, vec3f v2);
mat3f vec3f_hodgedual(vec3f v);
//vector operations (old nomenclature)
float vdot(vec3f v1, vec3f v2);
float vnorm(vec3f v);
vec3f vnormalize(vec3f v);
float vdist(vec3f v1, vec3f v2);
vec3f vcross(vec3f v1, vec3f v2);
vec3f vproj(vec3f v1, vec3f v2);
class mat3f
{
public:
float data[9];
mat3f();
mat3f(float _xx, float _yx, float _zx, float _xy, float _yy, float _zy, float _xz, float _yz, float _zz);
mat3f(const float *_data);
mat3f(const mat3f &rhs);
mat3f(const vec3f _col1, const vec3f _col2, const vec3f _col3);
mat3f& operator=(const mat3f rhs);
bool operator==(const mat3f rhs);
mat3f operator+(mat3f rhs) const;
mat3f operator-(mat3f rhs) const;
mat3f operator*(mat3f rhs) const;
mat3f operator/(mat3f rhs) const;
mat3f operator*(float rhs) const;
mat3f operator/(float rhs) const;
vec3f operator*(vec3f rhs) const;
float& operator()(int I, int J);
float& operator[](int I);
const float& operator()(int I, int J) const;
const float& operator[](int I) const;
float& at(int I, int J);
const float& at(int I, int J) const;
float det();
mat3f inverse();
void invert();
mat3f transpose();
void dotranspose();
};
//matrix operations
mat3f mat3f_eye();
mat3f mat3f_zeros();
mat3f mat3f_ones();
mat3f mat3f_mult(mat3f a, mat3f b);
vec3f mat3f_mult(vec3f a, mat3f b);
vec3f mat3f_mult(mat3f a, vec3f b);
float mat3f_det(mat3f a);
mat3f mat3f_inverse(mat3f a);
mat3f mat3f_transpose(mat3f a);
}; //end namespace ams
#endif

@ -4,6 +4,101 @@
namespace ams
{
class vec4;
class mat4;
class vec4
{
public:
double x;
double y;
double z;
double w;
vec4();
vec4(double _x, double _y, double _z, double _w);
vec4(const vec4 &rhs);
vec4& operator=(const vec4 &rhs);
bool operator==(vec4 rhs);
vec4 operator+(vec4 rhs) const;
vec4 operator-(vec4 rhs) const;
vec4 operator*(double rhs) const;
vec4 operator/(double rhs) const;
friend vec4 operator-(vec4 rhs);
double& operator[](int ind);
const double& operator[](int ind) const;
};
//vector operations
double vec4_dot(vec4 v1, vec4 v2);
double vec4_norm(vec4 v);
vec4 vec4_normalize(vec4 v);
double vec4_dist(vec4 v1, vec4 v2);
vec4 vec4_proj(vec4 v1, vec4 v2);
//vector operations (old nomenclature)
double vdot(vec4 v1, vec4 v2);
double vnorm(vec4 v);
vec4 vnormalize(vec4 v);
double vdist(vec4 v1, vec4 v2);
vec4 vproj(vec4 v1, vec4 v2);
class mat4
{
public:
double data[16];
mat4();
mat4(
double _xx, double _yx, double _zx, double _wx,
double _xy, double _yy, double _zy, double _wy,
double _xz, double _yz, double _zz, double _wz,
double _xw, double _yw, double _zw, double _ww
);
mat4(const double *_data);
mat4(const mat4 &rhs);
mat4(const vec4 _col1, const vec4 _col2, const vec4 _col3, const vec4 _col4);
mat4& operator=(const mat4 rhs);
bool operator==(const mat4 rhs);
mat4 operator+(mat4 rhs) const;
mat4 operator-(mat4 rhs) const;
mat4 operator*(mat4 rhs) const;
mat4 operator/(mat4 rhs) const;
mat4 operator*(double rhs) const;
mat4 operator/(double rhs) const;
vec4 operator*(vec4 rhs) const;
double& operator()(int I, int J);
double& operator[](int I);
const double& operator()(int I, int J) const;
const double& operator[](int I) const;
double& at(int I, int J);
const double& at(int I, int J) const;
double det();
mat4 inverse();
void invert();
mat4 transpose();
void dotranspose();
};
//matrix operations
mat4 mat4_eye();
mat4 mat4_zeros();
mat4 mat4_ones();
mat4 mat4_mult(mat4 a, mat4 b);
vec4 mat4_mult(vec4 a, mat4 b);
vec4 mat4_mult(mat4 a, vec4 b);
double mat4_det(mat4 a);
mat4 mat4_inverse(mat4 a);
mat4 mat4_transpose(mat4 a);
}; //end namespace ams

@ -4,6 +4,101 @@
namespace ams
{
class vec4f;
class mat4f;
class vec4f
{
public:
float x;
float y;
float z;
float w;
vec4f();
vec4f(float _x, float _y, float _z, float _w);
vec4f(const vec4f &rhs);
vec4f& operator=(const vec4f &rhs);
bool operator==(vec4f rhs);
vec4f operator+(vec4f rhs) const;
vec4f operator-(vec4f rhs) const;
vec4f operator*(float rhs) const;
vec4f operator/(float rhs) const;
friend vec4f operator-(vec4f rhs);
float& operator[](int ind);
const float& operator[](int ind) const;
};
//vector operations
float vec4f_dot(vec4f v1, vec4f v2);
float vec4f_norm(vec4f v);
vec4f vec4f_normalize(vec4f v);
float vec4f_dist(vec4f v1, vec4f v2);
vec4f vec4f_proj(vec4f v1, vec4f v2);
//vector operations (old nomenclature)
float vdot(vec4f v1, vec4f v2);
float vnorm(vec4f v);
vec4f vnormalize(vec4f v);
float vdist(vec4f v1, vec4f v2);
vec4f vproj(vec4f v1, vec4f v2);
class mat4f
{
public:
float data[16];
mat4f();
mat4f(
float _xx, float _yx, float _zx, float _wx,
float _xy, float _yy, float _zy, float _wy,
float _xz, float _yz, float _zz, float _wz,
float _xw, float _yw, float _zw, float _ww
);
mat4f(const float *_data);
mat4f(const mat4f &rhs);
mat4f(const vec4f _col1, const vec4f _col2, const vec4f _col3, const vec4f _col4);
mat4f& operator=(const mat4f rhs);
bool operator==(const mat4f rhs);
mat4f operator+(mat4f rhs) const;
mat4f operator-(mat4f rhs) const;
mat4f operator*(mat4f rhs) const;
mat4f operator/(mat4f rhs) const;
mat4f operator*(float rhs) const;
mat4f operator/(float rhs) const;
vec4f operator*(vec4f rhs) const;
float& operator()(int I, int J);
float& operator[](int I);
const float& operator()(int I, int J) const;
const float& operator[](int I) const;
float& at(int I, int J);
const float& at(int I, int J) const;
float det();
mat4f inverse();
void invert();
mat4f transpose();
void dotranspose();
};
//matrix operations
mat4f mat4f_eye();
mat4f mat4f_zeros();
mat4f mat4f_ones();
mat4f mat4f_mult(mat4f a, mat4f b);
vec4f mat4f_mult(vec4f a, mat4f b);
vec4f mat4f_mult(mat4f a, vec4f b);
float mat4f_det(mat4f a);
mat4f mat4f_inverse(mat4f a);
mat4f mat4f_transpose(mat4f a);
}; //end namespace ams

@ -6,6 +6,25 @@ namespace ams
namespace rand
{
typedef ::int32_t amsmu_randt1;
typedef ::int64_t amsmu_randt2;
static const amsmu_randt1 dpr32_mod = ( ((amsmu_randt1)1) << ((amsmu_randt1)30) ) - (amsmu_randt1)1;
static const amsmu_randt1 dpr32_mult1 = ( (amsmu_randt1) 1201633 );
static const amsmu_randt1 dpr32_add1 = ( (amsmu_randt1) 293482 );
static const amsmu_randt2 dpr64_mod = ( ((amsmu_randt2)1) << ((amsmu_randt2)62) ) - (amsmu_randt2)1;
static const amsmu_randt2 dpr64_mult1 = ( (amsmu_randt2) 1201633L );
static const amsmu_randt2 dpr64_add1 = ( (amsmu_randt2) 293482L );
extern amsmu_randt1 dpr32_rseed;
extern amsmu_randt2 dpr64_rseed;
amsmu_randt1 dpr32_nextseed(amsmu_randt1 seed);
amsmu_randt2 dpr64_nextseed(amsmu_randt2 seed);
}; //end namespace rand
}; //end namespace ams

@ -9,6 +9,9 @@ namespace amsmathutil25
void test_amsarray1();
void test_amsarray2();
void test_select();
void test_amsarray_sort();
}; //end namespace amsmathutil25
}; //end namespace ams

@ -78,12 +78,15 @@ namespace ams
amsarray<T> subarray(amsarray_size_t ind1, amsarray_size_t ind2) const;
//returns an array that is {thisarray[inds[0]],thisarray[inds[1]],...}
amsarray<T> select(amsarray<amsarray_size_t> inds);
amsarray<T> select(const amsarray<amsarray_size_t> &inds);
//returns an array of indices that is a permutation which will sort
//this array in ascending order
amsarray<amsarray_size_t> sort_permutation();
//sorts this array
int sort();
//returns an array that is this array in reverse order
amsarray<T> reverse();

@ -122,8 +122,6 @@ namespace ams
amsarray_size_t I;
int res;
if(this!=&other)
{
res = this->resize(other.size());
if(res!=amsarray_success)
{
@ -136,7 +134,7 @@ namespace ams
data[I] = other[I];
}
}
}
return *this;
}
@ -565,14 +563,14 @@ template<typename T> bool amsarray<T>::operator!=(const amsarray<T>& other) cons
template<typename T> int amsarray<T>::append(const T& val)
{
int ret = amsarray_success;
ret = insert(val,length);
ret = insert(length,val);
return ret;
}
template<typename T> int amsarray<T>::prepend(const T& val)
{
int ret = amsarray_success;
ret = insert(val,0);
ret = insert(0,val);
return ret;
}
@ -603,8 +601,8 @@ template<typename T> T amsarray<T>::pop_front()
template<typename T> void amsarray_select_tf(
int threadnum,
int nthreads,
amsarray<T> *array,
amsarray<amsarray_size_t> *inds,
const amsarray<T> *array,
const amsarray<amsarray_size_t> *inds,
amsarray<T> *ret
)
{
@ -634,7 +632,7 @@ template<typename T> void amsarray_select_tf(
}
//returns an array that is {thisarray[inds[0]],thisarray[inds[1]],...}
template<typename T> amsarray<T> amsarray<T>::select(amsarray<amsarray_size_t> inds)
template<typename T> amsarray<T> amsarray<T>::select(const amsarray<amsarray_size_t> &inds)
{
int res;
amsarray<T> ret;
@ -667,7 +665,7 @@ template<typename T> amsarray<T> amsarray<T>::select(amsarray<amsarray_size_t> i
else
{
threaded_execute(
&amsarray_select_tf,
&amsarray_select_tf<T>,
inds.length,
this,
&inds,
@ -681,7 +679,7 @@ template<typename T> amsarray<T> amsarray<T>::select(amsarray<amsarray_size_t> i
template<typename T> void amsarray_reverse_tf(
int threadnum,
int nthreads,
amsarray<T> *array,
const amsarray<T> *array,
amsarray<T> *ret
)
{
@ -727,7 +725,7 @@ template<typename T> amsarray<T> amsarray<T>::reverse()
else
{
threaded_execute(
&amsarray_reverse_tf,
&amsarray_reverse_tf<T>,
length,
this,
&ret
@ -737,7 +735,10 @@ template<typename T> amsarray<T> amsarray<T>::reverse()
return ret;
}
template<typename T> void amsarray<T>::print(bool newline, int printstyle)
{
//empty method - specialize for each type
}

@ -4,12 +4,13 @@
namespace ams
{
void amsarray_permutation_swap(amsarray<amsarray_size_t> *permutation, amsarray_size_t I, amsarray_size_t J);
template<typename T> int amsarray_quicksort_round(
amsarray<T> *array,
amsarray<amsarray_size_t> *permarray,
ams::pair<amsarray_size_t,amsarray_size_t> range,
amsarray_size_t *pivot_index,
amsarray<T> *array, //size N - array to sort
amsarray<amsarray_size_t> *permarray, //size N - permutation of sorting
ams::pair<amsarray_size_t,amsarray_size_t> range, //range over which to quicksort
ams::pair<amsarray_size_t,amsarray_size_t> *leftrange,
ams::pair<amsarray_size_t,amsarray_size_t> *rightrange
)
@ -20,12 +21,13 @@ template<typename T> int amsarray_quicksort_round(
T v1,v2;
amsarray_size_t tmp;
b1 = range.a < 0 || range.b < 0;
b2 = (range.b - range.a) < 2;
if((b1 || b2)
if(b1 || b2)
{
//there is no more work to be done within this range
*pivot_index = -1;
*leftrange = ams::pair<amsarray_size_t,amsarray_size_t>(-1,-1);
*rightrange = ams::pair<amsarray_size_t,amsarray_size_t>(-1,-1);
ret = -1;
@ -35,16 +37,15 @@ template<typename T> int amsarray_quicksort_round(
{
//two element range - sort directly
v1 = array->data[permarray->data[range.a]];
v2 = array->data[permarray->data[range.b]];
v2 = array->data[permarray->data[range.b-1]];
if(v2<v1)
{
//swap permutation indices
tmp = permarray->data[range.a];
permarray->data[range.a] = permarray->data[range.b];
permarray->data[range.b] = tmp;
permarray->data[range.a] = permarray->data[range.b-1];
permarray->data[range.b-1] = tmp;
}
//there is no more work to be done within this range
*pivot_index = -1;
*leftrange = ams::pair<amsarray_size_t,amsarray_size_t>(-1,-1);
*rightrange = ams::pair<amsarray_size_t,amsarray_size_t>(-1,-1);
ret = -1;
@ -52,19 +53,261 @@ template<typename T> int amsarray_quicksort_round(
}
else
{
//perform quicksort iteration
//perform quicksort round
//choose midpoint pivot
P = (range.a + range.b)/2;
P = (P<range.a) ? range.a : P;
P = (P>=range.b) ? range.b-1 : P;
//swap pivot to end of range
amsarray_permutation_swap(permarray,P,range.b-1);
P = range.b-1;
J = range.a;
for(I=range.a;I<range.b-1;I++)
{
if(array->data[permarray->data[I]]<array->data[permarray->data[P]])
{
if(J!=I)
{
amsarray_permutation_swap(permarray,I,J);
J++;
}
else
{
J++;
}
}
}
if(array->data[permarray->data[J]]<array->data[permarray->data[P]])
{
J++;
amsarray_permutation_swap(permarray,P,J);
}
else
{
amsarray_permutation_swap(permarray,P,J);
}
P = J;
if(P-range.a<=0)
{
leftrange->a = -1;
leftrange->b = -1;
}
else
{
leftrange->a = range.a;
leftrange->b = P;
}
if(range.b-(P+1)<=0)
{
rightrange->a = -1;
rightrange->b = -1;
}
else
{
rightrange->a = P+1;
rightrange->b = range.b;
}
ret = 1; //there is more work to do
}
return ret;
}
template<typename T> int amsarray_quicksort_unthreaded(
amsarray<T> *array, //size N - array to sort
amsarray<amsarray_size_t> *permarray //size N - permutation of sorting
)
{
int ret = amsarray_success;
int res;
amsarray<ams::pair<amsarray_size_t,amsarray_size_t>> ranges;
amsarray_size_t rangeptr = 0;
ams::pair<amsarray_size_t,amsarray_size_t> range,rangeleft,rangeright;
if(permarray->length!=array->length)
{
*permarray = permutation_identity(array->length);
if(permarray->length!=array->length)
{
ret = amsarray_failure;
return ret;
}
}
ranges.append(ams::pair<amsarray_size_t,amsarray_size_t>(0,array->length));
rangeptr = 0;
while(rangeptr<ranges.length)
{
range = ranges[rangeptr];
rangeptr++;
amsarray_quicksort_round(array,permarray,range,&rangeleft,&rangeright);
if(rangeleft.a>=0 && rangeleft.b>rangeleft.a)
{
ranges.append(rangeleft);
}
if(rangeright.a>=0 && rangeright.b>rangeright.a)
{
ranges.append(rangeright);
}
}
return ret;
}
template<typename T> void amsarray_quicksort_tf(
amsarray<T> *array, //size N - array to sort
amsarray<amsarray_size_t> *permarray, //size N - permutation of sorting
ams::pair<amsarray_size_t,amsarray_size_t> range,
amsarray<ams::pair<amsarray_size_t,amsarray_size_t>> *ranges,
std::mutex* threadlock
)
{
int res;
ams::pair<amsarray_size_t,amsarray_size_t> rangeleft,rangeright;
res = amsarray_quicksort_round(
array,
permarray,
range,
&rangeleft,
&rangeright
);
{ //scope wrapper for std::lock_guard
std::lock_guard<std::mutex> lock(*threadlock);
//critical section
if(rangeleft.a>=0 && rangeleft.b>rangeleft.a)
{
ranges->append(rangeleft);
}
if(rangeright.a>=0 && rangeright.b>rangeright.a)
{
ranges->append(rangeright);
}
}
//end critical section (end of function)
return;
}
template<typename T> int amsarray_quicksort_threaded(
amsarray<T> *array, //size N - array to sort
amsarray<amsarray_size_t> *permarray //size N - permutation of sorting
)
{
int ret = amsarray_success;
int res;
amsarray<ams::pair<amsarray_size_t,amsarray_size_t>> ranges;
amsarray_size_t rangeptr = 0;
amsarray_size_t I = 0;
ams::pair<amsarray_size_t,amsarray_size_t> range;
amsarray<std::thread*> threads;
std::mutex threadlock;
int maxthreads = std::thread::hardware_concurrency();
maxthreads = (maxthreads < 1) ? 1 : maxthreads;
maxthreads = (maxthreads>amsmathutil25_maxthreads) ? amsmathutil25_maxthreads : maxthreads;
int nthreads;
if(permarray->length!=array->length)
{
*permarray = permutation_identity(array->length);
if(permarray->length!=array->length)
{
ret = amsarray_failure;
return ret;
}
}
threads.resize(maxthreads);
threads.setall(NULL);
rangeptr = 0;
ranges.append(ams::pair<amsarray_size_t,amsarray_size_t>(0,array->length));
while(rangeptr<ranges.length)
{
//spawn up to the maximum number of threads
nthreads = ranges.length-rangeptr;
nthreads = (nthreads>maxthreads) ? maxthreads : nthreads;
for(I=0;I<nthreads;I++)
{
range = ranges[rangeptr+I];
threads[I] = new(std::nothrow) std::thread(
amsarray_quicksort_tf<T>,
array,permarray,
range,
&ranges,
&threadlock
);
}
for(I=0;I<nthreads;I++)
{
if(threads[I]==NULL)
{
printf("amsarray_quicksort_threaded: error: thread %ld failed to spawn\n",I);
ret = amsarray_failure;
}
}
for(I=0;I<nthreads;I++)
{
if(threads[I]!=NULL)
{
threads[I]->join();
delete threads[I];
threads[I] = NULL;
}
rangeptr++;
}
}
return ret;
}
template<typename T> int amsarray_quicksort(
amsarray<T> *array, //size N - array to sort
amsarray<amsarray_size_t> *permarray //size N - permutation of sorting
)
{
int ret = amsarray_success;
int res;
if(permarray->length!=array->length)
{
*permarray = permutation_identity(array->length);
if(permarray->length!=array->length)
{
ret = amsarray_failure;
return ret;
}
}
if(array->length<amsmathutil25_threadpsz)
{
//perform unthreaded quicksort
ret = amsarray_quicksort_unthreaded(
array,
permarray
);
}
else
{
//perform threaded quicksort
ret = amsarray_quicksort_threaded(
array,
permarray
);
}
return ret;
}
@ -77,9 +320,37 @@ template<typename T> amsarray<amsarray_size_t> amsarray<T>::sort_permutation()
int res;
amsarray<amsarray_size_t> ret;
ret = permutation_identity(this->length);
if(ret.length!=this->length)
{
printf("sort_permutation: error - permutation array failed to allocate.\n");
}
res = amsarray_quicksort(
this,&ret
);
return ret;
}
//returns an array of indices that is a permutation which will sort
//this array in ascending order
template<typename T> int amsarray<T>::sort()
{
int ret = amsarray_success;
amsarray<amsarray_size_t> perm;
perm = sort_permutation();
if(perm.length==this->length)
{
*this = this->select(perm);
}
else
{
ret = amsarray_failure;
}
return ret;
}

@ -11,6 +11,12 @@ namespace ams
//threaded set - sets N elements of bufffer to val
template<typename T> int buffer_set(T* buffer, buffer_size_t indstart, buffer_size_t indstop, const T val);
//threaded set - sets N elements of bufffer to val
template<typename T> int buffer_set_unthreaded(T* buffer, buffer_size_t N, const T val);
//threaded set - sets N elements of bufffer to val
template<typename T> int buffer_set_unthreaded(T* buffer, buffer_size_t indstart, buffer_size_t indstop, const T val);
//threaded copy of bufferfrom[offsetfrom + I] to bufferto[offsetto+I] I = [0,N)
template<typename T1, typename T2> int buffer_cast_copy(T1* bufferto, const T2* bufferfrom,
buffer_size_t offsetto, buffer_size_t offsetfrom, buffer_size_t N);
@ -18,6 +24,13 @@ namespace ams
//threaded copy of bufferfrom to bufferto
template<typename T1, typename T2> int buffer_cast_copy(T1* bufferto, const T2* bufferfrom, buffer_size_t N);
//threaded copy of bufferfrom[offsetfrom + I] to bufferto[offsetto+I] I = [0,N)
template<typename T1, typename T2> int buffer_cast_copy_unthreaded(T1* bufferto, const T2* bufferfrom,
buffer_size_t offsetto, buffer_size_t offsetfrom, buffer_size_t N);
//threaded copy of bufferfrom to bufferto
template<typename T1, typename T2> int buffer_cast_copy_unthreaded(T1* bufferto, const T2* bufferfrom, buffer_size_t N);
}; //end namespace ams
#include <amsmathutil25/util/amsmathutil25_bufferops_impl.hpp>

@ -40,6 +40,7 @@ namespace ams
template<typename T> int buffer_set(T* buffer, buffer_size_t indstart, buffer_size_t indstop, const T val)
{
int ret = amsmathutil25_success;
int res;
buffer_size_t psize;
buffer_size_t I;
@ -59,15 +60,51 @@ namespace ams
else
{
ams::threaded_execute(
res = ams::threaded_execute(
&buffer_set_tf<T>,(int64_t) psize,
buffer,indstart,indstop,val
);
ret = res;
}
return ret;
}
//threaded set - sets N elements of bufffer to val
template<typename T> int buffer_set_unthreaded(T* buffer, buffer_size_t N, const T val)
{
int ret = amsmathutil25_success;
buffer_size_t I;
for(I=0;I<N;I++)
{
buffer[I] = val;
}
return ret;
}
//threaded set - sets N elements of bufffer to val
template<typename T> int buffer_set_unthreaded(T* buffer, buffer_size_t indstart, buffer_size_t indstop, const T val)
{
int ret = amsmathutil25_success;
buffer_size_t I;
buffer_size_t psize;
indstart = (indstart<0) ? 0 : indstart;
indstop = (indstop<0) ? 0 : indstop;
indstop = (indstop<indstart) ? indstart : indstop;
psize = indstop-indstart;
for(I=0;I<psize;I++)
{
buffer[I+indstart] = val;
}
return ret;
}
//threaded set - sets N elements of bufffer to val
template<typename T> int buffer_set(T* buffer, buffer_size_t N, const T val)
{
@ -128,11 +165,12 @@ namespace ams
buffer_size_t offsetto, buffer_size_t offsetfrom, buffer_size_t N)
{
int ret = amsmathutil25_success;
ams::threaded_execute(
int res;
res = ams::threaded_execute(
&buffer_cast_copy_tf<T1,T2>,(int64_t) N,
bufferto,bufferfrom,offsetto,offsetfrom,N
);
ret = res;
return ret;
}
@ -155,6 +193,36 @@ namespace ams
return ret;
}
//threaded copy of bufferfrom[offsetfrom + I] to bufferto[offsetto+I] I = [0,N)
template<typename T1, typename T2> int buffer_cast_copy_unthreaded(T1* bufferto, const T2* bufferfrom,
buffer_size_t offsetto, buffer_size_t offsetfrom, buffer_size_t N)
{
int ret = amsmathutil25_success;
buffer_size_t I;
for(I=0;I<N;I++)
{
bufferto[I+offsetto] = (T1) bufferfrom[I+offsetfrom];
}
return ret;
}
//threaded copy of bufferfrom to bufferto
template<typename T1, typename T2> int buffer_cast_copy_unthreaded(T1* bufferto, const T2* bufferfrom, buffer_size_t N)
{
int ret = amsmathutil25_success;
buffer_size_t I;
for(I=0;I<N;I++)
{
bufferto[I] = (T1) bufferfrom[I];
}
return ret;
}
}; //end namespace ams
#endif

@ -0,0 +1,214 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
namespace amsmathutil25
{
bool isnan(double d)
{
bool ret = 0;
if(d!=d)
{
ret = 1;
}
return ret;
}
bool isinf(double d)
{
bool ret = 0;
ret = std::isinf(d);
return ret;
}
bool isinfnan(double d)
{
bool ret = 0;
ret = ams::isinf(d) || ams::isnan(d);
return ret;
}
bool isnan(float f)
{
bool ret = 0;
if(f!=f)
{
ret = 1;
}
return ret;
}
bool isinf(float f)
{
bool ret = 0;
ret = std::isinf(f);
return ret;
}
bool isinfnan(float f)
{
bool ret = 0;
ret = ams::isinf(f) || ams::isnan(f);
return ret;
}
double arg(double x, double y)
{
double ret = 0.0;
double z = ::sqrt(x*x+y*y);
if(z>1.0E-10)
{
ret = ::atan2(y,x);
if(ret<0.0) ret = ret + 2.0*ams::pi;
}
return ret;
}
float arg(float x, float y)
{
float ret = 0.0f;
float z = ::sqrtf(x*x+y*y);
if(z>1.0E-10)
{
ret = ::atan2f(y,x);
if(ret<0.0f) ret = ret + ams::pif;
}
return ret;
}
double sgn(double d)
{
double ret = 0.0;
ret = (d>0.0) ? 1.0 : ret;
ret = (d<0.0) ? -1.0 : ret;
return ret;
}
float sgn(float f)
{
float ret = 0.0f;
ret = (f>0.0f) ? 1.0f : ret;
ret = (f<0.0f) ? -1.0f : ret;
return ret;
}
//It has come to my attention that the behavior of Cs
//fmod is odd: Negative numbers have negative moduli
//I need to fix this with a proper modular function, whose values are in [0,N)
double mod(double x, double n)
{
x = ::fmod(x,n);
if(x<0)
{
x = x + n;
}
return x;
}
float mod(float x, float n)
{
x = ::fmodf(x,n);
if(x<0)
{
x = x + n;
}
return x;
}
int32_t mod(int32_t x, int32_t n)
{
x = x % n;
if(x<0)
{
x = x + n;
}
return x;
}
int64_t mod(int64_t x, int64_t n)
{
x = x % n;
if(x<0)
{
x = x + n;
}
return x;
}
int32_t truediv(int32_t x, int32_t y)
{
int32_t z = 0;
if(x>=0 && y>0)
{
z = x/y;
}
else if(x<0 && y>0)
{
z = -((-x)/y) - 1;
}
else if(x>=0 && y<0)
{
z = -(x/(-y)) - 1;
}
else if(x<0 && y<0)
{
z = ((-x)/(-y));
}
return z;
}
int64_t truediv(int64_t x, int64_t y)
{
int64_t z = 0;
if(x>=0 && y>0)
{
z = x/y;
}
else if(x<0 && y>0)
{
z = -((-x)/y) - 1;
}
else if(x>=0 && y<0)
{
z = -(x/(-y)) - 1;
}
else if(x<0 && y<0)
{
z = ((-x)/(-y));
}
return z;
}
double abs(double a)
{
double ret = ::fabs(a);
return ret;
}
float abs(float a)
{
float ret = ::fabsf(a);
return ret;
}
int32_t abs(int32_t a)
{
int32_t ret = (a<0) ? -a : a;
return ret;
}
int64_t abs(int64_t a)
{
int64_t ret = (a<0) ? -a : a;
return ret;
}
};
};

@ -0,0 +1,466 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
vec2::vec2()
{
x = 0.0;
y = 0.0;
}
vec2::vec2(double _x, double _y)
{
x = _x;
y = _y;
}
vec2& vec2::operator=(const vec2 &rhs)
{
if(this!=&rhs)
{
this->x = rhs.x;
this->y = rhs.y;
}
return *this;
}
bool vec2::operator==(vec2 rhs)
{
bool ret = 1;
ret = ret & (rhs.x == x);
ret = ret & (rhs.y == y);
return ret;
}
vec2::vec2(const vec2 &rhs)
{
this->x = rhs.x;
this->y = rhs.y;
return;
}
vec2 vec2::operator+(vec2 rhs) const
{
vec2 ret;
ret.x = this->x + rhs.x;
ret.y = this->y + rhs.y;
return ret;
}
vec2 vec2::operator-(vec2 rhs) const
{
vec2 ret;
ret.x = this->x - rhs.x;
ret.y = this->y - rhs.y;
return ret;
}
vec2 vec2::operator*(double rhs) const
{
vec2 ret;
ret.x = this->x*rhs;
ret.y = this->y*rhs;
return ret;
}
vec2 vec2::operator/(double rhs) const
{
vec2 ret;
ret.x = this->x/rhs;
ret.y = this->y/rhs;
return ret;
}
vec2 operator-(vec2 rhs)
{
vec2 ret;
ret.x = -rhs.x;
ret.y = -rhs.y;
return ret;
}
double& vec2::operator[](int ind)
{
if(ind==0) return x;
else if(ind==1) return y;
return x;
}
const double& vec2::operator[](int ind) const
{
if(ind==0) return x;
else if(ind==1) return y;
return x;
}
// vec2 vector operations
double vec2_dot(vec2 v1, vec2 v2)
{
double ret = v1.x*v2.x + v1.y*v2.y;
return ret;
}
double vec2_norm(vec2 v)
{
double ret = ::sqrt(v.x*v.x+v.y*v.y);
return ret;
}
vec2 vec2_normalize(vec2 v)
{
vec2 ret = vec2(0,0);
double nrm = vec2_norm(v);
if(nrm>0.0)
{
ret = v/nrm;
}
return ret;
}
double vec2_dist(vec2 v1, vec2 v2)
{
return vec2_norm(v1-v2);
}
double vec2_cross(vec2 v1, vec2 v2)
{
double ret = v1.x*v2.y - v1.y*v2.x;
return ret;
}
vec2 vec2_proj(vec2 v1, vec2 v2)
{
vec2 ret;
vec2 v2n = vec2_normalize(v2);
ret = v2n*vec2_dot(v1,v2n);
return ret;
}
vec2 vec2_hodgedual(vec2 v)
{
vec2 ret;
ret.x = -v.y;
ret.y = v.x;
return ret;
}
double vec2_arg(vec2 v)
{
double ret;
ret = ::atan2(v.y,v.x);
if(ret<0.0)
{
ret = ret + 2.0*ams::pi;
}
return ret;
}
// vec2 vector operations (old nomenclature)
double vdot(vec2 v1, vec2 v2)
{
return vec2_dot(v1,v2);
}
double vnorm(vec2 v)
{
return vec2_norm(v);
}
vec2 vnormalize(vec2 v)
{
return vec2_normalize(v);
}
double vdist(vec2 v1, vec2 v2)
{
return vec2_dist(v1,v2);
}
double vcross(vec2 v1, vec2 v2)
{
return vec2_cross(v1,v2);
}
vec2 vproj(vec2 v1, vec2 v2)
{
return vec2_proj(v1,v2);
}
// mat2 constructors and operators
mat2::mat2()
{
int I;
for(I=0;I<4;I++) data[I] = 0.0;
return;
}
mat2::mat2(double _xx, double _yx, double _xy, double _yy)
{
data[0] = _xx;
data[1] = _yx;
data[2] = _xy;
data[3] = _yy;
return;
}
mat2::mat2(const double *_data)
{
int I;
for(I=0;I<4;I++) data[I] = _data[I];
}
mat2::mat2(const mat2 &rhs)
{
int I;
for(I=0;I<4;I++) data[I] = rhs.data[I];
}
mat2::mat2(const vec2 _col1, const vec2 _col2)
{
data[0] = _col1[0];
data[1] = _col1[1];
data[2] = _col2[0];
data[3] = _col2[1];
}
mat2& mat2::operator=(const mat2 rhs)
{
int I;
for(I=0;I<4;I++)
{
data[I] = rhs.data[I];
}
return *this;
}
bool mat2::operator==(const mat2 rhs)
{
bool ret = 1;
int I;
for(I=0;I<4;I++)
{
if(data[I]!=rhs.data[I])
{
ret = 0;
break;
}
}
return ret;
}
mat2 mat2::operator+(mat2 rhs) const
{
mat2 ret;
int I;
for(I=0;I<4;I++)
{
ret.data[I] = this->data[I] + rhs.data[I];
}
return ret;
}
mat2 mat2::operator-(mat2 rhs) const
{
mat2 ret;
int I;
for(I=0;I<4;I++)
{
ret.data[I] = this->data[I] - rhs.data[I];
}
return ret;
}
mat2 mat2::operator*(mat2 rhs) const
{
mat2 ret = mat2(0,0,0,0);
int I,J,K;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
for(K=0;K<2;K++)
ret(I,K) += + (*this)(I,J)*rhs(J,K);
return ret;
}
mat2 mat2::operator/(mat2 rhs) const
{
mat2 rhsi = rhs.inverse();
return (*this)*rhsi;
}
mat2 mat2::operator*(double rhs) const
{
mat2 ret;
int I;
for(I=0;I<4;I++) ret.data[I] = this->data[I]*rhs;
return ret;
}
mat2 mat2::operator/(double rhs) const
{
mat2 ret;
int I;
for(I=0;I<4;I++) ret.data[I] = this->data[I]/rhs;
return ret;
}
vec2 mat2::operator*(vec2 rhs) const
{
vec2 ret = vec2(0,0);
int I,J;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
ret[I] += (*this)(I,J)*rhs[J];
return ret;
}
double& mat2::operator()(int I, int J)
{
if(I==0&&J==0) return data[0];
if(I==1&&J==0) return data[1];
if(I==0&&J==1) return data[2];
if(I==1&&J==1) return data[3];
return data[0];
}
double& mat2::operator[](int I)
{
return data[I];
}
const double& mat2::operator()(int I, int J) const
{
if(I==0&&J==0) return data[0];
if(I==1&&J==0) return data[1];
if(I==0&&J==1) return data[2];
if(I==1&&J==1) return data[3];
return data[0];
}
const double& mat2::operator[](int I) const
{
return data[I];
}
double& mat2::at(int I, int J)
{
return (*this)(I,J);
}
const double& mat2::at(int I, int J) const
{
return (*this)(I,J);
}
double mat2::det()
{
double ret = 0.0;
ret = ret + (*this)(0,0)*(*this)(1,1);
ret = ret - (*this)(1,0)*(*this)(0,1);
return ret;
}
mat2 mat2::inverse()
{
mat2 ret = mat2_zeros();
double dt = this->det();
if(dt>=vecmat_det_small || dt<=-vecmat_det_small)
{
ret(0,0) = (*this)(1,1)/dt;
ret(0,1) = -(*this)(0,1)/dt;
ret(1,0) = -(*this)(1,0)/dt;
ret(1,1) = (*this)(0,0)/dt;
}
return ret;
}
void mat2::invert()
{
mat2 q = this->inverse();
*this = q;
return;
}
mat2 mat2::transpose()
{
mat2 ret;
int I,J;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
ret(I,J) = this->at(J,I);
return ret;
}
void mat2::dotranspose()
{
mat2 t = this->transpose();
(*this) = t;
return;
}
// mat2 matrix operations
mat2 mat2_eye()
{
mat2 ret;
ret(0,0) = 1.0;
ret(1,1) = 1.0;
ret(0,1) = 0.0;
ret(1,0) = 0.0;
return ret;
}
mat2 mat2_zeros()
{
mat2 ret;
int I;
for(I=0;I<4;I++) ret.data[I] = 0.0;
return ret;
}
mat2 mat2_ones()
{
mat2 ret;
int I;
for(I=0;I<4;I++) ret.data[I] = 1.0;
return ret;
}
mat2 mat2_mult(mat2 a, mat2 b)
{
return a*b;
}
vec2 mat2_mult(vec2 a, mat2 b)
{
vec2 ret = vec2(0,0);
int I,J;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
ret[J] += a[I]*b(I,J);
return ret;
}
vec2 mat2_mult(mat2 a, vec2 b)
{
return a*b;
}
double mat2_det(mat2 a)
{
return a.det();
}
mat2 mat2_inverse(mat2 a)
{
return a.inverse();
}
mat2 mat2_transpose(mat2 a)
{
return a.transpose();
}
}; // end namespace ams

@ -0,0 +1,463 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
vec2f::vec2f()
{
x = 0.0f;
y = 0.0f;
}
vec2f::vec2f(float _x, float _y)
{
x = _x;
y = _y;
}
vec2f& vec2f::operator=(const vec2f &rhs)
{
if(this!=&rhs)
{
this->x = rhs.x;
this->y = rhs.y;
}
return *this;
}
bool vec2f::operator==(vec2f rhs)
{
bool ret = 1;
ret = ret & (rhs.x == x);
ret = ret & (rhs.y == y);
return ret;
}
vec2f::vec2f(const vec2f &rhs)
{
this->x = rhs.x;
this->y = rhs.y;
return;
}
vec2f vec2f::operator+(vec2f rhs) const
{
vec2f ret;
ret.x = this->x + rhs.x;
ret.y = this->y + rhs.y;
return ret;
}
vec2f vec2f::operator-(vec2f rhs) const
{
vec2f ret;
ret.x = this->x - rhs.x;
ret.y = this->y - rhs.y;
return ret;
}
vec2f vec2f::operator*(float rhs) const
{
vec2f ret;
ret.x = this->x*rhs;
ret.y = this->y*rhs;
return ret;
}
vec2f vec2f::operator/(float rhs) const
{
vec2f ret;
ret.x = this->x/rhs;
ret.y = this->y/rhs;
return ret;
}
vec2f operator-(vec2f rhs)
{
vec2f ret;
ret.x = -rhs.x;
ret.y = -rhs.y;
return ret;
}
float& vec2f::operator[](int ind)
{
if(ind==0) return x;
else if(ind==1) return y;
return x;
}
const float& vec2f::operator[](int ind) const
{
if(ind==0) return x;
else if(ind==1) return y;
return x;
}
float vec2f_dot(vec2f v1, vec2f v2)
{
float ret = v1.x*v2.x + v1.y*v2.y;
return ret;
}
float vec2f_norm(vec2f v)
{
float ret = ::sqrtf(v.x*v.x+v.y*v.y);
return ret;
}
vec2f vec2f_normalize(vec2f v)
{
vec2f ret = vec2f(0.0f,0.0f);
float nrm = vec2f_norm(v);
if(nrm>0.0f)
{
ret = v/nrm;
}
return ret;
}
float vec2f_dist(vec2f v1, vec2f v2)
{
return vec2f_norm(v1-v2);
}
float vec2f_cross(vec2f v1, vec2f v2)
{
float ret = v1.x*v2.y - v1.y*v2.x;
return ret;
}
vec2f vec2f_proj(vec2f v1, vec2f v2)
{
vec2f ret;
vec2f v2n = vec2f_normalize(v2);
ret = v2n*vec2f_dot(v1,v2n);
return ret;
}
vec2f vec2f_hodgedual(vec2f v)
{
vec2f ret;
ret.x = -v.y;
ret.y = v.x;
return ret;
}
float vec2f_arg(vec2f v)
{
float ret;
ret = ::atan2f(v.y,v.x);
if(ret<0.0f)
{
ret = ret + 2.0f*ams::pif;
}
return ret;
}
// vec2f vector operations (old nomenclature)
float vdot(vec2f v1, vec2f v2)
{
return vec2f_dot(v1,v2);
}
float vnorm(vec2f v)
{
return vec2f_norm(v);
}
vec2f vnormalize(vec2f v)
{
return vec2f_normalize(v);
}
float vdist(vec2f v1, vec2f v2)
{
return vec2f_dist(v1,v2);
}
float vcross(vec2f v1, vec2f v2)
{
return vec2f_cross(v1,v2);
}
vec2f vproj(vec2f v1, vec2f v2)
{
return vec2f_proj(v1,v2);
}
mat2f::mat2f()
{
int I;
for(I=0;I<4;I++) data[I] = 0.0f;
return;
}
mat2f::mat2f(float _xx, float _yx, float _xy, float _yy)
{
data[0] = _xx;
data[1] = _yx;
data[2] = _xy;
data[3] = _yy;
return;
}
mat2f::mat2f(const float *_data)
{
int I;
for(I=0;I<4;I++) data[I] = _data[I];
}
mat2f::mat2f(const mat2f &rhs)
{
int I;
for(I=0;I<4;I++) data[I] = rhs.data[I];
}
mat2f::mat2f(const vec2f _col1, const vec2f _col2)
{
data[0] = _col1[0];
data[1] = _col1[1];
data[2] = _col2[0];
data[3] = _col2[1];
}
mat2f& mat2f::operator=(const mat2f rhs)
{
int I;
for(I=0;I<4;I++)
{
data[I] = rhs.data[I];
}
return *this;
}
bool mat2f::operator==(const mat2f rhs)
{
bool ret = 1;
int I;
for(I=0;I<4;I++)
{
if(data[I]!=rhs.data[I])
{
ret = 0;
break;
}
}
return ret;
}
mat2f mat2f::operator+(mat2f rhs) const
{
mat2f ret;
int I;
for(I=0;I<4;I++)
{
ret.data[I] = this->data[I] + rhs.data[I];
}
return ret;
}
mat2f mat2f::operator-(mat2f rhs) const
{
mat2f ret;
int I;
for(I=0;I<4;I++)
{
ret.data[I] = this->data[I] - rhs.data[I];
}
return ret;
}
mat2f mat2f::operator*(mat2f rhs) const
{
mat2f ret = mat2f(0.0f,0.0f,0.0f,0.0f);
int I,J,K;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
for(K=0;K<2;K++)
ret(I,K) += + (*this)(I,J)*rhs(J,K);
return ret;
}
mat2f mat2f::operator/(mat2f rhs) const
{
mat2f rhsi = rhs.inverse();
return (*this)*rhsi;
}
mat2f mat2f::operator*(float rhs) const
{
mat2f ret;
int I;
for(I=0;I<4;I++) ret.data[I] = this->data[I]*rhs;
return ret;
}
mat2f mat2f::operator/(float rhs) const
{
mat2f ret;
int I;
for(I=0;I<4;I++) ret.data[I] = this->data[I]/rhs;
return ret;
}
vec2f mat2f::operator*(vec2f rhs) const
{
vec2f ret = vec2f(0.0f,0.0f);
int I,J;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
ret[I] += (*this)(I,J)*rhs[J];
return ret;
}
float& mat2f::operator()(int I, int J)
{
if(I==0&&J==0) return data[0];
if(I==1&&J==0) return data[1];
if(I==0&&J==1) return data[2];
if(I==1&&J==1) return data[3];
return data[0];
}
float& mat2f::operator[](int I)
{
return data[I];
}
const float& mat2f::operator()(int I, int J) const
{
if(I==0&&J==0) return data[0];
if(I==1&&J==0) return data[1];
if(I==0&&J==1) return data[2];
if(I==1&&J==1) return data[3];
return data[0];
}
const float& mat2f::operator[](int I) const
{
return data[I];
}
float& mat2f::at(int I, int J)
{
return (*this)(I,J);
}
const float& mat2f::at(int I, int J) const
{
return (*this)(I,J);
}
float mat2f::det()
{
float ret = 0.0f;
ret = ret + (*this)(0,0)*(*this)(1,1);
ret = ret - (*this)(1,0)*(*this)(0,1);
return ret;
}
mat2f mat2f::inverse()
{
mat2f ret = mat2f_zeros();
float dt = this->det();
if(dt>=vecmat_det_small || dt<=-vecmat_det_small)
{
ret(0,0) = (*this)(1,1)/dt;
ret(0,1) = -(*this)(0,1)/dt;
ret(1,0) = -(*this)(1,0)/dt;
ret(1,1) = (*this)(0,0)/dt;
}
return ret;
}
void mat2f::invert()
{
mat2f q = this->inverse();
*this = q;
return;
}
mat2f mat2f::transpose()
{
mat2f ret;
int I,J;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
ret(I,J) = this->at(J,I);
return ret;
}
void mat2f::dotranspose()
{
mat2f t = this->transpose();
(*this) = t;
return;
}
// mat2f matrix operations
mat2f mat2f_eye()
{
mat2f ret;
ret(0,0) = 1.0f;
ret(1,1) = 1.0f;
ret(0,1) = 0.0f;
ret(1,0) = 0.0f;
return ret;
}
mat2f mat2f_zeros()
{
mat2f ret;
int I;
for(I=0;I<4;I++) ret.data[I] = 0.0f;
return ret;
}
mat2f mat2f_ones()
{
mat2f ret;
int I;
for(I=0;I<4;I++) ret.data[I] = 1.0f;
return ret;
}
mat2f mat2f_mult(mat2f a, mat2f b)
{
return a*b;
}
vec2f mat2f_mult(vec2f a, mat2f b)
{
vec2f ret = vec2f(0.0f,0.0f);
int I,J;
for(I=0;I<2;I++)
for(J=0;J<2;J++)
ret[J] += a[I]*b(I,J);
return ret;
}
vec2f mat2f_mult(mat2f a, vec2f b)
{
return a*b;
}
float mat2f_det(mat2f a)
{
return a.det();
}
mat2f mat2f_inverse(mat2f a)
{
return a.inverse();
}
mat2f mat2f_transpose(mat2f a)
{
return a.transpose();
}
}; // end namespace ams

@ -0,0 +1,506 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
vec3::vec3()
{
x = 0.0;
y = 0.0;
z = 0.0;
return;
}
vec3::vec3(double _x, double _y, double _z)
{
x = _x;
y = _y;
z = _z;
return;
}
vec3::vec3(const vec3 &rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
return;
}
vec3& vec3::operator=(const vec3 &rhs)
{
this->x = rhs.x;
this->y = rhs.y;
this->z = rhs.z;
return *this;
}
bool vec3::operator==(vec3 rhs)
{
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z));
}
// vec3 arithmetic operators
vec3 vec3::operator+(vec3 rhs) const
{
vec3 ret;
ret.x = this->x + rhs.x;
ret.y = this->y + rhs.y;
ret.z = this->z + rhs.z;
return ret;
}
vec3 vec3::operator-(vec3 rhs) const
{
vec3 ret;
ret.x = this->x - rhs.x;
ret.y = this->y - rhs.y;
ret.z = this->z - rhs.z;
return ret;
}
vec3 vec3::operator*(double rhs) const
{
vec3 ret;
ret.x = this->x*rhs;
ret.y = this->y*rhs;
ret.z = this->z*rhs;
return ret;
}
vec3 vec3::operator/(double rhs) const
{
vec3 ret;
ret.x = this->x/rhs;
ret.y = this->y/rhs;
ret.z = this->z/rhs;
return ret;
}
vec3 operator-(vec3 rhs)
{
vec3 ret;
ret.x = -rhs.x;
ret.y = -rhs.y;
ret.z = -rhs.z;
return ret;
}
// vec3 subscript operators
double& vec3::operator[](int ind)
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
return x;
}
const double& vec3::operator[](int ind) const
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
return x;
}
// vector operations (new nomenclature)
double vec3_dot(vec3 v1, vec3 v2)
{
double ret = 0.0;
ret += v1.x*v2.x;
ret += v1.y*v2.y;
ret += v1.z*v2.z;
return ret;
}
double vec3_norm(vec3 v)
{
double ret = ::sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
return ret;
}
vec3 vec3_normalize(vec3 v)
{
vec3 ret = vec3(0,0,0);
double nrm = vec3_norm(v);
if(nrm>0.0)
{
ret = v/nrm;
}
return ret;
}
double vec3_dist(vec3 v1, vec3 v2)
{
return vec3_norm(v1-v2);
}
vec3 vec3_cross(vec3 v1, vec3 v2)
{
vec3 ret;
ret[0] = v1[1]*v2[2] - v1[2]*v2[1];
ret[1] = v1[2]*v2[0] - v1[0]*v2[2];
ret[2] = v1[0]*v2[1] - v1[1]*v2[0];
return ret;
}
vec3 vec3_proj(vec3 v1, vec3 v2)
{
vec3 ret;
vec3 v2n = vec3_normalize(v2);
ret = v2n*vec3_dot(v1,v2n);
return ret;
}
mat3 vec3_hodgedual(vec3 v)
{
mat3 ret;
ret(0,1) = v[2];
ret(1,2) = v[0];
ret(2,0) = v[1];
ret(1,0) = -v[2];
ret(2,1) = -v[0];
ret(0,2) = -v[1];
ret(0,0) = 0.0;
ret(1,1) = 0.0;
ret(2,2) = 0.0;
return ret;
}
// vector operations (old nomenclature)
double vdot(vec3 v1, vec3 v2)
{
return vec3_dot(v1,v2);
}
double vnorm(vec3 v)
{
return vec3_norm(v);
}
vec3 vnormalize(vec3 v)
{
return vec3_normalize(v);
}
double vdist(vec3 v1, vec3 v2)
{
return vec3_dist(v1,v2);
}
vec3 vcross(vec3 v1, vec3 v2)
{
return vec3_cross(v1,v2);
}
vec3 vproj(vec3 v1, vec3 v2)
{
return vec3_proj(v1,v2);
}
// mat3 constructors
mat3::mat3()
{
int I;
for(I=0;I<9;I++) data[I] = 0.0;
return;
}
mat3::mat3(double _xx, double _yx, double _zx, double _xy, double _yy, double _zy, double _xz, double _yz, double _zz)
{
data[0] = _xx;
data[1] = _yx;
data[2] = _zx;
data[3] = _xy;
data[4] = _yy;
data[5] = _zy;
data[6] = _xz;
data[7] = _yz;
data[8] = _zz;
return;
}
mat3::mat3(const double *_data)
{
int I;
for(I=0;I<9;I++) data[I] = _data[I];
return;
}
mat3::mat3(const mat3 &rhs)
{
int I;
for(I=0;I<9;I++) data[I] = rhs.data[I];
return;
}
mat3::mat3(const vec3 _col1, const vec3 _col2, const vec3 _col3)
{
data[0] = _col1[0];
data[1] = _col1[1];
data[2] = _col1[2];
data[3] = _col2[0];
data[4] = _col2[1];
data[5] = _col2[2];
data[6] = _col3[0];
data[7] = _col3[1];
data[8] = _col3[2];
return;
}
// mat3 assignment and comparison operators
mat3& mat3::operator=(const mat3 rhs)
{
int I;
for(I=0;I<9;I++) data[I] = rhs.data[I];
return *this;
}
bool mat3::operator==(const mat3 rhs)
{
bool ret = 1;
int I;
for(I=0;I<9;I++)
{
if(this->data[I]!=rhs.data[I])
{
ret = 0;
break;
}
}
return ret;
}
// mat3 arithmetic operators
mat3 mat3::operator+(mat3 rhs) const
{
mat3 ret;
int I;
for(I=0;I<9;I++)
{
ret.data[I] = this->data[I] + rhs.data[I];
}
return ret;
}
mat3 mat3::operator-(mat3 rhs) const
{
mat3 ret;
int I;
for(I=0;I<9;I++)
{
ret.data[I] = this->data[I] - rhs.data[I];
}
return ret;
}
mat3 mat3::operator*(mat3 rhs) const
{
mat3 ret = mat3_zeros();
int I,J,K;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
for(K=0;K<3;K++)
ret(I,K) += + (*this)(I,J)*rhs(J,K);
return ret;
}
mat3 mat3::operator/(mat3 rhs) const
{
mat3 rhsi = rhs.inverse();
return (*this)*rhsi;
}
mat3 mat3::operator*(double rhs) const
{
mat3 ret;
int I;
for(I=0;I<9;I++) ret.data[I] = this->data[I]*rhs;
return ret;
}
mat3 mat3::operator/(double rhs) const
{
mat3 ret;
int I;
for(I=0;I<9;I++) ret.data[I] = this->data[I]/rhs;
return ret;
}
vec3 mat3::operator*(vec3 rhs) const
{
vec3 ret = vec3(0,0,0);
int I,J;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
ret[I] += (*this)(I,J)*rhs[J];
return ret;
}
// mat3 access operators
double& mat3::operator()(int I, int J)
{
int ind = I + 3*J;
return data[ind];
}
double& mat3::operator[](int I)
{
return data[I];
}
const double& mat3::operator()(int I, int J) const
{
int ind = I + 3*J;
return data[ind];
}
const double& mat3::operator[](int I) const
{
return data[I];
}
double& mat3::at(int I, int J)
{
int ind = I + 3*J;
return data[ind];
}
const double& mat3::at(int I, int J) const
{
int ind = I + 3*J;
return data[ind];
}
// mat3 member functions
double mat3::det()
{
double ret = 0.0;
ret += (*this)(0,0)*(*this)(1,1)*(*this)(2,2);
ret += (*this)(0,1)*(*this)(1,2)*(*this)(2,0);
ret += (*this)(0,2)*(*this)(1,0)*(*this)(2,1);
ret -= (*this)(2,0)*(*this)(1,1)*(*this)(0,2);
ret -= (*this)(2,1)*(*this)(1,2)*(*this)(0,0);
ret -= (*this)(2,2)*(*this)(1,0)*(*this)(0,1);
return ret;
}
mat3 mat3::inverse()
{
mat3 ret = mat3_zeros();
double dt = this->det();
if(dt>vecmat_det_small||dt<-vecmat_det_small)
{
ret(0,0) = (this->at(1,1) * this->at(2,2) - this->at(1,2) * this->at(2,1))/dt;
ret(0,1) = -(this->at(1,0) * this->at(2,2) - this->at(1,2) * this->at(2,0))/dt;
ret(0,2) = (this->at(1,0) * this->at(2,1) - this->at(1,1) * this->at(2,0))/dt;
ret(1,0) = -(this->at(0,1) * this->at(2,2) - this->at(0,2) * this->at(2,1))/dt;
ret(1,1) = (this->at(0,0) * this->at(2,2) - this->at(0,2) * this->at(2,0))/dt;
ret(1,2) = -(this->at(0,0) * this->at(2,1) - this->at(0,1) * this->at(2,0))/dt;
ret(2,0) = (this->at(0,1) * this->at(1,2) - this->at(0,2) * this->at(1,1))/dt;
ret(2,1) = -(this->at(0,0) * this->at(1,2) - this->at(0,2) * this->at(1,0))/dt;
ret(2,2) = (this->at(0,0) * this->at(1,1) - this->at(0,1) * this->at(1,0))/dt;
}
return ret;
}
void mat3::invert()
{
mat3 m = this->inverse();
*this = m;
}
mat3 mat3::transpose()
{
mat3 ret;
int I,J;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
ret(I,J) = this->at(J,I);
return ret;
}
void mat3::dotranspose()
{
mat3 m = this->transpose();
*this = m;
}
// matrix operations (standalone functions)
mat3 mat3_eye()
{
mat3 ret = mat3_zeros();
ret(0,0) = 1.0;
ret(1,1) = 1.0;
ret(2,2) = 1.0;
return ret;
}
mat3 mat3_zeros()
{
mat3 ret;
// for speed - the constructor already sets data[I] to 0.0
// int I;
// for(I=0;I<9;I++) ret.data[I] = 0.0;
return ret;
}
mat3 mat3_ones()
{
mat3 ret;
int I;
for(I=0;I<9;I++) ret.data[I] = 1.0;
return ret;
}
mat3 mat3_mult(mat3 a, mat3 b)
{
return a*b;
}
vec3 mat3_mult(vec3 a, mat3 b)
{
vec3 ret = vec3(0,0,0);
int I,J;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
ret[J] += a[I] * b(I,J);
return ret;
}
vec3 mat3_mult(mat3 a, vec3 b)
{
return a*b;
}
double mat3_det(mat3 a)
{
return a.det();
}
mat3 mat3_inverse(mat3 a)
{
return a.inverse();
}
mat3 mat3_transpose(mat3 a)
{
return a.transpose();
}
};

@ -0,0 +1,506 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
vec3f::vec3f()
{
x = 0.0;
y = 0.0;
z = 0.0;
return;
}
vec3f::vec3f(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
return;
}
vec3f::vec3f(const vec3f &rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
return;
}
vec3f& vec3f::operator=(const vec3f &rhs)
{
this->x = rhs.x;
this->y = rhs.y;
this->z = rhs.z;
return *this;
}
bool vec3f::operator==(vec3f rhs)
{
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z));
}
// vec3f arithmetic operators
vec3f vec3f::operator+(vec3f rhs) const
{
vec3f ret;
ret.x = this->x + rhs.x;
ret.y = this->y + rhs.y;
ret.z = this->z + rhs.z;
return ret;
}
vec3f vec3f::operator-(vec3f rhs) const
{
vec3f ret;
ret.x = this->x - rhs.x;
ret.y = this->y - rhs.y;
ret.z = this->z - rhs.z;
return ret;
}
vec3f vec3f::operator*(float rhs) const
{
vec3f ret;
ret.x = this->x*rhs;
ret.y = this->y*rhs;
ret.z = this->z*rhs;
return ret;
}
vec3f vec3f::operator/(float rhs) const
{
vec3f ret;
ret.x = this->x/rhs;
ret.y = this->y/rhs;
ret.z = this->z/rhs;
return ret;
}
vec3f operator-(vec3f rhs)
{
vec3f ret;
ret.x = -rhs.x;
ret.y = -rhs.y;
ret.z = -rhs.z;
return ret;
}
// vec3f subscript operators
float& vec3f::operator[](int ind)
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
return x;
}
const float& vec3f::operator[](int ind) const
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
return x;
}
// vector operations (new nomenclature)
float vec3f_dot(vec3f v1, vec3f v2)
{
float ret = 0.0;
ret += v1.x*v2.x;
ret += v1.y*v2.y;
ret += v1.z*v2.z;
return ret;
}
float vec3f_norm(vec3f v)
{
float ret = ::sqrtf(v.x*v.x+v.y*v.y+v.z*v.z);
return ret;
}
vec3f vec3f_normalize(vec3f v)
{
vec3f ret = vec3f(0,0,0);
float nrm = vec3f_norm(v);
if(nrm>0.0)
{
ret = v/nrm;
}
return ret;
}
float vec3f_dist(vec3f v1, vec3f v2)
{
return vec3f_norm(v1-v2);
}
vec3f vec3f_cross(vec3f v1, vec3f v2)
{
vec3f ret;
ret[0] = v1[1]*v2[2] - v1[2]*v2[1];
ret[1] = v1[2]*v2[0] - v1[0]*v2[2];
ret[2] = v1[0]*v2[1] - v1[1]*v2[0];
return ret;
}
vec3f vec3f_proj(vec3f v1, vec3f v2)
{
vec3f ret;
vec3f v2n = vec3f_normalize(v2);
ret = v2n*vec3f_dot(v1,v2n);
return ret;
}
mat3f vec3f_hodgedual(vec3f v)
{
mat3f ret;
ret(0,1) = v[2];
ret(1,2) = v[0];
ret(2,0) = v[1];
ret(1,0) = -v[2];
ret(2,1) = -v[0];
ret(0,2) = -v[1];
ret(0,0) = 0.0;
ret(1,1) = 0.0;
ret(2,2) = 0.0;
return ret;
}
// vector operations (old nomenclature)
float vdot(vec3f v1, vec3f v2)
{
return vec3f_dot(v1,v2);
}
float vnorm(vec3f v)
{
return vec3f_norm(v);
}
vec3f vnormalize(vec3f v)
{
return vec3f_normalize(v);
}
float vdist(vec3f v1, vec3f v2)
{
return vec3f_dist(v1,v2);
}
vec3f vcross(vec3f v1, vec3f v2)
{
return vec3f_cross(v1,v2);
}
vec3f vproj(vec3f v1, vec3f v2)
{
return vec3f_proj(v1,v2);
}
// mat3f constructors
mat3f::mat3f()
{
int I;
for(I=0;I<9;I++) data[I] = 0.0;
return;
}
mat3f::mat3f(float _xx, float _yx, float _zx, float _xy, float _yy, float _zy, float _xz, float _yz, float _zz)
{
data[0] = _xx;
data[1] = _yx;
data[2] = _zx;
data[3] = _xy;
data[4] = _yy;
data[5] = _zy;
data[6] = _xz;
data[7] = _yz;
data[8] = _zz;
return;
}
mat3f::mat3f(const float *_data)
{
int I;
for(I=0;I<9;I++) data[I] = _data[I];
return;
}
mat3f::mat3f(const mat3f &rhs)
{
int I;
for(I=0;I<9;I++) data[I] = rhs.data[I];
return;
}
mat3f::mat3f(const vec3f _col1, const vec3f _col2, const vec3f _col3)
{
data[0] = _col1[0];
data[1] = _col1[1];
data[2] = _col1[2];
data[3] = _col2[0];
data[4] = _col2[1];
data[5] = _col2[2];
data[6] = _col3[0];
data[7] = _col3[1];
data[8] = _col3[2];
return;
}
// mat3f assignment and comparison operators
mat3f& mat3f::operator=(const mat3f rhs)
{
int I;
for(I=0;I<9;I++) data[I] = rhs.data[I];
return *this;
}
bool mat3f::operator==(const mat3f rhs)
{
bool ret = 1;
int I;
for(I=0;I<9;I++)
{
if(this->data[I]!=rhs.data[I])
{
ret = 0;
break;
}
}
return ret;
}
// mat3f arithmetic operators
mat3f mat3f::operator+(mat3f rhs) const
{
mat3f ret;
int I;
for(I=0;I<9;I++)
{
ret.data[I] = this->data[I] + rhs.data[I];
}
return ret;
}
mat3f mat3f::operator-(mat3f rhs) const
{
mat3f ret;
int I;
for(I=0;I<9;I++)
{
ret.data[I] = this->data[I] - rhs.data[I];
}
return ret;
}
mat3f mat3f::operator*(mat3f rhs) const
{
mat3f ret = mat3f_zeros();
int I,J,K;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
for(K=0;K<3;K++)
ret(I,K) += + (*this)(I,J)*rhs(J,K);
return ret;
}
mat3f mat3f::operator/(mat3f rhs) const
{
mat3f rhsi = rhs.inverse();
return (*this)*rhsi;
}
mat3f mat3f::operator*(float rhs) const
{
mat3f ret;
int I;
for(I=0;I<9;I++) ret.data[I] = this->data[I]*rhs;
return ret;
}
mat3f mat3f::operator/(float rhs) const
{
mat3f ret;
int I;
for(I=0;I<9;I++) ret.data[I] = this->data[I]/rhs;
return ret;
}
vec3f mat3f::operator*(vec3f rhs) const
{
vec3f ret = vec3f(0,0,0);
int I,J;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
ret[I] += (*this)(I,J)*rhs[J];
return ret;
}
// mat3f access operators
float& mat3f::operator()(int I, int J)
{
int ind = I + 3*J;
return data[ind];
}
float& mat3f::operator[](int I)
{
return data[I];
}
const float& mat3f::operator()(int I, int J) const
{
int ind = I + 3*J;
return data[ind];
}
const float& mat3f::operator[](int I) const
{
return data[I];
}
float& mat3f::at(int I, int J)
{
int ind = I + 3*J;
return data[ind];
}
const float& mat3f::at(int I, int J) const
{
int ind = I + 3*J;
return data[ind];
}
// mat3f member functions
float mat3f::det()
{
float ret = 0.0;
ret += (*this)(0,0)*(*this)(1,1)*(*this)(2,2);
ret += (*this)(0,1)*(*this)(1,2)*(*this)(2,0);
ret += (*this)(0,2)*(*this)(1,0)*(*this)(2,1);
ret -= (*this)(2,0)*(*this)(1,1)*(*this)(0,2);
ret -= (*this)(2,1)*(*this)(1,2)*(*this)(0,0);
ret -= (*this)(2,2)*(*this)(1,0)*(*this)(0,1);
return ret;
}
mat3f mat3f::inverse()
{
mat3f ret = mat3f_zeros();
float dt = this->det();
if(dt>vecmat_det_small||dt<-vecmat_det_small)
{
ret(0,0) = (this->at(1,1) * this->at(2,2) - this->at(1,2) * this->at(2,1))/dt;
ret(0,1) = -(this->at(1,0) * this->at(2,2) - this->at(1,2) * this->at(2,0))/dt;
ret(0,2) = (this->at(1,0) * this->at(2,1) - this->at(1,1) * this->at(2,0))/dt;
ret(1,0) = -(this->at(0,1) * this->at(2,2) - this->at(0,2) * this->at(2,1))/dt;
ret(1,1) = (this->at(0,0) * this->at(2,2) - this->at(0,2) * this->at(2,0))/dt;
ret(1,2) = -(this->at(0,0) * this->at(2,1) - this->at(0,1) * this->at(2,0))/dt;
ret(2,0) = (this->at(0,1) * this->at(1,2) - this->at(0,2) * this->at(1,1))/dt;
ret(2,1) = -(this->at(0,0) * this->at(1,2) - this->at(0,2) * this->at(1,0))/dt;
ret(2,2) = (this->at(0,0) * this->at(1,1) - this->at(0,1) * this->at(1,0))/dt;
}
return ret;
}
void mat3f::invert()
{
mat3f m = this->inverse();
*this = m;
}
mat3f mat3f::transpose()
{
mat3f ret;
int I,J;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
ret(I,J) = this->at(J,I);
return ret;
}
void mat3f::dotranspose()
{
mat3f m = this->transpose();
*this = m;
}
// matrix operations (standalone functions)
mat3f mat3f_eye()
{
mat3f ret = mat3f_zeros();
ret(0,0) = 1.0;
ret(1,1) = 1.0;
ret(2,2) = 1.0;
return ret;
}
mat3f mat3f_zeros()
{
mat3f ret;
// for speed - the constructor already sets data[I] to 0.0
// int I;
// for(I=0;I<9;I++) ret.data[I] = 0.0;
return ret;
}
mat3f mat3f_ones()
{
mat3f ret;
int I;
for(I=0;I<9;I++) ret.data[I] = 1.0;
return ret;
}
mat3f mat3f_mult(mat3f a, mat3f b)
{
return a*b;
}
vec3f mat3f_mult(vec3f a, mat3f b)
{
vec3f ret = vec3f(0,0,0);
int I,J;
for(I=0;I<3;I++)
for(J=0;J<3;J++)
ret[J] += a[I] * b(I,J);
return ret;
}
vec3f mat3f_mult(mat3f a, vec3f b)
{
return a*b;
}
float mat3f_det(mat3f a)
{
return a.det();
}
mat3f mat3f_inverse(mat3f a)
{
return a.inverse();
}
mat3f mat3f_transpose(mat3f a)
{
return a.transpose();
}
};

@ -0,0 +1,615 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
// vec4 constructors
vec4::vec4()
{
x = 0.0;
y = 0.0;
z = 0.0;
w = 0.0;
return;
}
vec4::vec4(double _x, double _y, double _z, double _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
return;
}
vec4::vec4(const vec4 &rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
w = rhs.w;
return;
}
// vec4 assignment and comparison operators
vec4& vec4::operator=(const vec4 &rhs)
{
this->x = rhs.x;
this->y = rhs.y;
this->z = rhs.z;
this->w = rhs.w;
return *this;
}
bool vec4::operator==(vec4 rhs)
{
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z) && (this->w == rhs.w));
}
// vec4 arithmetic operators
vec4 vec4::operator+(vec4 rhs) const
{
vec4 ret;
ret.x = this->x + rhs.x;
ret.y = this->y + rhs.y;
ret.z = this->z + rhs.z;
ret.w = this->w + rhs.w;
return ret;
}
vec4 vec4::operator-(vec4 rhs) const
{
vec4 ret;
ret.x = this->x - rhs.x;
ret.y = this->y - rhs.y;
ret.z = this->z - rhs.z;
ret.w = this->w - rhs.w;
return ret;
}
vec4 vec4::operator*(double rhs) const
{
vec4 ret;
ret.x = this->x*rhs;
ret.y = this->y*rhs;
ret.z = this->z*rhs;
ret.w = this->w*rhs;
return ret;
}
vec4 vec4::operator/(double rhs) const
{
vec4 ret;
ret.x = this->x/rhs;
ret.y = this->y/rhs;
ret.z = this->z/rhs;
ret.w = this->w/rhs;
return ret;
}
vec4 operator-(vec4 rhs)
{
vec4 ret;
ret.x = -rhs.x;
ret.y = -rhs.y;
ret.z = -rhs.z;
ret.w = -rhs.w;
return ret;
}
// vec4 subscript operators
double& vec4::operator[](int ind)
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
else if(ind==3) return w;
return x;
}
const double& vec4::operator[](int ind) const
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
else if(ind==3) return w;
return x;
}
// vector operations (new nomenclature)
double vec4_dot(vec4 v1, vec4 v2)
{
double ret = 0.0;
ret += v1.x*v2.x;
ret += v1.y*v2.y;
ret += v1.z*v2.z;
ret += v1.w*v2.w;
return ret;
}
double vec4_norm(vec4 v)
{
double ret = ::sqrt(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w);
return ret;
}
vec4 vec4_normalize(vec4 v)
{
vec4 ret = vec4(0,0,0,0);
double nrm = vec4_norm(v);
if(nrm>0.0)
{
ret = v/nrm;
}
return ret;
}
double vec4_dist(vec4 v1, vec4 v2)
{
return vec4_norm(v1-v2);
}
vec4 vec4_proj(vec4 v1, vec4 v2)
{
vec4 ret;
vec4 v2n = vec4_normalize(v2);
ret = v2n*vec4_dot(v1,v2n);
return ret;
}
// vector operations (old nomenclature)
double vdot(vec4 v1, vec4 v2)
{
return vec4_dot(v1,v2);
}
double vnorm(vec4 v)
{
return vec4_norm(v);
}
vec4 vnormalize(vec4 v)
{
return vec4_normalize(v);
}
double vdist(vec4 v1, vec4 v2)
{
return vec4_dist(v1,v2);
}
vec4 vproj(vec4 v1, vec4 v2)
{
return vec4_proj(v1,v2);
}
// mat4 constructors
mat4::mat4()
{
int I;
for(I=0;I<16;I++) data[I] = 0.0;
return;
}
mat4::mat4(
double _xx, double _yx, double _zx, double _wx,
double _xy, double _yy, double _zy, double _wy,
double _xz, double _yz, double _zz, double _wz,
double _xw, double _yw, double _zw, double _ww
)
{
data[0] = _xx;
data[1] = _yx;
data[2] = _zx;
data[3] = _wx;
data[4] = _xy;
data[5] = _yy;
data[6] = _zy;
data[7] = _wy;
data[8] = _xz;
data[9] = _yz;
data[10] = _zz;
data[11] = _wz;
data[12] = _xw;
data[13] = _yw;
data[14] = _zw;
data[15] = _ww;
return;
}
mat4::mat4(const double *_data)
{
int I;
for(I=0;I<16;I++) data[I] = _data[I];
return;
}
mat4::mat4(const mat4 &rhs)
{
int I;
for(I=0;I<16;I++) data[I] = rhs.data[I];
return;
}
mat4::mat4(const vec4 _col1, const vec4 _col2, const vec4 _col3, const vec4 _col4)
{
data[0] = _col1[0];
data[1] = _col1[1];
data[2] = _col1[2];
data[3] = _col1[3];
data[4] = _col2[0];
data[5] = _col2[1];
data[6] = _col2[2];
data[7] = _col2[3];
data[8] = _col3[0];
data[9] = _col3[1];
data[10] = _col3[2];
data[11] = _col3[3];
data[12] = _col4[0];
data[13] = _col4[1];
data[14] = _col4[2];
data[15] = _col4[3];
return;
}
// mat4 assignment and comparison operators
mat4& mat4::operator=(const mat4 rhs)
{
int I;
for(I=0;I<16;I++) data[I] = rhs.data[I];
return *this;
}
bool mat4::operator==(const mat4 rhs)
{
bool ret = 1;
int I;
for(I=0;I<16;I++)
{
if(this->data[I]!=rhs.data[I])
{
ret = 0;
break;
}
}
return ret;
}
// mat4 arithmetic operators
mat4 mat4::operator+(mat4 rhs) const
{
mat4 ret;
int I;
for(I=0;I<16;I++)
{
ret.data[I] = this->data[I] + rhs.data[I];
}
return ret;
}
mat4 mat4::operator-(mat4 rhs) const
{
mat4 ret;
int I;
for(I=0;I<16;I++)
{
ret.data[I] = this->data[I] - rhs.data[I];
}
return ret;
}
mat4 mat4::operator*(mat4 rhs) const
{
mat4 ret = mat4_zeros();
int I,J,K;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
for(K=0;K<4;K++)
ret(I,K) += (*this)(I,J)*rhs(J,K);
return ret;
}
mat4 mat4::operator/(mat4 rhs) const
{
mat4 rhsi = rhs.inverse();
return (*this)*rhsi;
}
mat4 mat4::operator*(double rhs) const
{
mat4 ret;
int I;
for(I=0;I<16;I++) ret.data[I] = this->data[I]*rhs;
return ret;
}
mat4 mat4::operator/(double rhs) const
{
mat4 ret;
int I;
for(I=0;I<16;I++) ret.data[I] = this->data[I]/rhs;
return ret;
}
vec4 mat4::operator*(vec4 rhs) const
{
vec4 ret = vec4(0,0,0,0);
int I,J;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
ret[I] += (*this)(I,J)*rhs[J];
return ret;
}
// mat4 access operators
double& mat4::operator()(int I, int J)
{
int ind = I + 4*J;
return data[ind];
}
double& mat4::operator[](int I)
{
return data[I];
}
const double& mat4::operator()(int I, int J) const
{
int ind = I + 4*J;
return data[ind];
}
const double& mat4::operator[](int I) const
{
return data[I];
}
double& mat4::at(int I, int J)
{
int ind = I + 4*J;
return data[ind];
}
const double& mat4::at(int I, int J) const
{
int ind = I + 4*J;
return data[ind];
}
double mat4::det()
{
double ret = 0.0;
double a00,a01,a02,a03;
double a10,a11,a12,a13;
double a20,a21,a22,a23;
double a30,a31,a32,a33;
a00 = this->at(0,0);
a01 = this->at(0,1);
a02 = this->at(0,2);
a03 = this->at(0,3);
a10 = this->at(1,0);
a11 = this->at(1,1);
a12 = this->at(1,2);
a13 = this->at(1,3);
a20 = this->at(2,0);
a21 = this->at(2,1);
a22 = this->at(2,2);
a23 = this->at(2,3);
a30 = this->at(3,0);
a31 = this->at(3,1);
a32 = this->at(3,2);
a33 = this->at(3,3);
ret = a03*a12*a21*a30 -
a02*a13*a21*a30 -
a03*a11*a22*a30 +
a01*a13*a22*a30 +
a02*a11*a23*a30 -
a01*a12*a23*a30 -
a03*a12*a20*a31 +
a02*a13*a20*a31 +
a03*a10*a22*a31 -
a00*a13*a22*a31 -
a02*a10*a23*a31 +
a00*a12*a23*a31 +
a03*a11*a20*a32 -
a01*a13*a20*a32 -
a03*a10*a21*a32 +
a00*a13*a21*a32 +
a01*a10*a23*a32 -
a00*a11*a23*a32 -
a02*a11*a20*a33 +
a01*a12*a20*a33 +
a02*a10*a21*a33 -
a00*a12*a21*a33 -
a01*a10*a22*a33 +
a00*a11*a22*a33;
return ret;
}
mat4 mat4::inverse()
{
mat4 ret = mat4_zeros();
double dt = this->det();
double a00,a01,a02,a03;
double a10,a11,a12,a13;
double a20,a21,a22,a23;
double a30,a31,a32,a33;
double b00,b01,b02,b03;
double b10,b11,b12,b13;
double b20,b21,b22,b23;
double b30,b31,b32,b33;
a00 = this->at(0,0);
a01 = this->at(0,1);
a02 = this->at(0,2);
a03 = this->at(0,3);
a10 = this->at(1,0);
a11 = this->at(1,1);
a12 = this->at(1,2);
a13 = this->at(1,3);
a20 = this->at(2,0);
a21 = this->at(2,1);
a22 = this->at(2,2);
a23 = this->at(2,3);
a30 = this->at(3,0);
a31 = this->at(3,1);
a32 = this->at(3,2);
a33 = this->at(3,3);
if(ams::abs(dt)>vecmat_det_small)
{
b00 = -a13*a22*a31 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 + a11*a22*a33;
b01 = a03*a22*a31 - a02*a23*a31 - a03*a21*a32 + a01*a23*a32 + a02*a21*a33 - a01*a22*a33;
b02 = -a03*a12*a31 + a02*a13*a31 + a03*a11*a32 - a01*a13*a32 - a02*a11*a33 + a01*a12*a33;
b03 = a03*a12*a21 - a02*a13*a21 - a03*a11*a22 + a01*a13*a22 + a02*a11*a23 - a01*a12*a23;
b10 = a13*a22*a30 - a12*a23*a30 - a13*a20*a32 + a10*a23*a32 + a12*a20*a33 - a10*a22*a33;
b11 = -a03*a22*a30 + a02*a23*a30 + a03*a20*a32 - a00*a23*a32 - a02*a20*a33 + a00*a22*a33;
b12 = a03*a12*a30 - a02*a13*a30 - a03*a10*a32 + a00*a13*a32 + a02*a10*a33 - a00*a12*a33;
b13 = -a03*a12*a20 + a02*a13*a20 + a03*a10*a22 - a00*a13*a22 - a02*a10*a23 + a00*a12*a23;
b20 = -a13*a21*a30 + a11*a23*a30 + a13*a20*a31 - a10*a23*a31 - a11*a20*a33 + a10*a21*a33;
b21 = a03*a21*a30 - a01*a23*a30 - a03*a20*a31 + a00*a23*a31 + a01*a20*a33 - a00*a21*a33;
b22 = -a03*a11*a30 + a01*a13*a30 + a03*a10*a31 - a00*a13*a31 - a01*a10*a33 + a00*a11*a33;
b23 = a03*a11*a20 - a01*a13*a20 - a03*a10*a21 + a00*a13*a21 + a01*a10*a23 - a00*a11*a23;
b30 = a12*a21*a30 - a11*a22*a30 - a12*a20*a31 + a10*a22*a31 + a11*a20*a32 - a10*a21*a32;
b31 = -a02*a21*a30 + a01*a22*a30 + a02*a20*a31 - a00*a22*a31 - a01*a20*a32 + a00*a21*a32;
b32 = a02*a11*a30 - a01*a12*a30 - a02*a10*a31 + a00*a12*a31 + a01*a10*a32 - a00*a11*a32;
b33 = -a02*a11*a20 + a01*a12*a20 + a02*a10*a21 - a00*a12*a21 - a01*a10*a22 + a00*a11*a22;
b00 = b00/dt;
b01 = b01/dt;
b02 = b02/dt;
b03 = b03/dt;
b10 = b10/dt;
b11 = b11/dt;
b12 = b12/dt;
b13 = b13/dt;
b20 = b20/dt;
b21 = b21/dt;
b22 = b22/dt;
b23 = b23/dt;
b30 = b30/dt;
b31 = b31/dt;
b32 = b32/dt;
b33 = b33/dt;
ret(0,0) = b00;
ret(0,1) = b01;
ret(0,2) = b02;
ret(0,3) = b03;
ret(1,0) = b10;
ret(1,1) = b11;
ret(1,2) = b12;
ret(1,3) = b13;
ret(2,0) = b20;
ret(2,1) = b21;
ret(2,2) = b22;
ret(2,3) = b23;
ret(3,0) = b30;
ret(3,1) = b31;
ret(3,2) = b32;
ret(3,3) = b33;
}
//this was STUPID. Gaah. Computer algebra system saves the day? I'd be surprised if this didn't end up *slower* than gaussian elimination. Don't do this again!
return ret;
}
void mat4::invert()
{
mat4 m = this->inverse();
*this = m;
}
mat4 mat4::transpose()
{
mat4 ret;
int I,J;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
ret(I,J) = this->at(J,I);
return ret;
}
void mat4::dotranspose()
{
mat4 m = this->transpose();
*this = m;
}
// matrix operations (standalone functions)
mat4 mat4_eye()
{
mat4 ret = mat4_zeros();
ret(0,0) = 1.0;
ret(1,1) = 1.0;
ret(2,2) = 1.0;
ret(3,3) = 1.0;
return ret;
}
mat4 mat4_zeros()
{
mat4 ret;
// for speed - the constructor already sets data[I] to 0.0
// int I;
// for(I=0;I<16;I++) ret.data[I] = 0.0;
return ret;
}
mat4 mat4_ones()
{
mat4 ret;
int I;
for(I=0;I<16;I++) ret.data[I] = 1.0;
return ret;
}
mat4 mat4_mult(mat4 a, mat4 b)
{
return a*b;
}
vec4 mat4_mult(vec4 a, mat4 b)
{
vec4 ret = vec4(0,0,0,0);
int I,J;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
ret[J] += a[I] * b(I,J);
return ret;
}
vec4 mat4_mult(mat4 a, vec4 b)
{
return a*b;
}
double mat4_det(mat4 a)
{
return a.det();
}
mat4 mat4_inverse(mat4 a)
{
return a.inverse();
}
mat4 mat4_transpose(mat4 a)
{
return a.transpose();
}
};

@ -0,0 +1,615 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
// vec4f constructors
vec4f::vec4f()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
w = 0.0f;
return;
}
vec4f::vec4f(float _x, float _y, float _z, float _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
return;
}
vec4f::vec4f(const vec4f &rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
w = rhs.w;
return;
}
// vec4f assignment and comparison operators
vec4f& vec4f::operator=(const vec4f &rhs)
{
this->x = rhs.x;
this->y = rhs.y;
this->z = rhs.z;
this->w = rhs.w;
return *this;
}
bool vec4f::operator==(vec4f rhs)
{
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z) && (this->w == rhs.w));
}
// vec4f arithmetic operators
vec4f vec4f::operator+(vec4f rhs) const
{
vec4f ret;
ret.x = this->x + rhs.x;
ret.y = this->y + rhs.y;
ret.z = this->z + rhs.z;
ret.w = this->w + rhs.w;
return ret;
}
vec4f vec4f::operator-(vec4f rhs) const
{
vec4f ret;
ret.x = this->x - rhs.x;
ret.y = this->y - rhs.y;
ret.z = this->z - rhs.z;
ret.w = this->w - rhs.w;
return ret;
}
vec4f vec4f::operator*(float rhs) const
{
vec4f ret;
ret.x = this->x*rhs;
ret.y = this->y*rhs;
ret.z = this->z*rhs;
ret.w = this->w*rhs;
return ret;
}
vec4f vec4f::operator/(float rhs) const
{
vec4f ret;
ret.x = this->x/rhs;
ret.y = this->y/rhs;
ret.z = this->z/rhs;
ret.w = this->w/rhs;
return ret;
}
vec4f operator-(vec4f rhs)
{
vec4f ret;
ret.x = -rhs.x;
ret.y = -rhs.y;
ret.z = -rhs.z;
ret.w = -rhs.w;
return ret;
}
// vec4f subscript operators
float& vec4f::operator[](int ind)
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
else if(ind==3) return w;
return x;
}
const float& vec4f::operator[](int ind) const
{
if(ind==0) return x;
else if(ind==1) return y;
else if(ind==2) return z;
else if(ind==3) return w;
return x;
}
// vector operations (new nomenclature)
float vec4f_dot(vec4f v1, vec4f v2)
{
float ret = 0.0f;
ret += v1.x*v2.x;
ret += v1.y*v2.y;
ret += v1.z*v2.z;
ret += v1.w*v2.w;
return ret;
}
float vec4f_norm(vec4f v)
{
float ret = ::sqrtf(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w);
return ret;
}
vec4f vec4f_normalize(vec4f v)
{
vec4f ret = vec4f(0,0,0,0);
float nrm = vec4f_norm(v);
if(nrm>0.0)
{
ret = v/nrm;
}
return ret;
}
float vec4f_dist(vec4f v1, vec4f v2)
{
return vec4f_norm(v1-v2);
}
vec4f vec4f_proj(vec4f v1, vec4f v2)
{
vec4f ret;
vec4f v2n = vec4f_normalize(v2);
ret = v2n*vec4f_dot(v1,v2n);
return ret;
}
// vector operations (old nomenclature)
float vdot(vec4f v1, vec4f v2)
{
return vec4f_dot(v1,v2);
}
float vnorm(vec4f v)
{
return vec4f_norm(v);
}
vec4f vnormalize(vec4f v)
{
return vec4f_normalize(v);
}
float vdist(vec4f v1, vec4f v2)
{
return vec4f_dist(v1,v2);
}
vec4f vproj(vec4f v1, vec4f v2)
{
return vec4f_proj(v1,v2);
}
// mat4f constructors
mat4f::mat4f()
{
int I;
for(I=0;I<16;I++) data[I] = 0.0f;
return;
}
mat4f::mat4f(
float _xx, float _yx, float _zx, float _wx,
float _xy, float _yy, float _zy, float _wy,
float _xz, float _yz, float _zz, float _wz,
float _xw, float _yw, float _zw, float _ww
)
{
data[0] = _xx;
data[1] = _yx;
data[2] = _zx;
data[3] = _wx;
data[4] = _xy;
data[5] = _yy;
data[6] = _zy;
data[7] = _wy;
data[8] = _xz;
data[9] = _yz;
data[10] = _zz;
data[11] = _wz;
data[12] = _xw;
data[13] = _yw;
data[14] = _zw;
data[15] = _ww;
return;
}
mat4f::mat4f(const float *_data)
{
int I;
for(I=0;I<16;I++) data[I] = _data[I];
return;
}
mat4f::mat4f(const mat4f &rhs)
{
int I;
for(I=0;I<16;I++) data[I] = rhs.data[I];
return;
}
mat4f::mat4f(const vec4f _col1, const vec4f _col2, const vec4f _col3, const vec4f _col4)
{
data[0] = _col1[0];
data[1] = _col1[1];
data[2] = _col1[2];
data[3] = _col1[3];
data[4] = _col2[0];
data[5] = _col2[1];
data[6] = _col2[2];
data[7] = _col2[3];
data[8] = _col3[0];
data[9] = _col3[1];
data[10] = _col3[2];
data[11] = _col3[3];
data[12] = _col4[0];
data[13] = _col4[1];
data[14] = _col4[2];
data[15] = _col4[3];
return;
}
// mat4f assignment and comparison operators
mat4f& mat4f::operator=(const mat4f rhs)
{
int I;
for(I=0;I<16;I++) data[I] = rhs.data[I];
return *this;
}
bool mat4f::operator==(const mat4f rhs)
{
bool ret = 1;
int I;
for(I=0;I<16;I++)
{
if(this->data[I]!=rhs.data[I])
{
ret = 0;
break;
}
}
return ret;
}
// mat4f arithmetic operators
mat4f mat4f::operator+(mat4f rhs) const
{
mat4f ret;
int I;
for(I=0;I<16;I++)
{
ret.data[I] = this->data[I] + rhs.data[I];
}
return ret;
}
mat4f mat4f::operator-(mat4f rhs) const
{
mat4f ret;
int I;
for(I=0;I<16;I++)
{
ret.data[I] = this->data[I] - rhs.data[I];
}
return ret;
}
mat4f mat4f::operator*(mat4f rhs) const
{
mat4f ret = mat4f_zeros();
int I,J,K;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
for(K=0;K<4;K++)
ret(I,K) += (*this)(I,J)*rhs(J,K);
return ret;
}
mat4f mat4f::operator/(mat4f rhs) const
{
mat4f rhsi = rhs.inverse();
return (*this)*rhsi;
}
mat4f mat4f::operator*(float rhs) const
{
mat4f ret;
int I;
for(I=0;I<16;I++) ret.data[I] = this->data[I]*rhs;
return ret;
}
mat4f mat4f::operator/(float rhs) const
{
mat4f ret;
int I;
for(I=0;I<16;I++) ret.data[I] = this->data[I]/rhs;
return ret;
}
vec4f mat4f::operator*(vec4f rhs) const
{
vec4f ret = vec4f(0,0,0,0);
int I,J;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
ret[I] += (*this)(I,J)*rhs[J];
return ret;
}
// mat4f access operators
float& mat4f::operator()(int I, int J)
{
int ind = I + 4*J;
return data[ind];
}
float& mat4f::operator[](int I)
{
return data[I];
}
const float& mat4f::operator()(int I, int J) const
{
int ind = I + 4*J;
return data[ind];
}
const float& mat4f::operator[](int I) const
{
return data[I];
}
float& mat4f::at(int I, int J)
{
int ind = I + 4*J;
return data[ind];
}
const float& mat4f::at(int I, int J) const
{
int ind = I + 4*J;
return data[ind];
}
float mat4f::det()
{
float ret = 0.0f;
float a00,a01,a02,a03;
float a10,a11,a12,a13;
float a20,a21,a22,a23;
float a30,a31,a32,a33;
a00 = this->at(0,0);
a01 = this->at(0,1);
a02 = this->at(0,2);
a03 = this->at(0,3);
a10 = this->at(1,0);
a11 = this->at(1,1);
a12 = this->at(1,2);
a13 = this->at(1,3);
a20 = this->at(2,0);
a21 = this->at(2,1);
a22 = this->at(2,2);
a23 = this->at(2,3);
a30 = this->at(3,0);
a31 = this->at(3,1);
a32 = this->at(3,2);
a33 = this->at(3,3);
ret = a03*a12*a21*a30 -
a02*a13*a21*a30 -
a03*a11*a22*a30 +
a01*a13*a22*a30 +
a02*a11*a23*a30 -
a01*a12*a23*a30 -
a03*a12*a20*a31 +
a02*a13*a20*a31 +
a03*a10*a22*a31 -
a00*a13*a22*a31 -
a02*a10*a23*a31 +
a00*a12*a23*a31 +
a03*a11*a20*a32 -
a01*a13*a20*a32 -
a03*a10*a21*a32 +
a00*a13*a21*a32 +
a01*a10*a23*a32 -
a00*a11*a23*a32 -
a02*a11*a20*a33 +
a01*a12*a20*a33 +
a02*a10*a21*a33 -
a00*a12*a21*a33 -
a01*a10*a22*a33 +
a00*a11*a22*a33;
return ret;
}
mat4f mat4f::inverse()
{
mat4f ret = mat4f_zeros();
float dt = this->det();
float a00,a01,a02,a03;
float a10,a11,a12,a13;
float a20,a21,a22,a23;
float a30,a31,a32,a33;
float b00,b01,b02,b03;
float b10,b11,b12,b13;
float b20,b21,b22,b23;
float b30,b31,b32,b33;
a00 = this->at(0,0);
a01 = this->at(0,1);
a02 = this->at(0,2);
a03 = this->at(0,3);
a10 = this->at(1,0);
a11 = this->at(1,1);
a12 = this->at(1,2);
a13 = this->at(1,3);
a20 = this->at(2,0);
a21 = this->at(2,1);
a22 = this->at(2,2);
a23 = this->at(2,3);
a30 = this->at(3,0);
a31 = this->at(3,1);
a32 = this->at(3,2);
a33 = this->at(3,3);
if(ams::abs(dt)>vecmat_det_small)
{
b00 = -a13*a22*a31 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 + a11*a22*a33;
b01 = a03*a22*a31 - a02*a23*a31 - a03*a21*a32 + a01*a23*a32 + a02*a21*a33 - a01*a22*a33;
b02 = -a03*a12*a31 + a02*a13*a31 + a03*a11*a32 - a01*a13*a32 - a02*a11*a33 + a01*a12*a33;
b03 = a03*a12*a21 - a02*a13*a21 - a03*a11*a22 + a01*a13*a22 + a02*a11*a23 - a01*a12*a23;
b10 = a13*a22*a30 - a12*a23*a30 - a13*a20*a32 + a10*a23*a32 + a12*a20*a33 - a10*a22*a33;
b11 = -a03*a22*a30 + a02*a23*a30 + a03*a20*a32 - a00*a23*a32 - a02*a20*a33 + a00*a22*a33;
b12 = a03*a12*a30 - a02*a13*a30 - a03*a10*a32 + a00*a13*a32 + a02*a10*a33 - a00*a12*a33;
b13 = -a03*a12*a20 + a02*a13*a20 + a03*a10*a22 - a00*a13*a22 - a02*a10*a23 + a00*a12*a23;
b20 = -a13*a21*a30 + a11*a23*a30 + a13*a20*a31 - a10*a23*a31 - a11*a20*a33 + a10*a21*a33;
b21 = a03*a21*a30 - a01*a23*a30 - a03*a20*a31 + a00*a23*a31 + a01*a20*a33 - a00*a21*a33;
b22 = -a03*a11*a30 + a01*a13*a30 + a03*a10*a31 - a00*a13*a31 - a01*a10*a33 + a00*a11*a33;
b23 = a03*a11*a20 - a01*a13*a20 - a03*a10*a21 + a00*a13*a21 + a01*a10*a23 - a00*a11*a23;
b30 = a12*a21*a30 - a11*a22*a30 - a12*a20*a31 + a10*a22*a31 + a11*a20*a32 - a10*a21*a32;
b31 = -a02*a21*a30 + a01*a22*a30 + a02*a20*a31 - a00*a22*a31 - a01*a20*a32 + a00*a21*a32;
b32 = a02*a11*a30 - a01*a12*a30 - a02*a10*a31 + a00*a12*a31 + a01*a10*a32 - a00*a11*a32;
b33 = -a02*a11*a20 + a01*a12*a20 + a02*a10*a21 - a00*a12*a21 - a01*a10*a22 + a00*a11*a22;
b00 = b00/dt;
b01 = b01/dt;
b02 = b02/dt;
b03 = b03/dt;
b10 = b10/dt;
b11 = b11/dt;
b12 = b12/dt;
b13 = b13/dt;
b20 = b20/dt;
b21 = b21/dt;
b22 = b22/dt;
b23 = b23/dt;
b30 = b30/dt;
b31 = b31/dt;
b32 = b32/dt;
b33 = b33/dt;
ret(0,0) = b00;
ret(0,1) = b01;
ret(0,2) = b02;
ret(0,3) = b03;
ret(1,0) = b10;
ret(1,1) = b11;
ret(1,2) = b12;
ret(1,3) = b13;
ret(2,0) = b20;
ret(2,1) = b21;
ret(2,2) = b22;
ret(2,3) = b23;
ret(3,0) = b30;
ret(3,1) = b31;
ret(3,2) = b32;
ret(3,3) = b33;
}
//this was STUPID. Gaah. Computer algebra system saves the day? I'd be surprised if this didn't end up *slower* than gaussian elimination. Don't do this again!
return ret;
}
void mat4f::invert()
{
mat4f m = this->inverse();
*this = m;
}
mat4f mat4f::transpose()
{
mat4f ret;
int I,J;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
ret(I,J) = this->at(J,I);
return ret;
}
void mat4f::dotranspose()
{
mat4f m = this->transpose();
*this = m;
}
// matrix operations (standalone functions)
mat4f mat4f_eye()
{
mat4f ret = mat4f_zeros();
ret(0,0) = 1.0f;
ret(1,1) = 1.0f;
ret(2,2) = 1.0f;
ret(3,3) = 1.0f;
return ret;
}
mat4f mat4f_zeros()
{
mat4f ret;
// for speed - the constructor already sets data[I] to 0.0
// int I;
// for(I=0;I<16;I++) ret.data[I] = 0.0;
return ret;
}
mat4f mat4f_ones()
{
mat4f ret;
int I;
for(I=0;I<16;I++) ret.data[I] = 1.0f;
return ret;
}
mat4f mat4f_mult(mat4f a, mat4f b)
{
return a*b;
}
vec4f mat4f_mult(vec4f a, mat4f b)
{
vec4f ret = vec4f(0,0,0,0);
int I,J;
for(I=0;I<4;I++)
for(J=0;J<4;J++)
ret[J] += a[I] * b(I,J);
return ret;
}
vec4f mat4f_mult(mat4f a, vec4f b)
{
return a*b;
}
float mat4f_det(mat4f a)
{
return a.det();
}
mat4f mat4f_inverse(mat4f a)
{
return a.inverse();
}
mat4f mat4f_transpose(mat4f a)
{
return a.transpose();
}
};

@ -0,0 +1,414 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
namespace cmp
{
complex::complex()
{
//initcode
r = 0.0;
i = 0.0;
return;
}
complex::complex(double _r, double _i)
{
r = _r; i = _i;
return;
}
complex::complex(double _r)
{
r = _r; i = 0.0;
return;
}
complex::complex(const complex &other)
{
r = other.r;
i = other.i;
return;
}
complex& complex::operator=(const complex& other)
{
r = other.r;
i = other.i;
return *this;
}
complex& complex::operator=(const double other)
{
r = other;
i = 0.0;
return *this;
}
double& complex::operator[](int& ind)
{
if(ind==0)
{
return this->r;
}
else if(ind==1)
{
return this->i;
}
else
{
printf("complex::operator[] index %d out of bounds\n",ind);
exit(0);
}
}
const double& complex::operator[](const int& ind) const
{
if(ind==0)
{
return this->r;
}
else if(ind==1)
{
return this->i;
}
else
{
printf("complex::operator[] index %d out of bounds\n",ind);
exit(0);
}
}
complex complex::operator+(const complex &z)
{
complex cp;
cp.r = r+z.r;
cp.i = i+z.i;
return cp;
}
complex complex::operator-(const complex &z)
{
complex cp;
cp.r = r-z.r;
cp.i = i-z.i;
return cp;
}
complex complex::operator*(const complex &z)
{
complex cp;
cp.r = r * z.r - i * z.i;
cp.i = r * z.i + i * z.r;
return cp;
}
complex complex::operator/(const complex &z)
{
complex cp;
cp.r = (r*z.r+i*z.i)/(z.r*z.r+z.i*z.i);
cp.i = (i*z.r-r*z.i)/(z.r*z.r+z.i*z.i);
return cp;
}
complex complex::operator+(const double &z)
{
complex cp;
cp.r = r + z;
cp.i = i + 0.0;
return cp;
}
complex complex::operator-(const double &z)
{
complex cp;
cp.r = r - z;
cp.i = i - 0.0;
return cp;
}
complex complex::operator*(const double &z)
{
complex cp;
cp.r = r * z;
cp.i = i * z;
return cp;
}
complex complex::operator/(const double &z)
{
complex cp;
cp.r = r/z;
cp.i = i/z;
return cp;
}
complex operator-(const complex &z)
{
complex ret;
ret.r = -z.r;
ret.i = -z.i;
return ret;
}
double complex::arg()
{
double ret = ams::arg(this->r,this->i);
return ret;
}
double complex::mag()
{
return ::sqrt(r*r+i*i);
}
bool complex::iszero()
{
bool ret = 0;
if(r==0.0 && i == 0.0)
{
ret = 1;
}
return ret;
}
bool complex::isreal()
{
bool ret = 0;
// bool ret = 0;
// if(re>DSMALL||re<-DSMALL)
// {
// ret = 0;
// }
// else
// {
// ret = 1;
// }
if(i==0.0)
{
ret = 1;
}
return ret;
}
bool complex::isimag()
{
bool ret = 0;
if(r==0.0)
{
ret = 1;
}
return ret;
}
const complex complex::conj()
{
complex cp;
cp.r = r;
cp.i = -i;
return cp;
}
double real(complex z)
{
return z.r;
}
double imag(complex z)
{
return z.i;
}
complex conj(complex z)
{
complex cp;
cp.r = z.r;
cp.i = -z.i;
return cp;
}
complex exp(complex z)
{
complex ret;
ret.r = ::exp(z.r)*::cos(z.i);
ret.i = ::exp(z.r)*::sin(z.i);
return ret;
}
complex log(complex z)
{
complex ret;
ret.r = ::log(::sqrt(z.r*z.r+z.i*z.i));
ret.i = ams::arg(z.r,z.i);
return ret;
}
complex cos(complex z)
{
complex ret = complex(0.0,0.0);
complex div = complex(2.0,0.0);
complex im1 = complex(0.0,1.0);
ret = (exp(im1*z)+exp(im1*(-z)))/div;
return ret;
}
complex sin(complex z)
{
complex ret = complex(0.0,0.0);
complex div = complex(0.0,2.0);
complex im1 = complex(0.0,1.0);
ret = (exp(im1*z)-exp(im1*(-z)))/div;
return ret;
}
complex cosh(complex z)
{
complex ret = complex(0.0,0.0);
complex div = complex(2.0,0.0);
ret = (exp(z)+exp((-z)))/div;
return ret;
}
complex sinh(complex z)
{
complex ret = complex(0.0,0.0);
complex div = complex(2.0,0.0);
ret = (exp(z)-exp(-z))/div;
return ret;
}
complex tan(complex z)
{
return sin(z)/cos(z);
}
complex tanh(complex z)
{
return sinh(z)/cosh(z);
}
complex pow(complex z1, complex z2)
{
complex ret;
if(z1.mag()>DSMALL)
ret= ams::cmp::exp(z2*ams::cmp::log(z1));
else
ret = 0.0;
return ret;
}
double abs(complex z)
{
return z.mag();
}
double arg(ams::cmp::complex z)
{
return ams::arg(z.r,z.i);
}
//comparison operators
bool complex::operator==(const complex &z)
{
bool ret = 0;
if((z.r == this->r) && (z.i == this->i))
{
ret = 1;
}
return ret;
}
bool complex::operator!=(const complex &z)
{
bool ret = !(*this == z);
return ret;
}
//sort first by real value, then by imaginary value
//this is done so that an ordering exists, as long as two values aren't equal
bool complex::operator>(const complex& z)
{
bool ret = 0;
if(this->r > z.r)
{
ret = 1;
}
else if(this->r == z.r)
{
if(this->i > z.i)
{
ret = 1;
}
}
return ret;
}
bool complex::operator<(const complex& z)
{
bool ret = 0;
ret = !((*this>z) || *this==z);
return ret;
}
bool complex::operator>=(const complex &z)
{
bool ret = 0;
ret = (*this==z) || (*this>z);
return ret;
}
bool complex::operator<=(const complex &z)
{
bool ret = 0;
ret = (*this<z) || (*this==z);
return ret;
}
bool complex::isnan()
{
bool ret = 0;
if(ams::isnan(this->r) || ams::isnan(this->i))
{
ret = 1;
}
return ret;
}
bool complex::isinf()
{
bool ret = 0;
//calls math.h isinf()
if(::isinf(this->r) || ::isinf(this->i))
{
ret = 1;
}
return ret;
}
complex csgn(complex z)
{
double a;
complex ret = ams::cmp::complex(0,0);
if(z.r==0.0 && z.i==0.0)
{
//do nothing
}
else
{
a = ams::cmp::arg(z);
ret.r = ::cos(a);
ret.i = ::sin(a);
}
return ret;
}
};//end namespace cmp
};//end namespace ams

@ -0,0 +1,414 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
namespace cmp
{
complex64::complex64()
{
//initcode
r = 0.0;
i = 0.0;
return;
}
complex64::complex64(float _r, float _i)
{
r = _r; i = _i;
return;
}
complex64::complex64(float _r)
{
r = _r; i = 0.0;
return;
}
complex64::complex64(const complex64 &other)
{
r = other.r;
i = other.i;
return;
}
complex64& complex64::operator=(const complex64& other)
{
r = other.r;
i = other.i;
return *this;
}
complex64& complex64::operator=(const float other)
{
r = other;
i = 0.0;
return *this;
}
float& complex64::operator[](int& ind)
{
if(ind==0)
{
return this->r;
}
else if(ind==1)
{
return this->i;
}
else
{
printf("complex64::operator[] index %d out of bounds\n",ind);
exit(0);
}
}
const float& complex64::operator[](const int& ind) const
{
if(ind==0)
{
return this->r;
}
else if(ind==1)
{
return this->i;
}
else
{
printf("complex64::operator[] index %d out of bounds\n",ind);
exit(0);
}
}
complex64 complex64::operator+(const complex64 &z)
{
complex64 cp;
cp.r = r+z.r;
cp.i = i+z.i;
return cp;
}
complex64 complex64::operator-(const complex64 &z)
{
complex64 cp;
cp.r = r-z.r;
cp.i = i-z.i;
return cp;
}
complex64 complex64::operator*(const complex64 &z)
{
complex64 cp;
cp.r = r * z.r - i * z.i;
cp.i = r * z.i + i * z.r;
return cp;
}
complex64 complex64::operator/(const complex64 &z)
{
complex64 cp;
cp.r = (r*z.r+i*z.i)/(z.r*z.r+z.i*z.i);
cp.i = (i*z.r-r*z.i)/(z.r*z.r+z.i*z.i);
return cp;
}
complex64 complex64::operator+(const float &z)
{
complex64 cp;
cp.r = r + z;
cp.i = i + 0.0;
return cp;
}
complex64 complex64::operator-(const float &z)
{
complex64 cp;
cp.r = r - z;
cp.i = i - 0.0;
return cp;
}
complex64 complex64::operator*(const float &z)
{
complex64 cp;
cp.r = r * z;
cp.i = i * z;
return cp;
}
complex64 complex64::operator/(const float &z)
{
complex64 cp;
cp.r = r/z;
cp.i = i/z;
return cp;
}
complex64 operator-(const complex64 &z)
{
complex64 ret;
ret.r = -z.r;
ret.i = -z.i;
return ret;
}
float complex64::arg()
{
float ret = ams::arg(this->r,this->i);
return ret;
}
float complex64::mag()
{
return ::sqrtf(r*r+i*i);
}
bool complex64::iszero()
{
bool ret = 0;
if(r==0.0 && i == 0.0)
{
ret = 1;
}
return ret;
}
bool complex64::isreal()
{
bool ret = 0;
// bool ret = 0;
// if(re>DSMALL||re<-DSMALL)
// {
// ret = 0;
// }
// else
// {
// ret = 1;
// }
if(i==0.0)
{
ret = 1;
}
return ret;
}
bool complex64::isimag()
{
bool ret = 0;
if(r==0.0)
{
ret = 1;
}
return ret;
}
const complex64 complex64::conj()
{
complex64 cp;
cp.r = r;
cp.i = -i;
return cp;
}
float real(complex64 z)
{
return z.r;
}
float imag(complex64 z)
{
return z.i;
}
complex64 conj(complex64 z)
{
complex64 cp;
cp.r = z.r;
cp.i = -z.i;
return cp;
}
complex64 exp(complex64 z)
{
complex64 ret;
ret.r = ::expf(z.r)*::cos(z.i);
ret.i = ::expf(z.r)*::sin(z.i);
return ret;
}
complex64 log(complex64 z)
{
complex64 ret;
ret.r = ::log(::sqrtf(z.r*z.r+z.i*z.i));
ret.i = ams::arg(z.r,z.i);
return ret;
}
complex64 cos(complex64 z)
{
complex64 ret = complex64(0.0,0.0);
complex64 div = complex64(2.0,0.0);
complex64 im1 = complex64(0.0,1.0);
ret = (exp(im1*z)+exp(im1*(-z)))/div;
return ret;
}
complex64 sin(complex64 z)
{
complex64 ret = complex64(0.0,0.0);
complex64 div = complex64(0.0,2.0);
complex64 im1 = complex64(0.0,1.0);
ret = (exp(im1*z)-exp(im1*(-z)))/div;
return ret;
}
complex64 cosh(complex64 z)
{
complex64 ret = complex64(0.0,0.0);
complex64 div = complex64(2.0,0.0);
ret = (exp(z)+exp((-z)))/div;
return ret;
}
complex64 sinh(complex64 z)
{
complex64 ret = complex64(0.0,0.0);
complex64 div = complex64(2.0,0.0);
ret = (exp(z)-exp(-z))/div;
return ret;
}
complex64 tan(complex64 z)
{
return sin(z)/cos(z);
}
complex64 tanh(complex64 z)
{
return sinh(z)/cosh(z);
}
complex64 pow(complex64 z1, complex64 z2)
{
complex64 ret;
if(z1.mag()>DSMALL)
ret= ams::cmp::exp(z2*ams::cmp::log(z1));
else
ret = 0.0;
return ret;
}
float abs(complex64 z)
{
return z.mag();
}
float arg(ams::cmp::complex64 z)
{
return ams::arg(z.r,z.i);
}
//comparison operators
bool complex64::operator==(const complex64 &z)
{
bool ret = 0;
if((z.r == this->r) && (z.i == this->i))
{
ret = 1;
}
return ret;
}
bool complex64::operator!=(const complex64 &z)
{
bool ret = !(*this == z);
return ret;
}
//sort first by real value, then by imaginary value
//this is done so that an ordering exists, as long as two values aren't equal
bool complex64::operator>(const complex64& z)
{
bool ret = 0;
if(this->r > z.r)
{
ret = 1;
}
else if(this->r == z.r)
{
if(this->i > z.i)
{
ret = 1;
}
}
return ret;
}
bool complex64::operator<(const complex64& z)
{
bool ret = 0;
ret = !((*this>z) || *this==z);
return ret;
}
bool complex64::operator>=(const complex64 &z)
{
bool ret = 0;
ret = (*this==z) || (*this>z);
return ret;
}
bool complex64::operator<=(const complex64 &z)
{
bool ret = 0;
ret = (*this<z) || (*this==z);
return ret;
}
bool complex64::isnan()
{
bool ret = 0;
if(ams::isnan(this->r) || ams::isnan(this->i))
{
ret = 1;
}
return ret;
}
bool complex64::isinf()
{
bool ret = 0;
//calls math.h isinf()
if(::isinf(this->r) || ::isinf(this->i))
{
ret = 1;
}
return ret;
}
complex64 csgn(complex64 z)
{
float a;
complex64 ret = ams::cmp::complex64(0,0);
if(z.r==0.0 && z.i==0.0)
{
//do nothing
}
else
{
a = ams::cmp::arg(z);
ret.r = ::cos(a);
ret.i = ::sin(a);
}
return ret;
}
};//end namespace cmp
};//end namespace ams

@ -0,0 +1,29 @@
#include <amsmathutil25/amsmathutil25.hpp>
namespace ams
{
namespace rand
{
amsmu_randt1 dpr32_rseed;
amsmu_randt2 dpr64_rseed;
amsmu_randt1 dpr32_nextseed(amsmu_randt1 seed)
{
amsmu_randt1 sret = seed;
sret = ams::mod(sret*dpr32_mult1+dpr32_add1,dpr32_mod);
return sret;
}
amsmu_randt2 dpr64_nextseed(amsmu_randt2 seed)
{
amsmu_randt2 sret = seed;
sret = ams::mod(sret*dpr64_mult1+dpr64_add1,dpr64_mod);
return sret;
}
};
};

@ -92,5 +92,7 @@ void test_amsarray2()
}
}; //end namespace amsmathutil25
}; //end namespace ams

@ -79,6 +79,10 @@ template<> void amsarray<double>::print(bool newline,int printstyle)
return;
}
// Explicit Class Instantiations?
template class amsarray<int>;
template class amsarray<float>;
template class amsarray<int64_t>;
template class amsarray<double>;
};

@ -59,4 +59,13 @@ amsarray<amsarray_size_t> permutation_identity(amsarray_size_t _length)
return ret;
}
void amsarray_permutation_swap(amsarray<amsarray_size_t> *permutation, amsarray_size_t I, amsarray_size_t J)
{
amsarray_size_t tmp;
tmp = permutation->data[I];
permutation->data[J] = permutation->data[I];
permutation->data[I] = tmp;
return;
}
};
Loading…
Cancel
Save