// Note that in the interest of efficiency, we do not preserve this term in this process. // Also note that we accumulate into the given multivector. bool Multivector::Term::PerformProductMorphism( Multivector& multivector ) { ProductType targetProductType = OtherProductType( productType ); if( productOfVectors.Count() == 1 ) { ProductOfVectors::Node* node = productOfVectors.Head(); productOfVectors.Remove( node, false ); Term* term = new Term( targetProductType, coeficient ); term->productOfVectors.InsertAfter( 0, node ); multivector.sumOfTerms.InsertAfter()->data = term; return true; } else if( productOfVectors.Count() == 0 ) { Term* term = new Term( targetProductType, coeficient ); multivector.sumOfTerms.InsertAfter()->data = term; return true; } ProductOfVectors::Node* node = productOfVectors.Head(); Vector* vector = node->data; productOfVectors.Remove( node, false ); bool success = false; do { if( targetProductType == GEOMETRIC_PRODUCT ) { Multivector termMultivector; termMultivector.sumOfTerms.InsertAfter()->data = Clone(); Multivector innerProductMultivector; if( !innerProductMultivector.InnerProductMultiply( *vector, termMultivector ) ) break; innerProductMultivector.Negate(); while( innerProductMultivector.sumOfTerms.Count() > 0 ) { SumOfTerms::Node* node = innerProductMultivector.sumOfTerms.Head(); Term* term = node->data; if( !term->PerformProductMorphism( multivector ) ) break; innerProductMultivector.sumOfTerms.Remove( node, true ); } if( innerProductMultivector.sumOfTerms.Count() > 0 ) break; } Multivector subMultivector; if( !PerformProductMorphism( subMultivector ) ) break; if( targetProductType == OUTER_PRODUCT ) { if( !multivector.InnerProductMultiply( *vector, subMultivector ) ) break; if( !multivector.OuterProductMultiply( *vector, subMultivector ) ) break; } else if( targetProductType == GEOMETRIC_PRODUCT ) { if( !multivector.GeometricProductMultiply( *vector, subMultivector ) ) break; } success = true; } while( false ); delete node; return success; }