// Generated on 2007-08-08 10:15:12 by G2 0.1 from 'E:\gasandbox\ga_sandbox\libgasandbox\e2ga.gs2'
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <string.h>
#include "e2ga.h"
// pre_cpp_include
namespace e2ga {
// The dimension of the space:
const int mv_spaceDim = 2;
// Is the metric of the space Euclidean?
const bool mv_metricEuclidean = true;
// This array can be used to lookup the number of coordinates for a grade part of a general multivector
const int mv_gradeSize[3] = {
1, 2, 1
};
// This array can be used to lookup the number of coordinates based on a grade usage bitmap
const int mv_size[8] = {
0, 1, 2, 3, 1, 2, 3, 4
};
// This array of ASCIIZ strings contains the names of the basis vectors
const char *mv_basisVectorNames[2] = {
"e1", "e2"
};
// This array of integers contains the order of basis elements in the general multivector
const int mv_basisElements[4][3] = {
{-1}
, {0, -1}
, {1, -1}
, {0, 1, -1}
};
// This array of integers contains the 'sign' (even/odd permutation of the canonical order) of basis elements in the general multivector
// Use it to answer 'what is the permutation of the coordinate at index [x]'?
const double mv_basisElementSignByIndex[4] = {
1.0, 1.0, 1.0, 1.0
};
// This array of integers contains the 'sign' (even/odd permutation of canonical order) of basis elements in the general multivector
// Use it to answer 'what is the permutation of the coordinate of bitmap [x]'?
const double mv_basisElementSignByBitmap[4] = {
1.0, 1.0, 1.0, 1.0
};
// This array of integers contains the order of basis elements in the general multivector
// Use it to answer: 'at what index do I find basis element [x] (x = basis vector bitmap)?
const int mv_basisElementIndexByBitmap[4] = {
0, 1, 2, 3
};
// This array of integers contains the indices of basis elements in the general multivector
// Use it to answer: 'what basis element do I find at index [x]'?
const int mv_basisElementBitmapByIndex[4] = {
0, 1, 2, 3
};
// This array of grade of each basis elements in the general multivector
// Use it to answer: 'what is the grade of basis element bitmap [x]'?
extern const int mv_basisElementGradeByBitmap[4] = {
0, 1, 1, 2
};
// These strings determine how the output of string() is formatted.
// You can alter them at runtime using mv_setStringFormat().
const char *mv_string_fp = "%2.2f";
const char *mv_string_start = "";
const char *mv_string_end = "";
const char *mv_string_mul = "*";
const char *mv_string_wedge = "^";
const char *mv_string_plus = " + ";
const char *mv_string_minus = " - ";
void mv_setStringFormat(const char *what, const char *format) {
if (!strcmp(what, "fp"))
mv_string_fp = (format) ? format : "%2.2f";
else if (!strcmp(what, "start"))
mv_string_start = (format) ? format : "";
else if (!strcmp(what, "end"))
mv_string_end = (format) ? format : "";
else if (!strcmp(what, "mul"))
mv_string_mul = (format) ? format : "*";
else if (!strcmp(what, "wedge"))
mv_string_wedge = (format) ? format : "^";
else if (!strcmp(what, "plus"))
mv_string_plus = (format) ? format : " + ";
else if (!strcmp(what, "minus"))
mv_string_minus = (format) ? format : " - "; else {
char msg[1024];
sprintf(msg, "invalid argument to mv_setStringFormat(): %s", what);
mv_throw_exception(msg, MV_EXCEPTION_WARNING);
}
}
namespace g2Profiling {
// Just a bunch of dummy functions:
// Profiling is disabled, but having these functions around
// simplifies a lot.
void profile(unsigned int funcIdx, unsigned short storageTypeIdx, unsigned short nbArg, unsigned short argType[]) {
}
void reset() {
}
void save(const char *filename /*= "E:\\gasandbox\\ga_sandbox\\libgasandbox\\e2ga.gp2"*/, bool append /*= false*/) {
}
void init(const char *filename /*= "E:\\gasandbox\\ga_sandbox\\libgasandbox\\e2ga.gp2"*/,
const char *hostName /*= "localhost"*/, int port /*= 7693*/) {
}
} // end of namespace g2Profiling
// todo: for all storage formats, generate constants
// set to 0
void mv::set() {
// set grade usage
gu(0);
}
// set to copy
void mv::set(const mv &arg1) {
// copy grade usage
gu(arg1.gu());
// copy coordinates
mv_memcpy(m_c, arg1.m_c, mv_size[gu()]);
}
// set to scalar
void mv::set(Float scalarVal) {
// set grade usage
gu(1);
// set type (if profile)
// set coordinate
m_c[0] = scalarVal;
}
// set to coordinates
void mv::set(unsigned int gradeUsage, const Float *coordinates) {
// set grade usage
gu(gradeUsage);
// set coordinates
mv_memcpy(m_c, coordinates, mv_size[gu()]);
}
// set to 1 coordinates
void mv::set(unsigned int gradeUsage, Float c0 ) {
// set grade usage
gu(gradeUsage);
// check the number of coordinates
if (mv_size[gu()] != 1)
throw (-1); // todo: more sensible exception
// set coordinates
m_c[0] = c0;
}
// set to 2 coordinates
void mv::set(unsigned int gradeUsage, Float c0, Float c1 ) {
// set grade usage
gu(gradeUsage);
// check the number of coordinates
if (mv_size[gu()] != 2)
throw (-1); // todo: more sensible exception
// set coordinates
m_c[0] = c0;
m_c[1] = c1;
}
// set to 3 coordinates
void mv::set(unsigned int gradeUsage, Float c0, Float c1, Float c2 ) {
// set grade usage
gu(gradeUsage);
// check the number of coordinates
if (mv_size[gu()] != 3)
throw (-1); // todo: more sensible exception
// set coordinates
m_c[0] = c0;
m_c[1] = c1;
m_c[2] = c2;
}
// set to 4 coordinates
void mv::set(unsigned int gradeUsage, Float c0, Float c1, Float c2, Float c3 ) {
// set grade usage
gu(gradeUsage);
// check the number of coordinates
if (mv_size[gu()] != 4)
throw (-1); // todo: more sensible exception
// set coordinates
m_c[0] = c0;
m_c[1] = c1;
m_c[2] = c2;
m_c[3] = c3;
}
// set to e1_t
void mv::set(const e1_t & arg1) {
// set grade usage
gu(2);
m_c[0] = arg1.m_c[0] ;
m_c[1] = (Float)0;
}
// set to e2_t
void mv::set(const e2_t & arg1) {
// set grade usage
gu(2);
m_c[0] = (Float)0;
m_c[1] = arg1.m_c[0] ;
}
// set to scalar
void mv::set(const scalar & arg1) {
// set grade usage
gu(1);
m_c[0] = arg1.m_c[0] ;
}
// set to vector
void mv::set(const vector & arg1) {
// set grade usage
gu(2);
m_c[0] = arg1.m_c[0] ;
m_c[1] = arg1.m_c[1] ;
}
// set to bivector
void mv::set(const bivector & arg1) {
// set grade usage
gu(4);
m_c[0] = arg1.m_c[0] ;
}
// set to rotor
void mv::set(const rotor & arg1) {
// set grade usage
gu(5);
m_c[0] = arg1.m_c[0] ;
m_c[1] = arg1.m_c[1] ;
}
// set to __e1_ct__
void mv::set(const __e1_ct__ & arg1) {
// set grade usage
gu(2);
m_c[0] = (Float)1.0f;
m_c[1] = (Float)0;
}
// set to __e2_ct__
void mv::set(const __e2_ct__ & arg1) {
// set grade usage
gu(2);
m_c[0] = (Float)0;
m_c[1] = (Float)1.0f;
}
// set to __I2_ct__
void mv::set(const __I2_ct__ & arg1) {
// set grade usage
gu(4);
m_c[0] = (Float)1.0f;
}
// set to __I2i_ct__
void mv::set(const __I2i_ct__ & arg1) {
// set grade usage
gu(4);
m_c[0] = (Float)-1.0f;
}
// assign copy
mv& mv::operator=(const mv &arg1) {
set(arg1);
return *this;
}
// assign scalar
mv& mv::operator=(Float s) {
set(s);
return *this;
}
// assign e1_t
mv& mv::operator=(const e1_t& arg1) {
set(arg1);
return *this;
}
// assign e2_t
mv& mv::operator=(const e2_t& arg1) {
set(arg1);
return *this;
}
// assign scalar
mv& mv::operator=(const scalar& arg1) {
set(arg1);
return *this;
}
// assign vector
mv& mv::operator=(const vector& arg1) {
set(arg1);
return *this;
}
// assign bivector
mv& mv::operator=(const bivector& arg1) {
set(arg1);
return *this;
}
// assign rotor
mv& mv::operator=(const rotor& arg1) {
set(arg1);
return *this;
}
// assign __e1_ct__
mv& mv::operator=(const __e1_ct__& arg1) {
set(arg1);
return *this;
}
// assign __e2_ct__
mv& mv::operator=(const __e2_ct__& arg1) {
set(arg1);
return *this;
}
// assign __I2_ct__
mv& mv::operator=(const __I2_ct__& arg1) {
set(arg1);
return *this;
}
// assign __I2i_ct__
mv& mv::operator=(const __I2i_ct__& arg1) {
set(arg1);
return *this;
}
float mv::largestCoordinate() const {
int nc = mv_size[gu()], i;
Float maxC = -1.0, C;
for (i = 0; i < nc; i++) {
C = (m_c[i] < (Float)0.0) ? -m_c[i] : m_c[i];
if (C > maxC) maxC = C;
}
return maxC;
}
float mv::largestBasisBlade(unsigned int &bm) const {
int nc = mv_size[gu()];
Float maxC = -1.0, C;
int idx = 0;
int grade = 0;
int i = 0;
while (i < nc) {
if (gu() & (1 << grade)) {
for (int j = 0; j < mv_gradeSize[grade]; j++) {
C = (m_c[i] < (Float)0.0) ? -m_c[i] : m_c[i];
if (C > maxC) {
maxC = C;
bm = mv_basisElementBitmapByIndex[idx];
}
idx++;
i++;
}
}
else idx += mv_gradeSize[grade];
grade++;
}
return maxC;
}
// set to mv
void e1_t::set(const mv & arg1) {
int gidx = 0;
if (arg1.gu() & 1) {
gidx += 1; }
else {
}
if (arg1.gu() & 2) {
m_c[0] = arg1.m_c[gidx + 0];
}
else {
m_c[0] = (Float)0.0;
}
}
float e1_t::largestCoordinate() const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
return maxC;
}
float e1_t::largestBasisBlade(unsigned int &bm) const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
bm = 1;
return maxC;
}
// set to mv
void e2_t::set(const mv & arg1) {
int gidx = 0;
if (arg1.gu() & 1) {
gidx += 1; }
else {
}
if (arg1.gu() & 2) {
m_c[0] = arg1.m_c[gidx + 1];
}
else {
m_c[0] = (Float)0.0;
}
}
float e2_t::largestCoordinate() const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
return maxC;
}
float e2_t::largestBasisBlade(unsigned int &bm) const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
bm = 2;
return maxC;
}
// set to mv
void scalar::set(const mv & arg1) {
if (arg1.gu() & 1) {
m_c[0] = arg1.m_c[0];
}
else {
m_c[0] = (Float)0.0;
}
}
float scalar::largestCoordinate() const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
return maxC;
}
float scalar::largestBasisBlade(unsigned int &bm) const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
bm = 0;
return maxC;
}
// set to mv
void vector::set(const mv & arg1) {
int gidx = 0;
if (arg1.gu() & 1) {
gidx += 1; }
else {
}
if (arg1.gu() & 2) {
m_c[0] = arg1.m_c[gidx + 0];
m_c[1] = arg1.m_c[gidx + 1];
}
else {
m_c[0] = (Float)0.0;
m_c[1] = (Float)0.0;
}
}
float vector::largestCoordinate() const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0], C;
C = (m_c[1] < (Float)0.0) ? -m_c[1] : m_c[1];
if (C > maxC) maxC = C;
return maxC;
}
float vector::largestBasisBlade(unsigned int &bm) const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0], C;
bm = 1;
C = (m_c[1] < (Float)0.0) ? -m_c[1] : m_c[1];
if (C > maxC) {
maxC = C;
bm = 2;
}
return maxC;
}
// set to mv
void bivector::set(const mv & arg1) {
int gidx = 0;
if (arg1.gu() & 1) {
gidx += 1; }
else {
}
if (arg1.gu() & 2) {
gidx += 2; }
else {
}
if (arg1.gu() & 4) {
m_c[0] = arg1.m_c[gidx + 0];
}
else {
m_c[0] = (Float)0.0;
}
}
float bivector::largestCoordinate() const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
return maxC;
}
float bivector::largestBasisBlade(unsigned int &bm) const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0];
bm = 3;
return maxC;
}
// set to mv
void rotor::set(const mv & arg1) {
int gidx = 0;
if (arg1.gu() & 1) {
m_c[0] = arg1.m_c[gidx + 0];
gidx += 1; }
else {
m_c[0] = (Float)0.0;
}
if (arg1.gu() & 2) {
gidx += 2; }
else {
}
if (arg1.gu() & 4) {
m_c[1] = arg1.m_c[gidx + 0];
}
else {
m_c[1] = (Float)0.0;
}
}
float rotor::largestCoordinate() const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0], C;
C = (m_c[1] < (Float)0.0) ? -m_c[1] : m_c[1];
if (C > maxC) maxC = C;
return maxC;
}
float rotor::largestBasisBlade(unsigned int &bm) const {
Float maxC = (m_c[0] < (Float)0.0) ? -m_c[0] : m_c[0], C;
bm = 0;
C = (m_c[1] < (Float)0.0) ? -m_c[1] : m_c[1];
if (C > maxC) {
maxC = C;
bm = 3;
}
return maxC;
}
// set to mv
void __e1_ct__::set(const mv & arg1) {
}
float __e1_ct__::largestCoordinate() const {
Float maxC = (Float)1.0f;
return maxC;
}
float __e1_ct__::largestBasisBlade(unsigned int &bm) const {
Float maxC = (Float)1.0f;
bm = 1;
return maxC;
}
// set to mv
void __e2_ct__::set(const mv & arg1) {
}
float __e2_ct__::largestCoordinate() const {
Float maxC = (Float)1.0f;
return maxC;
}
float __e2_ct__::largestBasisBlade(unsigned int &bm) const {
Float maxC = (Float)1.0f;
bm = 2;
return maxC;
}
// set to mv
void __I2_ct__::set(const mv & arg1) {
}
float __I2_ct__::largestCoordinate() const {
Float maxC = (Float)1.0f;
return maxC;
}
float __I2_ct__::largestBasisBlade(unsigned int &bm) const {
Float maxC = (Float)1.0f;
bm = 3;
return maxC;
}
// set to mv
void __I2i_ct__::set(const mv & arg1) {
}
float __I2i_ct__::largestCoordinate() const {
Float maxC = (Float)1.0f;
return maxC;
}
float __I2i_ct__::largestBasisBlade(unsigned int &bm) const {
Float maxC = (Float)1.0f;
bm = 3;
return maxC;
}
// set to identity 'I'
void om::set() {
// simplify forward call to set(scalar)
set(1.0);
}
// set to copy
void om::set(const om &arg1) {
mv_memcpy(m_c, arg1.m_c, 5);
}
// set to scalar
void om::set(Float scalarVal) {
e2ga::__G2_GENERATED__::set(*this, vector(vector_e1_e2, scalarVal, (Float)0), vector(vector_e1_e2, (Float)0, scalarVal));
}
// set to coordinates
void om::set(const Float *coordinates) {
mv_memcpy(m_c, coordinates, 5);
}
// set from basis vectors array
void om::set(const vector *vectors) {
e2ga::__G2_GENERATED__::set(*this, vectors[0], vectors[1]);
}
// set from basis vectors
void om::set(const vector & image_of_e1, const vector & image_of_e2) {
e2ga::__G2_GENERATED__::set(*this, image_of_e1, image_of_e2);
}
// set by coordinates, transpose
void om::set(const Float *coordinates, bool transpose) {
if (transpose) {
m_c[0] = coordinates[0];
m_c[2] = coordinates[1];
m_c[1] = coordinates[2];
m_c[3] = coordinates[3];
m_c[4] = coordinates[4];
}
else set(coordinates);
}
// assign copy
om &om::operator=(const om &arg1) {
set(arg1);
return *this;
}
// assign scalar (creates scalar * 'I' outermorphism)
om &om::operator=(Float scalarVal) {
set(scalarVal);
return *this;
}
/// assign specialization:
// G2 functions:
mv lcont(const mv& x, const mv& y) {
mv __temp_var_1__;
float __tmp_coord_array_1__[4] ;
mv_zero(__tmp_coord_array_1__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
if (((y.m_gu & 1) != 0)) {
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_1__[0] += (__x_xpd__[0][0] * __y_xpd__[0][0]);
}
}
if (((y.m_gu & 2) != 0)) {
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_1__[1] += (__y_xpd__[1][0] * __x_xpd__[0][0]);
__tmp_coord_array_1__[2] += (__y_xpd__[1][1] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_1__[0] += ((__x_xpd__[1][0] * __y_xpd__[1][0]) + (__x_xpd__[1][1] * __y_xpd__[1][1]));
}
}
if (((y.m_gu & 4) != 0)) {
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_1__[3] += (__y_xpd__[2][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_1__[1] += (-1.0f * __x_xpd__[1][1] * __y_xpd__[2][0]);
__tmp_coord_array_1__[2] += (__x_xpd__[1][0] * __y_xpd__[2][0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_1__[0] += (-1.0f * __x_xpd__[2][0] * __y_xpd__[2][0]);
}
}
__temp_var_1__ = mv_compress(__tmp_coord_array_1__);
return __temp_var_1__;
}
scalar scp(const mv& x, const mv& y) {
scalar __temp_var_1__;
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((y.m_gu & 1) != 0)) {
if (((x.m_gu & 1) != 0)) {
__temp_var_1__.m_c[0] += (__x_xpd__[0][0] * __y_xpd__[0][0]);
}
}
if (((y.m_gu & 2) != 0)) {
if (((x.m_gu & 2) != 0)) {
__temp_var_1__.m_c[0] += ((__x_xpd__[1][0] * __y_xpd__[1][0]) + (__x_xpd__[1][1] * __y_xpd__[1][1]));
}
}
if (((y.m_gu & 4) != 0)) {
if (((x.m_gu & 4) != 0)) {
__temp_var_1__.m_c[0] += (-1.0f * __x_xpd__[2][0] * __y_xpd__[2][0]);
}
}
return __temp_var_1__;
}
mv gp(const mv& x, const mv& y) {
mv __temp_var_1__;
float __tmp_coord_array_2__[4] ;
mv_zero(__tmp_coord_array_2__, 4);
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((y.m_gu & 1) != 0)) {
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_2__[0] += (__x_xpd__[0][0] * __y_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_2__[1] += (__x_xpd__[1][0] * __y_xpd__[0][0]);
__tmp_coord_array_2__[2] += (__x_xpd__[1][1] * __y_xpd__[0][0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_2__[3] += (__x_xpd__[2][0] * __y_xpd__[0][0]);
}
}
if (((y.m_gu & 2) != 0)) {
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_2__[1] += (__x_xpd__[0][0] * __y_xpd__[1][0]);
__tmp_coord_array_2__[2] += (__x_xpd__[0][0] * __y_xpd__[1][1]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_2__[0] += ((__x_xpd__[1][0] * __y_xpd__[1][0]) + (__x_xpd__[1][1] * __y_xpd__[1][1]));
__tmp_coord_array_2__[3] += ((-1.0f * __x_xpd__[1][1] * __y_xpd__[1][0]) + (__x_xpd__[1][0] * __y_xpd__[1][1]));
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_2__[1] += (__x_xpd__[2][0] * __y_xpd__[1][1]);
__tmp_coord_array_2__[2] += (-1.0f * __x_xpd__[2][0] * __y_xpd__[1][0]);
}
}
if (((y.m_gu & 4) != 0)) {
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_2__[3] += (__x_xpd__[0][0] * __y_xpd__[2][0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_2__[1] += (-1.0f * __x_xpd__[1][1] * __y_xpd__[2][0]);
__tmp_coord_array_2__[2] += (__x_xpd__[1][0] * __y_xpd__[2][0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_2__[0] += (-1.0f * __x_xpd__[2][0] * __y_xpd__[2][0]);
}
}
__temp_var_1__ = mv_compress(__tmp_coord_array_2__);
return __temp_var_1__;
}
mv op(const mv& x, const mv& y) {
mv __temp_var_1__;
float __tmp_coord_array_3__[4] ;
mv_zero(__tmp_coord_array_3__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
if (((x.m_gu & 1) != 0)) {
if (((y.m_gu & 1) != 0)) {
__tmp_coord_array_3__[0] += (__x_xpd__[0][0] * __y_xpd__[0][0]);
}
if (((y.m_gu & 2) != 0)) {
__tmp_coord_array_3__[1] += (__x_xpd__[0][0] * __y_xpd__[1][0]);
__tmp_coord_array_3__[2] += (__x_xpd__[0][0] * __y_xpd__[1][1]);
}
if (((y.m_gu & 4) != 0)) {
__tmp_coord_array_3__[3] += (__x_xpd__[0][0] * __y_xpd__[2][0]);
}
}
if (((x.m_gu & 2) != 0)) {
if (((y.m_gu & 1) != 0)) {
__tmp_coord_array_3__[1] += (__x_xpd__[1][0] * __y_xpd__[0][0]);
__tmp_coord_array_3__[2] += (__x_xpd__[1][1] * __y_xpd__[0][0]);
}
if (((y.m_gu & 2) != 0)) {
__tmp_coord_array_3__[3] += ((-1.0f * __x_xpd__[1][1] * __y_xpd__[1][0]) + (__x_xpd__[1][0] * __y_xpd__[1][1]));
}
}
if (((x.m_gu & 4) != 0)) {
if (((y.m_gu & 1) != 0)) {
__tmp_coord_array_3__[3] += (__x_xpd__[2][0] * __y_xpd__[0][0]);
}
}
__temp_var_1__ = mv_compress(__tmp_coord_array_3__);
return __temp_var_1__;
}
mv add(const mv& x, const mv& y) {
mv __temp_var_1__;
float __tmp_coord_array_4__[4] ;
mv_zero(__tmp_coord_array_4__, 4);
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_4__[0] += __x_xpd__[0][0];
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_4__[1] += __x_xpd__[1][0];
__tmp_coord_array_4__[2] += __x_xpd__[1][1];
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_4__[3] += __x_xpd__[2][0];
}
if (((y.m_gu & 1) != 0)) {
__tmp_coord_array_4__[0] += __y_xpd__[0][0];
}
if (((y.m_gu & 2) != 0)) {
__tmp_coord_array_4__[1] += __y_xpd__[1][0];
__tmp_coord_array_4__[2] += __y_xpd__[1][1];
}
if (((y.m_gu & 4) != 0)) {
__tmp_coord_array_4__[3] += __y_xpd__[2][0];
}
__temp_var_1__ = mv_compress(__tmp_coord_array_4__);
return __temp_var_1__;
}
mv subtract(const mv& x, const mv& y) {
mv __temp_var_1__;
float __tmp_coord_array_5__[4] ;
mv_zero(__tmp_coord_array_5__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
if (((y.m_gu & 1) != 0)) {
__tmp_coord_array_5__[0] += (-1.0f * __y_xpd__[0][0]);
}
if (((y.m_gu & 2) != 0)) {
__tmp_coord_array_5__[1] += (-1.0f * __y_xpd__[1][0]);
__tmp_coord_array_5__[2] += (-1.0f * __y_xpd__[1][1]);
}
if (((y.m_gu & 4) != 0)) {
__tmp_coord_array_5__[3] += (-1.0f * __y_xpd__[2][0]);
}
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_5__[0] += __x_xpd__[0][0];
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_5__[1] += __x_xpd__[1][0];
__tmp_coord_array_5__[2] += __x_xpd__[1][1];
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_5__[3] += __x_xpd__[2][0];
}
__temp_var_1__ = mv_compress(__tmp_coord_array_5__);
return __temp_var_1__;
}
scalar norm_e2(const mv& x) {
scalar __temp_var_1__;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__temp_var_1__.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__temp_var_1__.m_c[0] += ((__x_xpd__[1][0] * __x_xpd__[1][0]) + (__x_xpd__[1][1] * __x_xpd__[1][1]));
}
if (((x.m_gu & 4) != 0)) {
__temp_var_1__.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
return __temp_var_1__;
}
scalar norm_e(const mv& x) {
scalar e2;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
e2.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
e2.m_c[0] += ((__x_xpd__[1][1] * __x_xpd__[1][1]) + (__x_xpd__[1][0] * __x_xpd__[1][0]));
}
if (((x.m_gu & 4) != 0)) {
e2.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
return scalar(scalar_scalar, sqrt(e2.m_c[0]));
}
mv unit_e(const mv& x) {
scalar e2;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
e2.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
e2.m_c[0] += ((__x_xpd__[1][0] * __x_xpd__[1][0]) + (__x_xpd__[1][1] * __x_xpd__[1][1]));
}
if (((x.m_gu & 4) != 0)) {
e2.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
scalar ie;
ie.m_c[0] = ((char)1 / sqrt(e2.m_c[0]));
mv __temp_var_1__;
float __tmp_coord_array_6__[4] ;
mv_zero(__tmp_coord_array_6__, 4);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_6__[0] += (__x_xpd__[0][0] * ie.m_c[0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_6__[1] += (__x_xpd__[1][0] * ie.m_c[0]);
__tmp_coord_array_6__[2] += (__x_xpd__[1][1] * ie.m_c[0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_6__[3] += (__x_xpd__[2][0] * ie.m_c[0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_6__);
return __temp_var_1__;
}
scalar norm_r2(const mv& x) {
scalar __temp_var_1__;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__temp_var_1__.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__temp_var_1__.m_c[0] += ((__x_xpd__[1][0] * __x_xpd__[1][0]) + (__x_xpd__[1][1] * __x_xpd__[1][1]));
}
if (((x.m_gu & 4) != 0)) {
__temp_var_1__.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
return __temp_var_1__;
}
scalar norm_r(const mv& x) {
scalar r2;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
r2.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
r2.m_c[0] += ((__x_xpd__[1][1] * __x_xpd__[1][1]) + (__x_xpd__[1][0] * __x_xpd__[1][0]));
}
if (((x.m_gu & 4) != 0)) {
r2.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
return scalar(scalar_scalar, ((((r2.m_c[0] < (char)0)) ? (char)-1 : ((((r2.m_c[0] > (char)0)) ? (char)1 : (char)0))) * sqrt((((r2.m_c[0] < (char)0)) ? ((-r2.m_c[0])) : (r2.m_c[0])))));
}
mv unit_r(const mv& x) {
scalar r2;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
r2.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
r2.m_c[0] += ((__x_xpd__[1][1] * __x_xpd__[1][1]) + (__x_xpd__[1][0] * __x_xpd__[1][0]));
}
if (((x.m_gu & 4) != 0)) {
r2.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
scalar ir;
ir.m_c[0] = ((char)1 / sqrt((((r2.m_c[0] < (char)0)) ? ((-r2.m_c[0])) : (r2.m_c[0]))));
mv __temp_var_1__;
float __tmp_coord_array_7__[4] ;
mv_zero(__tmp_coord_array_7__, 4);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_7__[0] += (__x_xpd__[0][0] * ir.m_c[0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_7__[1] += (__x_xpd__[1][0] * ir.m_c[0]);
__tmp_coord_array_7__[2] += (__x_xpd__[1][1] * ir.m_c[0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_7__[3] += (__x_xpd__[2][0] * ir.m_c[0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_7__);
return __temp_var_1__;
}
mv reverse(const mv& x) {
mv __temp_var_1__;
float __tmp_coord_array_8__[4] ;
mv_zero(__tmp_coord_array_8__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_8__[0] += __x_xpd__[0][0];
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_8__[1] += __x_xpd__[1][0];
__tmp_coord_array_8__[2] += __x_xpd__[1][1];
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_8__[3] += (-1.0f * __x_xpd__[2][0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_8__);
return __temp_var_1__;
}
mv negate(const mv& x) {
mv __temp_var_1__;
float __tmp_coord_array_9__[4] ;
mv_zero(__tmp_coord_array_9__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_9__[0] += (-1.0f * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_9__[1] += (-1.0f * __x_xpd__[1][0]);
__tmp_coord_array_9__[2] += (-1.0f * __x_xpd__[1][1]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_9__[3] += (-1.0f * __x_xpd__[2][0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_9__);
return __temp_var_1__;
}
mv dual(const mv& x) {
mv __temp_var_1__;
float __tmp_coord_array_10__[4] ;
mv_zero(__tmp_coord_array_10__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_10__[3] += (-1.0f * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_10__[1] += __x_xpd__[1][1];
__tmp_coord_array_10__[2] += (-1.0f * __x_xpd__[1][0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_10__[0] += __x_xpd__[2][0];
}
__temp_var_1__ = mv_compress(__tmp_coord_array_10__);
return __temp_var_1__;
}
mv undual(const mv& x) {
mv __temp_var_1__;
float __tmp_coord_array_11__[4] ;
mv_zero(__tmp_coord_array_11__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_11__[3] += __x_xpd__[0][0];
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_11__[1] += (-1.0f * __x_xpd__[1][1]);
__tmp_coord_array_11__[2] += __x_xpd__[1][0];
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_11__[0] += (-1.0f * __x_xpd__[2][0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_11__);
return __temp_var_1__;
}
mv inverse(const mv& x) {
scalar n;
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
n.m_c[0] += (__x_xpd__[0][0] * __x_xpd__[0][0]);
}
if (((x.m_gu & 2) != 0)) {
n.m_c[0] += ((__x_xpd__[1][1] * __x_xpd__[1][1]) + (__x_xpd__[1][0] * __x_xpd__[1][0]));
}
if (((x.m_gu & 4) != 0)) {
n.m_c[0] += (__x_xpd__[2][0] * __x_xpd__[2][0]);
}
scalar in;
in.m_c[0] = ((char)1 / n.m_c[0]);
mv __temp_var_1__;
float __tmp_coord_array_12__[4] ;
mv_zero(__tmp_coord_array_12__, 4);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_12__[0] += (__x_xpd__[0][0] * in.m_c[0]);
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_12__[1] += (__x_xpd__[1][0] * in.m_c[0]);
__tmp_coord_array_12__[2] += (__x_xpd__[1][1] * in.m_c[0]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_12__[3] += (-1.0f * __x_xpd__[2][0] * in.m_c[0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_12__);
return __temp_var_1__;
}
mv gradeInvolution(const mv& x) {
mv __temp_var_1__;
float __tmp_coord_array_13__[4] ;
mv_zero(__tmp_coord_array_13__, 4);
const float* __x_xpd__[3] ;
x.expand(__x_xpd__, true);
if (((x.m_gu & 1) != 0)) {
__tmp_coord_array_13__[0] += __x_xpd__[0][0];
}
if (((x.m_gu & 2) != 0)) {
__tmp_coord_array_13__[1] += (-1.0f * __x_xpd__[1][0]);
__tmp_coord_array_13__[2] += (-1.0f * __x_xpd__[1][1]);
}
if (((x.m_gu & 4) != 0)) {
__tmp_coord_array_13__[3] += __x_xpd__[2][0];
}
__temp_var_1__ = mv_compress(__tmp_coord_array_13__);
return __temp_var_1__;
}
// G2 functions:
mv apply_om(const om& x, const mv& y) {
mv __temp_var_1__;
float __tmp_coord_array_14__[4] ;
mv_zero(__tmp_coord_array_14__, 4);
const float* __y_xpd__[3] ;
y.expand(__y_xpd__, true);
if (((y.m_gu & 2) != 0)) {
__tmp_coord_array_14__[1] += ((x.m_c[0] * __y_xpd__[1][0]) + (x.m_c[1] * __y_xpd__[1][1]));
__tmp_coord_array_14__[2] += ((x.m_c[2] * __y_xpd__[1][0]) + (x.m_c[3] * __y_xpd__[1][1]));
}
if (((y.m_gu & 4) != 0)) {
__tmp_coord_array_14__[3] += (x.m_c[4] * __y_xpd__[2][0]);
}
__temp_var_1__ = mv_compress(__tmp_coord_array_14__);
return __temp_var_1__;
}
namespace __G2_GENERATED__ {
void set(om& __x__, const vector& __image_of_e1__, const vector& __image_of_e2__) {
__x__.m_c[0] = __image_of_e1__.m_c[0];
__x__.m_c[2] = __image_of_e1__.m_c[1];
__x__.m_c[1] = __image_of_e2__.m_c[0];
__x__.m_c[3] = __image_of_e2__.m_c[1];
__x__.m_c[4] = ((__x__.m_c[3] * __x__.m_c[0]) + (-1.0f * __x__.m_c[1] * __x__.m_c[2]));
}
} /* end of namespace __G2_GENERATED__ */
// algebra / user constants:
__I2i_ct__ I2i;
__I2_ct__ I2;
__e1_ct__ e1;
__e2_ct__ e2;
char *string(const mv & obj, char *str, int maxLength, const char *fp /* = NULL */) {
int stdIdx = 0, l;
char tmpBuf[256], tmpFloatBuf[256];
int i, j, k = 0, bei, ia = 0, s = mv_size[obj.gu()], p = 0, cnt = 0;
// set up the floating point precision
if (fp == NULL) fp = mv_string_fp;
// start the string
l = sprintf(tmpBuf, "%s", mv_string_start);
if (stdIdx + l <= maxLength) {
strcpy(str + stdIdx, tmpBuf);
stdIdx += l;
}
else mv_throw_exception("Buffer supplied to string() is too small", MV_EXCEPTION_ERROR);
// print all coordinates
for (i = 0; i <= 2; i++) {
if (obj.gu() & (1 << i)) {
for (j = 0; j < mv_gradeSize[i]; j++) {
float coord = (float)mv_basisElementSignByIndex[ia] * obj.m_c[k];
/* goal: print [+|-]obj.m_c[k][* basisVector1 ^ ... ^ basisVectorN] */
sprintf(tmpFloatBuf, fp, fabs(coord));
if (atof(tmpFloatBuf) != 0.0) {
l = 0;
// print [+|-]
l += sprintf(tmpBuf + l, "%s", (coord >= 0.0)
? (cnt ? mv_string_plus : "")
: mv_string_minus);
// print obj.m_c[k]
l += sprintf(tmpBuf + l, tmpFloatBuf);
if (i) { // if not grade 0, print [* basisVector1 ^ ... ^ basisVectorN]
l += sprintf(tmpBuf + l, "%s", mv_string_mul);
// print all basis vectors
bei = 0;
while (mv_basisElements[ia][bei] >= 0) {
l += sprintf(tmpBuf + l, "%s%s", (bei) ? mv_string_wedge : "",
mv_basisVectorNames[mv_basisElements[ia][bei]]);
bei++;
}
}
//copy all to 'str'
if (stdIdx + l <= maxLength) {
strcpy(str + stdIdx, tmpBuf);
stdIdx += l;
}
else mv_throw_exception("Buffer supplied to string() is too small", MV_EXCEPTION_ERROR);
cnt++;
}
k++; ia++;
}
}
else ia += mv_gradeSize[i];
}
// if no coordinates printed: 0
l = 0;
if (cnt == 0) {
l += sprintf(tmpBuf + l, "0");
}
// end the string
l += sprintf(tmpBuf + l, "%s", mv_string_end);
if (stdIdx + l <= maxLength) {
strcpy(str + stdIdx, tmpBuf);
stdIdx += l;
}
else mv_throw_exception("Buffer supplied to string() is too small", MV_EXCEPTION_ERROR);
return str;
}
// this function should be deprecated (conflicts with C++ stdlib)
char *string(const mv & obj, const char *fp /* = NULL */) {
// not multithreading safe, but not fatal either.
static char str[2048];
return string(obj, str, 2047, fp);
}
char *c_str(const mv & obj, const char *fp /* = NULL */) {
return string(obj, fp);
}
std::string toString(const mv & obj, const char *fp /* = NULL */) {
std::string str;
const int SIZE = 2048;
str.resize(SIZE);
string(obj, &(str[0]), SIZE-1, fp);
str.resize(strlen(&(str[0])));
return str;
}
/** This function is not for external use. It compressed arrays of floats for storage in multivectors. */
void compress(const float *c, float *cc, int &cgu, float epsilon /*= 0.0*/, int gu /*= ...*/) {
int i, j, ia = 0, ib = 0, f, s;
cgu = 0;
// for all grade parts...
for (i = 0; i <= 2; i++) {
// check if grade part has memory use:
if (!(gu & (1 << i))) continue;
// check if abs coordinates of grade part are all < epsilon
s = mv_gradeSize[i];
j = ia + s;
f = 0;
for (; ia < j; ia++)
if (mv_absLessThan(c[ia], epsilon)) {f = 1; break;}
ia = j;
if (f) {
mv_memcpy(cc + ib, c + ia - s, s);
ib += s;
cgu |= (1 << i);
}
}
}
mv mv_compress(const float *c, float epsilon/*= 0.0*/, int gu /*= ...*/) {
float cc[4];
int cgu;
compress(c, cc, cgu, epsilon, gu);
return mv(cgu, cc);
}
mv compress(const mv & arg1, float epsilon /*= 0.0*/) {
return mv_compress(arg1.m_c, epsilon, arg1.m_gu);
}
void mv::compress(float epsilon /*= 0.0*/) {
float cc[4];
int cgu;
e2ga::compress(m_c, cc, cgu, epsilon, m_gu);
set(cgu, cc);
}
mv mv_compress(int nbBlades, const unsigned int *bitmaps, const mv::Float *coords) {
// convert basis blade compression to regular coordinate array:
mv::Float A[4];
mv_zero(A, 4);
// int gu = 0;
for (int i = 0; i < nbBlades; i++) {
A[mv_basisElementIndexByBitmap[bitmaps[i]]] = coords[i] * (mv::Float)mv_basisElementSignByBitmap[bitmaps[i]];
// gu |= (1 << mv_basisElementGradeByBitmap[bitmaps[i]]);
}
return mv_compress(A); //, (mv::Float)0.0, gu);
}
/** This function is not for external use. It decompresses the coordinates stored in this */
void mv::expand(const Float *ptrs[], bool nulls /* = true */) const {
const Float *c(m_c);
const Float *null = (nulls) ? NULL : nullFloats();
if (m_gu & 1) {
ptrs[0] = c;
c += 1;
}
else ptrs[0] = null;
if (m_gu & 2) {
ptrs[1] = c;
c += 2;
}
else ptrs[1] = null;
if (m_gu & 4) {
ptrs[2] = c;
c += 1;
}
else ptrs[2] = null;
}
void mvType::init(const mv &X, mv::Float epsilon) {
m_type = MULTIVECTOR;
// first of all determine grade usage & parity
mv cX = X;
cX.compress(epsilon);
m_gradeUsage = (int)cX.gu();
int cnt[2] = {0,0}; // nb even, odd grade parts in use
{
// count grade part usage:
int cntIdx = 0;
int gu = m_gradeUsage;
while (gu != 0) {
if ((gu & 1) != 0)
cnt[cntIdx & 1]++;
gu >>= 1;
m_grade = cntIdx;
cntIdx++;
}
// if no grade part in use: zero blade
if ((cnt[0] == 0) && (cnt[1] == 0)) {
// multivector = zero blade, case closed
m_zero = true;
m_type = BLADE;
m_parity = 0;
m_grade = 0; // forced to grade 0, but actually, does not really have a grade
return;
}
else {
m_zero = false;
// if both even and odd grade parts in use: multivector
if ((cnt[0] != 0) && (cnt[1] != 0)) {
// X = multivector, case closed
m_parity = -1;
return;
}
else // more work to do, but parity is known:
// either a blade, or a versor, TBD below
m_parity = (cnt[1] != 0) ? 1 : 0;
}
}
// first test for versor:
bool useAlgebraMetric = true;
init(X, epsilon, useAlgebraMetric, cnt[0] + cnt[1]);
}
void mvType::init(const mv &X, mv::Float epsilon, bool useAlgebraMetric, int guCnt) {
mv rX = reverse(X);
// test if null:
mv Sq = (useAlgebraMetric) ? scp(X, rX) : scp(X, rX);
Sq.compress(epsilon);
if (_Float(Sq) == 0) {
// X = multivector, case closed
m_type = MULTIVECTOR;
return;
}
// versor inverse must be true inverse:
mv Xvi = (useAlgebraMetric) ? inverse(X) : inverse(X);
mv Xgi = gradeInvolution(X);
// check if (Xgi Xvi) is a scalar:
mv XgiXvi = (useAlgebraMetric) ? gp(Xgi, Xvi) : gp(Xgi, Xvi);
{
mv tmp = XgiXvi;
tmp.compress(epsilon);
if (tmp.gu() != GRADE_0) { // if not scalar:
// X = multivector, case closed
m_type = MULTIVECTOR;
return;
}
}
// check if Xgi Xvi == Xvi Xgi
mv XviXgi = (useAlgebraMetric) ? gp(Xvi, Xgi) : gp(Xvi, Xgi);
{
mv tmp = XviXgi - XgiXvi;
tmp.compress(epsilon); // this should result in 0
if (tmp.gu()) {
// if not:
// X = multivector, case closed
m_type = MULTIVECTOR;
return;
}
}
// check if grade preserving for all basis vectors:
{
{
// test e1
mv tmp = (useAlgebraMetric) ? gp(gp(Xvi, e1), Xgi) : gp(gp(Xvi, e1), Xgi);
tmp.compress(epsilon);
if (tmp.gu() != GRADE_1) { // X = multivector, case closed
m_type = MULTIVECTOR;
return;
}
}
{
// test e2
mv tmp = (useAlgebraMetric) ? gp(gp(Xvi, e2), Xgi) : gp(gp(Xvi, e2), Xgi);
tmp.compress(epsilon);
if (tmp.gu() != GRADE_1) { // X = multivector, case closed
m_type = MULTIVECTOR;
return;
}
}
}
// if homogeneous: blade
if (guCnt == 1) m_type = BLADE;
else m_type = VERSOR;
}
std::string mvType::toString() const {
char buf[1024];
sprintf(buf, "%s, grade: %d, gradeUsage: %X, parity: %s",
(m_type == MULTIVECTOR) ? "multivector" : ((m_type == BLADE) ? "blade" : "versor"),
m_grade, m_gradeUsage,
(m_parity < 0) ? "none" : ((m_parity == 0) ? "even" : "odd"));
return buf;
}
} // end of namespace e2ga
// post_cpp_include