Ejemplo n.º 1
0
		private static ExpressionList GetAsExpressionList(Expression expression)
		{
			Assert.IsTrue(expression is SingleComponentExpression);
			var component = ((SingleComponentExpression)expression).Component;
			Assert.IsTrue(component is SingleFactorComponent);
			var factor = ((SingleFactorComponent)component).Factor;
			Assert.IsTrue(factor is ExpressionList);
			return (ExpressionList)factor;
		}
Ejemplo n.º 2
0
		private Expression Evaluate(Expression parameter)
		{
			var operand = Factorizer.ToFactor(parameter.Evaluate());
			if (operand is AlphabeticFactor)
			{
				// If operand is a constant (like pi), and the result is not an integer, don't evaluate
				var factor = (AlphabeticFactor)operand;
				if (Constants.IsNamedConstant(factor.Value))
				{
					var result = _function(Constants.Get(factor.Value));
					if (IsInteger(result))
					{
						return Expressionizer.ToExpression(new NumericFactor(new Integer((int)result)));
					}
					return Expressionizer.ToExpression(new FunctionComponent(Name, new List<Expression> { parameter }));
				}
			}

			// See if our input is any of the basic trig identities
			var identityResult = TrigonometricIdentities.Get(Name, operand);
			if (identityResult != null) return Expressionizer.ToExpression(identityResult);
			
			if (operand is NumericFactor)
			{
				var factor = (NumericFactor)operand;
				if (factor.Number is Float)
				{
					var number = (Float)factor.Number;

					if (Name == "tan" && Math.Abs(number.Value - Math.PI / 2) < Constants.Tolerance)
					{
						return Expressionizer.ToExpression(new ExpressionFactor(new UndefinedExpression()));
					}

					return Expressionizer.ToExpression(new NumericFactor(new Float(_function(number.Value))));
				}
			}

			return Expressionizer.ToExpression(new FunctionComponent(Name, new List<Expression> { Expressionizer.ToExpression(operand) }));
		}
Ejemplo n.º 3
0
		internal ExpressionFactor(Expression expression)
		{
			Expression = expression;
		}
Ejemplo n.º 4
0
		private static bool ReduceExponents(out Expression expression, Expression left, Expression right)
		{
			FunctionComponent leftFunction;
			FunctionComponent rightFunction;
			// If there is an exponent times another instance of that base, combine them
			// e.g. x^2 * x = x^3
			if (Common.IsFunction(left, out leftFunction) && leftFunction.Function is Exponent)
			{
				var baseExpression = leftFunction.Operands[0];
				var power = Factorizer.ToFactor(leftFunction.Operands[1]);
				if (power is NumericFactor && baseExpression.Equals(right))
				{
					expression = Expressionizer.ToExpression(new FunctionComponent(new Exponent(), new List<Expression>
					{
						baseExpression,
						Expressionizer.ToExpression(new NumericFactor(((NumericFactor) power).Number + new Integer(1)))
					}));
					return true;
				}
			}
			if (Common.IsFunction(right, out rightFunction) && rightFunction.Function is Exponent)
			{
				var baseExpression = rightFunction.Operands[0];
				var power = Factorizer.ToFactor(rightFunction.Operands[1]);
				if (power is NumericFactor && baseExpression.Equals(left))
				{
					expression = Expressionizer.ToExpression(new FunctionComponent(new Exponent(), new List<Expression>
					{
						baseExpression,
						Expressionizer.ToExpression(new NumericFactor(((NumericFactor) power).Number + new Integer(1)))
					}));
					return true;
				}
			}

			expression = null;
			return false;
		}
Ejemplo n.º 5
0
		private static bool ReduceFunctionsWithSameOperands(ComponentListFactor leftFactor, ComponentListFactor rightFactor, out Expression expression, Expression left, Expression right)
		{
			FunctionComponent leftFunction;
			FunctionComponent rightFunction;
			// If there are two functions with the same operands that should cancel out, cancel them out
			if (Common.IsFunction(left, out leftFunction) && Common.IsFunction(right, out rightFunction))
			{
				if (leftFunction.Function.Name == rightFunction.Function.Name &&
				    leftFunction.Operands.Count == rightFunction.Operands.Count)
				{
					for (var i = 0; i < leftFunction.Operands.Count; i++)
					{
						var leftOperand = leftFunction.Operands[i];
						var rightOperand = rightFunction.Operands[i];

						if (!leftOperand.ToString().Equals(rightOperand.ToString()))
						{
							break;
						}

						if (leftFactor.IsInNumerator != rightFactor.IsInNumerator)
						{
							expression = Expressionizer.ToExpression(new NumericFactor(new Integer(1)));
							return true;
						}
					}
				}
			}

			expression = null;
			return false;
		}
