bool Multivector::Multiply( const Multivector& multivectorA, const Multivector& multivectorB, Term::ProductType productType ) { Term::ProductType otherProductType = Term::OtherProductType( productType ); if( multivectorA.CountProductTypes( otherProductType ) > 0 ) if( !const_cast< Multivector* >( &multivectorA )->CollectTerms( productType ) ) return false; if( multivectorB.CountProductTypes( otherProductType ) > 0 ) if( !const_cast< Multivector* >( &multivectorB )->CollectTerms( productType ) ) return false; Multivector* multivectorResult = this; Multivector multivectorStorage; if( this == &multivectorA || this == &multivectorB ) multivectorResult = &multivectorStorage; multivectorResult->sumOfTerms.RemoveAll(); for( const SumOfTerms::Node* nodeA = multivectorA.sumOfTerms.Head(); nodeA; nodeA = nodeA->Next() ) { const Term* termA = nodeA->data; for( const SumOfTerms::Node* nodeB = multivectorB.sumOfTerms.Head(); nodeB; nodeB = nodeB->Next() ) { const Term* termB = nodeB->data; Term* termResult = new Term( productType ); multivectorResult->sumOfTerms.InsertAfter()->data = termResult; if( !termResult->coeficient->AssignProduct( *termA->coeficient, *termB->coeficient ) ) return false; for( const Term::ProductOfVectors::Node* node = termA->productOfVectors.Head(); node; node = node->Next() ) termResult->productOfVectors.InsertAfter()->data = node->data->Clone(); for( const Term::ProductOfVectors::Node* node = termB->productOfVectors.Head(); node; node = node->Next() ) termResult->productOfVectors.InsertAfter()->data = node->data->Clone(); } } if( !multivectorResult->CollectTerms( productType ) ) return false; if( multivectorResult == &multivectorStorage ) return Assign( multivectorStorage ); return true; }
bool Multivector::AssignInnerProduct( const Multivector& multivectorA, const Multivector& multivectorB ) { if( multivectorA.CountProductTypes( Term::GEOMETRIC_PRODUCT ) > 0 ) if( !const_cast< Multivector* >( &multivectorA )->CollectTerms( Term::OUTER_PRODUCT ) ) return false; if( multivectorB.CountProductTypes( Term::GEOMETRIC_PRODUCT ) > 0 ) if( !const_cast< Multivector* >( &multivectorB )->CollectTerms( Term::OUTER_PRODUCT ) ) return false; Multivector* multivectorResult = this; Multivector multivectorStorage; if( this == &multivectorA || this == &multivectorB ) multivectorResult = &multivectorStorage; for( const SumOfTerms::Node* nodeA = multivectorA.sumOfTerms.Head(); nodeA; nodeA = nodeA->Next() ) { const Term* termA = nodeA->data; for( const SumOfTerms::Node* nodeB = multivectorB.sumOfTerms.Head(); nodeB; nodeB = nodeB->Next() ) { const Term* termB = nodeB->data; Multivector innerProductMultivector; if( !termA->InnerProductMultiply( termB, innerProductMultivector ) ) return false; Scalar scalar; if( !scalar.AssignProduct( *termA->coeficient, *termB->coeficient ) ) return false; if( !innerProductMultivector.AssignScalarProduct( scalar, innerProductMultivector ) ) return false; multivectorResult->sumOfTerms.Absorb( &innerProductMultivector.sumOfTerms ); } } if( multivectorResult == &multivectorStorage ) return Assign( multivectorStorage ); return true; }