示例#1
0
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;
}
示例#2
0
std::string DebugString(Multivector<Scalar, Frame, rank> const& multivector) {
  // This |using| is required for the |Trivector|, since we need an ambiguity
  // between |geometry::DebugString(R3Element<Scalar> const&)| and
  // |quantities::DebugString(Scalar const&)| in order for the template magic
  // to work out.
  using quantities::DebugString;
  return DebugString(multivector.coordinates());
}
示例#3
0
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;
}
示例#4
0
Multivector<quantities::Quotient<LScalar, quantities::Quantity<RDimension>>,
            Frame,
            rank>
operator/(Multivector<LScalar, Frame, rank> const& left,
          quantities::Quantity<RDimension> const& right) {
  return Multivector<
      quantities::Quotient<LScalar, quantities::Quantity<RDimension>>,
      Frame,
      rank>(left.coordinates() / right);
}
示例#5
0
Multivector<quantities::Product<quantities::Quantity<LDimension>, RScalar>,
            Frame,
            rank>
operator*(quantities::Quantity<LDimension> const& left,
          Multivector<RScalar, Frame, rank> const& right) {
  return Multivector<
      quantities::Product<quantities::Quantity<LDimension>, RScalar>,
      Frame,
      rank>(left * right.coordinates());
}
示例#6
0
inline Multivector<
    quantities::Product<LScalar, quantities::Quantity<RDimension>>,
    Frame,
    rank>
operator*(Multivector<LScalar, Frame, rank> const& left,
          quantities::Quantity<RDimension> const& right) {
  return Multivector<
      quantities::Product<LScalar, quantities::Quantity<RDimension>>,
      Frame,
      rank>(left.coordinates() * right);
}
示例#7
0
bool operator!=(Multivector<Scalar, Frame, rank> const& left,
                Multivector<Scalar, Frame, rank> const& right) {
  return left.coordinates() != right.coordinates();
}
示例#8
0
Multivector<Scalar, Frame, rank> operator/(
    Multivector<Scalar, Frame, rank> const& left,
    double const right) {
  return Multivector<Scalar, Frame, rank>(left.coordinates() / right);
}
示例#9
0
Multivector<Scalar, Frame, rank> operator*(
    double const left,
    Multivector<Scalar, Frame, rank> const& right) {
  return Multivector<Scalar, Frame, rank>(left * right.coordinates());
}
示例#10
0
Multivector<Scalar, Frame, rank> operator-(
    Multivector<Scalar, Frame, rank> const& left,
    Multivector<Scalar, Frame, rank> const& right) {
  return Multivector<Scalar, Frame, rank>(
      left.coordinates() - right.coordinates());
}
示例#11
0
Multivector<Scalar, Frame, rank> operator+(
    Multivector<Scalar, Frame, rank> const& right) {
  return Multivector<Scalar, Frame, rank>(+right.coordinates());
}
示例#12
0
Multivector<double, Frame, 3> Normalize(
    Multivector<Scalar, Frame, 3> const& multivector) {
  Scalar const norm = multivector.Norm();
  CHECK_NE(Scalar(), norm);
  return multivector / norm;
}
示例#13
0
Multivector<double, Frame, 2> Normalize(
    Multivector<Scalar, Frame, 2> const& multivector) {
  return Multivector<double, Frame, 2>(Normalize(multivector.coordinates()));
}
示例#14
0
// 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;
}
示例#15
0
inline Multivector<double, Frame, rank> Normalize(
    Multivector<Scalar, Frame, rank> const& multivector) {
  return multivector / multivector.Norm();
}