bool Multivector::CollectTerms( Term::ProductType productType ) { Term::ProductType otherProductType = Term::OtherProductType( productType ); for(;;) { SumOfTerms::Node* node = FindTermOfProductType( otherProductType ); if( !node ) break; Term* term = node->data; Multivector multivector; if( !term->PerformProductMorphism( multivector ) ) return false; sumOfTerms.Remove( node, true ); sumOfTerms.Absorb( &multivector.sumOfTerms ); } if( productType == Term::OUTER_PRODUCT ) { // STPTODO: Presort all term products, accounting for the sign change. This way we can use CombineWidth( ..., false ) to save time. } // STPTODO: Combine terms here. // STPTODO: Cull zero terms here. return true; }
// 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; }