//========================================================================================= /*virtual*/ bool InverseFunctionEvaluator::EvaluateResult( Number& result, Environment& environment ) { bool success = false; Number* argumentResult = 0; do { FunctionArgumentEvaluator* argument = GetArgument(0); if( !argument ) { environment.AddError( "The inverse function expects an argument." ); break; } argumentResult = environment.CreateNumber( argument ); if( !argument->EvaluateResult( *argumentResult, environment ) ) break; if( !result.IsTypeOf( MultivectorNumber::ClassName() ) ) break; if( !result.AssignMultilicativeInverse( argumentResult, environment ) ) { environment.AddError( "Failed to take the inverse!" ); break; } success = true; } while( false ); delete argumentResult; return success; }
//========================================================================================= bool BinaryOperationEvaluator::EvaluateOperands( Number*& leftNumber, Number*& rightNumber, Environment& environment ) { bool success = false; leftNumber = 0; rightNumber = 0; do { if( !leftOperand ) { environment.AddError( "Binary operator has no left operand." ); break; } if( !rightOperand ) { environment.AddError( "Binary operator has no right operand." ); break; } // Call upon the environment to create the types of numbers we'll be working with. leftNumber = environment.CreateNumber( this ); rightNumber = environment.CreateNumber( this ); if( !( leftNumber && rightNumber ) ) { environment.AddError( "Failed to create numbers from environment for binary operation." ); break; } // Evaluate our left and right operands. if( !leftOperand->EvaluateResult( *leftNumber, environment ) ) { environment.AddError( "Failed to evaluate left operand of binary operator." ); break; } if( !rightOperand->EvaluateResult( *rightNumber, environment ) ) { environment.AddError( "Failed to evaluate right operand of binary operator." ); break; } success = true; } while( false ); if( !success ) { delete leftNumber; delete rightNumber; leftNumber = 0; rightNumber = 0; } return success; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::AssignFrom( const Number* number, Environment& environment ) { if( !number->IsTypeOf( MultivectorNumber::ClassName() ) ) { environment.AddError( "Cannot assign anything but a multivector-type number to such a number." ); return false; } MultivectorNumber* multivectorNumber = ( MultivectorNumber* )number; if( !multivector.AssignSumOfBlades( multivectorNumber->multivector ) ) { environment.AddError( "Failed to assign one multivector to another!" ); return false; } return true; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::AssignFrom( const GeometricAlgebra::SumOfBlades& sumOfBlades, Environment& environment ) { if( !multivector.AssignSumOfBlades( sumOfBlades ) ) { environment.AddError( "Failed to assign sum of blades to multivector number." ); return false; } return true; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::AssignFrom( double number, Environment& environment ) { if( !multivector.AssignScalar( number ) ) { environment.AddError( "Failed to assign scalar %f to multivector.", number ); return false; } return true; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::Print( char* buffer, int bufferSize, bool printLatex, Environment& environment ) const { ScalarAlgebra::PrintPurpose printPurpose = ScalarAlgebra::PRINT_FOR_READING; if( printLatex ) printPurpose = ScalarAlgebra::PRINT_FOR_LATEX; if( !environment.IsTypeOf( GeometricAlgebraEnvironment::ClassName() ) ) { environment.AddError( "Multivector numbers can't be printed in a non-geometric-algebra environment." ); return false; } GeometricAlgebraEnvironment* geometricAlgebraEnvironment = ( GeometricAlgebraEnvironment* )&environment; if( geometricAlgebraEnvironment->displayMode == GeometricAlgebraEnvironment::DISPLAY_AS_SUM_OF_BLADES ) { if( !multivector.Print( buffer, bufferSize, printPurpose ) ) { environment.AddError( "Failed to print multivector!" ); return false; } } else if( geometricAlgebraEnvironment->displayMode == GeometricAlgebraEnvironment::DISPLAY_AS_SUM_OF_VERSORS ) { GeometricAlgebra::SumOfPseudoVersors sumOfPseudoVersors; if( !sumOfPseudoVersors.AssignSumOfBlades( multivector ) ) return false; if( !sumOfPseudoVersors.Print( buffer, bufferSize, printPurpose ) ) { environment.AddError( "Failed to print sum of versors!" ); return false; } } else { environment.AddError( "Multivector number display mode is unknown." ); return false; } return true; }
//========================================================================================= bool UnaryOperationEvaluator::EvaluateOperand( Number*& number, Environment& environment ) { bool success = false; do { if( !operand ) { environment.AddError( "Unary operator has no argument." ); break; } // Call upon the environment to create the type of number we'll be working with. number = environment.CreateNumber( operand ); if( !number ) { environment.AddError( "Failed to create number from environment for unary operator." ); break; } // Evaluate our operand. if( !operand->EvaluateResult( *number, environment ) ) { environment.AddError( "Unary operand operand evaluation failed." ); break; } success = true; } while( false ); if( !success ) { delete number; number = 0; } return success; }
//========================================================================================= /*virtual*/ bool FunctionArgumentEvaluator::EvaluateResult( Number& result, Environment& environment ) { if( !argument ) { environment.AddError( "Function argument evaluator has no argument to evaluate." ); return false; } if( !argument->EvaluateResult( result, environment ) ) return false; return true; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::AssignFrom( const char* numberString, Environment& environment ) { if( *numberString == '$' ) { const char* variableName = numberString + 1; if( !multivector.AssignScalar( variableName ) ) { environment.AddError( "Failed to assign scalar \"%s\" to multivector.", variableName ); return false; } } else { double scalar = atof( numberString ); if( !multivector.AssignScalar( scalar ) ) { environment.AddError( "Failed to assign scalar %f to multivector.", scalar ); return false; } } return true; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::AssignMultilicativeInverse( const Number* number, Environment& environment ) { if( !number->IsTypeOf( MultivectorNumber::ClassName() ) ) return false; GeometricAlgebra::SumOfBlades::InverseResult inverseResult; MultivectorNumber* multivectorNumber = ( MultivectorNumber* )number; if( !multivector.AssignGeometricInverse( multivectorNumber->multivector, GeometricAlgebra::SumOfBlades::RIGHT_INVERSE, inverseResult ) ) { if( inverseResult == GeometricAlgebra::SumOfBlades::SINGULAR_MULTIVECTOR ) { environment.AddError( "The multivector that you tried to invert is not invertable." ); return false; } else { environment.AddError( "An error occured while trying to calculate the inverse of the multivector." ); return false; } } return true; }
//========================================================================================= /*virtual*/ bool FractionNumber::AssignMultilicativeInverse( const Number* number, Environment& environment ) { FractionNumber* fraction = ( FractionNumber* )number; if( fraction->numerator == 0 ) { environment.AddError( "Zero does not have a multiplicative inverse!" ); return false; } // Assign the reciprical. numerator = fraction->denominator; denominator = fraction->numerator; // We always keep the denominator positive. if( denominator < 0 ) { numerator *= -1; denominator *= -1; } return true; }
//========================================================================================= /*virtual*/ bool MultivectorNumber::CompareWith( const Number* number, Comparison& comparison, Environment& environment ) const { MultivectorNumber* multivectorNumber = ( MultivectorNumber* )number; if( !multivector.IsHomogeneousOfGrade(0) || !multivectorNumber->multivector.IsHomogeneousOfGrade(0) ) { environment.AddError( "How do you compare one multivector to another when one or both of them is/are not homogeneous of grade zero?" ); return false; } double thisScalar, givenScalar; if( !multivector.AssignScalarTo( thisScalar ) ) return false; if( !multivectorNumber->multivector.AssignScalarTo( givenScalar ) ) return false; if( thisScalar == givenScalar ) comparison = IS_EQUAL_TO; else if( thisScalar < givenScalar ) comparison = IS_LESS_THAN; else if( thisScalar > givenScalar ) comparison = IS_GREATER_THAN; return true; }
//========================================================================================= /*virtual*/ bool Evaluator::StoreResult( const Number& result, Environment& environment ) { environment.AddError( "Result cannot be stored." ); return false; }