Ejemplo n.º 6
0
		private static bool ReduceMultipliedAlphabeticFactors(ComponentListFactor leftFactor, ComponentListFactor rightFactor, out Expression expression)
		{
			// If any alphabetic factors are identical, convert to exponent
			if (leftFactor.Factor is AlphabeticFactor && rightFactor.Factor is AlphabeticFactor)
			{
				var leftAlpha = (AlphabeticFactor) leftFactor.Factor;
				var rightAlpha = (AlphabeticFactor) rightFactor.Factor;

				if (leftAlpha.Value.Equals(rightAlpha.Value))
				{
					var shouldPower = leftFactor.IsInNumerator && rightFactor.IsInNumerator;
					if (shouldPower)
					{
						expression = new SingleComponentExpression(new FunctionComponent("^", new List<Expression> { Expressionizer.ToExpression(leftAlpha), NumberToExpression(new Integer(2)) }));
						return true;
					}

					expression = NumberToExpression(new Integer(1));
					return true;
				}
			}

			expression = null;
			return false;
		}
Ejemplo n.º 7
0
		private static bool CanReduce(ComponentListFactor leftFactor, ComponentListFactor rightFactor, out Expression expression)
		{
			if (ReduceMultipliedAlphabeticFactors(leftFactor, rightFactor, out expression))
			{
				return true;
			}

			var left = Expressionizer.ToExpression(leftFactor.Factor);
			var right = Expressionizer.ToExpression(rightFactor.Factor);

			Number leftNumber;
			Number rightNumber;

			if ((Common.IsConstant(left, out leftNumber) && Common.IsFloat(right, out rightNumber)) ||
				(Common.IsFloat(left, out leftNumber) && Common.IsConstant(right, out rightNumber)) ||
				(Common.IsNumber(left, out leftNumber) && Common.IsNumber(right, out rightNumber)))
			{
				expression = Evaluate(leftNumber, rightNumber, leftFactor.IsInNumerator, rightFactor.IsInNumerator);
				return true;
			}

			ExpressionList leftList;
			ExpressionList rightList;

			if (Common.IsList(left, out leftList))
			{
				expression = Evaluate(leftList, right, leftFactor.IsInNumerator == rightFactor.IsInNumerator);
				return true;
			}

			if (Common.IsList(right, out rightList))
			{
				expression = Evaluate(rightList, left, leftFactor.IsInNumerator == rightFactor.IsInNumerator);
				return true;
			}

			IntegerFraction leftFraction;
			IntegerFraction rightFraction;

			if (Common.IsNumber(left, out leftNumber) && Common.IsIntegerFraction(right, out rightFraction))
			{
				expression = Expressionizer.ToExpression(Evaluate(leftNumber, rightFraction, leftFactor.IsInNumerator, rightFactor.IsInNumerator));
				return true;
			}

			if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsNumber(right, out rightNumber))
			{
				expression = Expressionizer.ToExpression(Evaluate(leftFraction, rightNumber, leftFactor.IsInNumerator, rightFactor.IsInNumerator));
				return true;
			}

			if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsIntegerFraction(right, out rightFraction))
			{
				expression = Expressionizer.ToExpression(Evaluate(leftFraction, rightFraction, leftFactor.IsInNumerator, rightFactor.IsInNumerator));
				return true;
			}

			if (ReduceFunctionsWithSameOperands(leftFactor, rightFactor, out expression, left, right))
			{
				return true;
			}

			if (ReduceExponents(out expression, left, right))
			{
				return true;
			}

			expression = null;
			return false;
		}
Ejemplo n.º 8
0
		private static Component ToComponent(Expression expression)
		{
			return expression is SingleComponentExpression
				? ToComponent(((SingleComponentExpression)expression).Component)
				: new SingleFactorComponent(new ExpressionFactor(expression));
		}
Ejemplo n.º 9
0
		private static Expression ToExpression(Expression expression)
		{
			return expression is SingleComponentExpression
				? ToExpression(((SingleComponentExpression)expression).Component)
				: expression;
		}
Ejemplo n.º 10
0
		private static Factor ToFactor(Expression expression)
		{
			return expression is SingleComponentExpression
				? ToFactor(((SingleComponentExpression)expression).Component)
				: new ExpressionFactor(expression);
		}