private Equation(Algebrable left, Algebrable right, bool register) { _Left = left; _Right = right; if (register) { AddDependents(left); AddDependents(right); } }
/// <summary> /// Determines if an expression contains the specified dependent variable. /// </summary> /// <returns><c>true</c> if an expression contains the specified dependent variable; otherwise, <c>false</c>.</returns> /// <param name="expression">The expression to search.</param> /// <param name="dv">The dependent variable to find.</param> /// <typeparam name="T">The type of the dependent variable.</typeparam> public static bool HasDV <T>(Algebrable expression, DependentVariable <T> dv) where T : Algebrable { if (expression is AlgebraOperation) { return(HasDV((AlgebraOperation)expression, dv)); } else { return(((object)expression) == ((object)dv)); } }
private void AddDependents(Algebrable op) { if (op is AlgebraOperation) { AddDependents((AlgebraOperation)op); } else if (op is IDependentVariable <Algebrable> ) { ((IDependentVariable <Algebrable>)op).AddEquation(this); } }
/// <summary> /// Exponentiates this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Exponentiate(Algebrable second) { return(Evaluate().Exponentiate(second)); }
/// <summary> /// Divides this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Divide(Algebrable second) { return(Evaluate().Divide(second)); }
/// <summary> /// Multiplies another algebrable object by this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Multiply(Algebrable second) { return(Evaluate().Multiply(second)); }
/// <summary> /// Subtracts another algebrable object from this object. /// </summary> /// <param name="second">The other object.</param> public abstract Algebrable Subtract(Algebrable second);
/// <summary> /// Exponentiates this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Exponentiate(Algebrable second) { return(new ExponentiationOperation(this, second)); }
/// <summary> /// Divides this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public abstract Algebrable Divide(Algebrable second);
/// <summary> /// Gets the inverse <see cref="LINA.AlgebraOperation"/> with the specified left operand. /// </summary> /// <returns>The inverse operation.</returns> /// <param name="left">The left operand.</param> protected abstract AlgebraOperation GetInverse(Algebrable left);
/// <summary> /// Solved this equation for the specified dependent variable. /// </summary> /// <param name="dv">The dependent variable to solve for.</param> /// <typeparam name="T">The type of the dependent variable.</typeparam> public T Solve <T>(DependentVariable <T> dv) where T : Algebrable { if (HasDV(Left, dv)) { if (HasDV(Right, dv)) { throw new NotImplementedException("A DV on both sides of an equation is not yet supported"); } else { Algebrable left = Left; Algebrable right = Right; while (((object)left) != ((object)dv)) { if (left is AlgebraOperation) { AlgebraOperation op = (AlgebraOperation)left; Algebrable subLeft; Algebrable subRight; if (HasDV(op.Left, dv)) { if (HasDV(op.Right, dv)) { throw new NotImplementedException("Only 1 DV is currently supported"); } else { subLeft = op.Left; subRight = op.Right; } } else if (HasDV(op.Right, dv)) { op = op.Flip; subLeft = op.Left; subRight = op.Right; } else { throw new InvalidOperationException("Internal error"); } left = subLeft; right = op.Inverse[right]; } else { throw new NotImplementedException("Unknown equation type"); } } return((T)right.Evaluate()); } } else if (HasDV(Right, dv)) { return(Inverse.Solve(dv)); } else { throw new InvalidOperationException("DV does not exist in equation"); } }
/// <summary> /// Multiplies another algebrable object by this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Multiply(Algebrable second) { return(second is Constant <T>?(((object)Value) == null ? null : Value.Multiply(second)) : base.Multiply(second)); }
/// <summary> /// Exponentiates this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Exponentiate(Algebrable second) { return(second is Constant <T>?(((object)Value) == null ? null : Value.Exponentiate(second)) : base.Exponentiate(second)); }
/// <summary> /// Subtracts another algebrable object from this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Subtract(Algebrable second) { return(second is Constant <T>?(((object)Value) == null ? null : Value.Subtract(second)) : base.Subtract(second)); }
/// <summary> /// Takes the logarithm of this object in the base of another algebrable object. /// </summary> /// <param name="second">The other object.</param> public abstract Algebrable Logarithm(Algebrable second);
/// <summary> /// Exponentiates this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public abstract Algebrable Exponentiate(Algebrable second);
/// <summary> /// Takes the logarithm of this object in the base of another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Logarithm(Algebrable second) { return(Evaluate().Logarithm(second)); }
/// <summary> /// Adds another algebrable object to this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Add(Algebrable second) { return(new AdditionOperation(this, second)); }
/// <summary> /// Gets the inverse <see cref="LINA.AlgebraOperation"/> with the specified left operand. /// </summary> /// <param name="left">The left operand.</param> public AlgebraOperation this[Algebrable left] { get { return(Op.GetInverse(left)); } }
/// <summary> /// Multiplies another algebrable object by this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Multiply(Algebrable second) { return(new MultiplicationOperation(this, second)); }
/// <summary> /// Adds another algebrable object to this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Add(Algebrable second) { return(Evaluate().Add(second)); }
/// <summary> /// Multiplies another algebrable object by this object. /// </summary> /// <param name="second">The other object.</param> public abstract Algebrable Multiply(Algebrable second);
/// <summary> /// Subtracts another algebrable object from this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Subtract(Algebrable second) { return(new SubtractionOperation(this, second)); }
/// <summary> /// Initializes a new instance of the <see cref="LINA.Equation"/> class. /// </summary> /// <param name="left">The left side of the equation.</param> /// <param name="right">The left side of the equation.</param> public Equation(Algebrable left, Algebrable right) : this(left, right, true) { }
/// <summary> /// Divides this object by another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Divide(Algebrable second) { return(new DivisionOperation(this, second)); }
/// <summary> /// Subtracts another algebrable object from this object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Subtract(Algebrable second) { return(Evaluate().Subtract(second)); }
/// <summary> /// Takes the logarithm of this object in the base of another algebrable object. /// </summary> /// <param name="second">The other object.</param> public override Algebrable Logarithm(Algebrable second) { return(new LogarithmOperation(this, second)); }
/// <summary> /// Adds another algebrable object to this object. /// </summary> /// <param name="second">The other object.</param> public abstract Algebrable Add(Algebrable second);