예제 #1
0
//=========================================================================================
/*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;
}
예제 #2
0
//=========================================================================================
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;
}
예제 #3
0
//=========================================================================================
/*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;
}
예제 #4
0
//=========================================================================================
/*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;
}
예제 #5
0
//=========================================================================================
/*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;
}
예제 #6
0
//=========================================================================================
/*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;
}
예제 #7
0
//=========================================================================================
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;
}
예제 #8
0
//=========================================================================================
/*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;
}
예제 #9
0
//=========================================================================================
/*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;
}
예제 #10
0
//=========================================================================================
/*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;
}
예제 #11
0
//=========================================================================================
/*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;
}
예제 #12
0
//=========================================================================================
/*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;
}
예제 #13
0
//=========================================================================================
/*virtual*/ bool Evaluator::StoreResult( const Number& result, Environment& environment )
{
	environment.AddError( "Result cannot be stored." );
	return false;
}