/* The quaternion structure: 4 doubles, one for time, xyz for space */ typedef struct q { double T, X, Y, Z; }Q; /* functions */ /* For initialization, replacements, copying */ Q* constructQ(double T, double X, double Y, double Z); void replaceQ(double T, double X, double Y, double Z, Q *Q1); Q* qcopy(Q *Q1); void rqcopy(Q *Q1, Q *Q2); /* Unary functions */ double dtau2(Q *Q1); double dabs(Q *Q1); double dabs_vector(Q *Q1); double dnorm(Q *Q1); double dnorm_vector(Q *Q1); double ddet(Q *Q1); /* Unary functions inverses */ double dtau2_inv(Q *Q1); double dabs_inv(Q *Q1); double dabs_vector_inv(Q *Q1); double dnorm_inv(Q *Q1); double dnorm_vector_inv(Q *Q1); double ddet_inv(Q *Q1); /* Unary functions */ Q* qscalar(Q *Q1); Q* qvector(Q *Q1); Q* qconj(Q *Q1); Q* qinv(Q *Q1); Q* qadj(Q *Q1); Q* qunit(Q *Q1); void rqscalar(Q *Q1, Q *Q2); void rqvector(Q *Q1, Q *Q2); void rqconj(Q *Q1, Q *Q2); void rqinv(Q *Q1, Q *Q2); void rqadj(Q *Q1, Q *Q2); void rqunit(Q *Q1, Q *Q2); /* unary trig */ Q* qsin(Q *Q1); Q* qcos(Q *Q1); Q* qtan(Q *Q1); Q* qsinh(Q *Q1); Q* qcosh(Q *Q1); Q* qtanh(Q *Q1); void rqsin(Q *Q1, Q *Q2); void rqcos(Q *Q1, Q *Q2); void rqtan(Q *Q1, Q *Q2); void rqsinh(Q *Q1, Q *Q2); void rqcosh(Q *Q1, Q *Q2); void rqtanh(Q *Q1, Q *Q2); /* unary hyperbolic trig */ Q* qasin(Q *Q1); Q* qacos(Q *Q1); Q* qatan(Q *Q1); Q* qasinh(Q *Q1); Q* qacosh(Q *Q1); Q* qatanh(Q *Q1); void rqasin(Q *Q1, Q *Q2); void rqacos(Q *Q1, Q *Q2); void rqatan(Q *Q1, Q *Q2); void rqasinh(Q *Q1, Q *Q2); void rqacosh(Q *Q1, Q *Q2); void rqatanh(Q *Q1, Q *Q2); /* Exponentials, powers and logs */ Q* qexp(Q *Q1); Q* qtotheN(Q *Q1, double D); Q* qtotheQ(Q *Q1, Q *Q2); Q* qln(Q *Q1); Q* qlog(Q *Q1); void rqexp(Q *Q1, Q *Q2); void rqtotheN(Q *Q1, double D, Q *Q2); void rqtotheQ(Q *Q1, Q *Q2, Q *Q3); void rqln(Q *Q1, Q *Q2); void rqlog(Q *Q1, Q *Q2); /* addition and subtraction */ Q* qsum(Q *Q1, Q *Q2); Q* qdif(Q *Q1, Q *Q2); void rqsum(Q *Q1, Q *Q2, Q *Q3); void rqdif(Q *Q1, Q *Q2, Q *Q3); /* multiplication */ Q* qxs(Q *Q1, double s); Q* qx(Q *Q1, Q *Q2); Q* qxinv(Q *Q1, Q *Q2); Q* qinvx(Q *Q1, Q *Q2); Q* qxeven(Q *Q1, Q *Q2); Q* qxodd(Q *Q1, Q *Q2); Q* qcx(Q *Q1, Q *Q2); Q* qcxeven(Q *Q1, Q *Q2); Q* qcxodd(Q *Q1, Q *Q2); Q* qxc(Q *Q1, Q *Q2); Q* qxceven(Q *Q1, Q *Q2); Q* qxcodd(Q *Q1, Q *Q2); void rqxs(Q *Q1, double s, Q *Q2); void rqx(Q *Q1, Q *Q2, Q *Q3); void rqxinv(Q *Q1, Q *Q2, Q *Q3); void rqinvx(Q *Q1, Q *Q2, Q *Q3); void rqxeven(Q *Q1, Q *Q2, Q *Q3); void rqxodd(Q *Q1, Q *Q2, Q *Q3); void rqcx(Q *Q1, Q *Q2, Q *Q3); void rqcxeven(Q *Q1, Q *Q2, Q *Q3); void rqcxodd(Q *Q1, Q *Q2, Q *Q3); void rqxc(Q *Q1, Q *Q2, Q *Q3); void rqxceven(Q *Q1, Q *Q2, Q *Q3); void rqxcodd(Q *Q1, Q *Q2, Q *Q3); /* rotations */ Q* qrot_x_by_angle(Q *Q1, double D1); Q* qrot_y_by_angle(Q *Q1, double D1); Q* qrot_z_by_angle(Q *Q1, double D1); Q* qrot_xyz_by_angle(Q *Q1, double DX, double DY, double DZ, double D1); Q* q3D_rotation(Q *Q1, Q *Q2); Q* qcxq(Q *Q1, Q *Q2); void rqrot_x_by_angle(Q *Q1, double D1, Q *Q2); void rqrot_y_by_angle(Q *Q1, double D1, Q *Q2); void rqrot_z_by_angle(Q *Q1, double D1, Q *Q2); void rqrot_xyz_by_angle(Q *Q1, double DX, double DY, double DZ, double D1, Q *Q2); void rq3D_rotation(Q *Q1, Q *Q2, Q *Q3); void rqcxq(Q *Q1, Q *Q2, Q *Q3); /* Printing functions */ void printq(Q *Q1);