public static SymbolicVariable operator -(SymbolicVariable a, SymbolicVariable b) { return(SymbolicVariable.Subtract(a, b)); }
/// <summary> /// Multiply Coeffecients of second argument into first argument. /// </summary> /// <param name="SourceTerm"></param> /// <param name="TargetSubTerm"></param> private static void DivideCoeffecients(ref SymbolicVariable SourceTerm, SymbolicVariable TargetSubTerm) { // Note: I will try to avoid the primary coeffecient so it doesn't hold power // and only hold coeffecient itself. foreach (var cst in TargetSubTerm.Constants) { if (SourceTerm._CoeffecientPowerTerm == null && cst.ConstantPower == null) { SourceTerm.Coeffecient /= cst.ConstantValue; } // there is a coeffecient power term needs to be injected into the source else { // no the coeffecient part is not empty so we will test if bases are equal // then make use of the fusedsymbols to add our constant double sbase = Math.Log(SourceTerm.Coeffecient, cst.ConstantValue); if (SourceTerm.Coeffecient == cst.ConstantValue) { // sample: 2^x/2^y = 2^(x-y) var cpower = cst.ConstantPower; if (cpower == null) { cpower = One; } if (SourceTerm._CoeffecientPowerTerm == null) { SourceTerm._CoeffecientPowerTerm = One; } SourceTerm._CoeffecientPowerTerm -= cpower; } else if ((sbase - Math.Floor(sbase)) == 0.0 && sbase > 0) // make sure there are no { // then we can use the target base // 27/3^x = 3^3/3^x = 3^(3-x) var cpower = cst.ConstantPower; if (cpower == null) { cpower = new SymbolicVariable("1"); } SourceTerm._CoeffecientPowerTerm = SymbolicVariable.Subtract(new SymbolicVariable(sbase.ToString(CultureInfo.InvariantCulture)), cpower); SourceTerm.Coeffecient = cst.ConstantValue; } else { // sample: 2^(x+y)*log(2)*3^y * 3^z can't be summed. HybridVariable SameCoeffecient; if (SourceTerm.FusedConstants.TryGetValue(cst.ConstantValue, out SameCoeffecient)) { SameCoeffecient.SymbolicVariable -= cst.ConstantPower; SourceTerm.FusedConstants[cst.ConstantValue] = SameCoeffecient; } else { // Add Target coefficient symbol to the fused symbols in source, with key as the coefficient number itself. if (cst.ConstantPower != null) { SourceTerm.FusedConstants.Add( cst.ConstantValue, new HybridVariable { NumericalVariable = -1, // power SymbolicVariable = Subtract(Zero, cst.ConstantPower) }); } else { // coeffecient we working with is number only // First Attempt: to try to get the power of this number with base of available coeffecients // if no base produced an integer power value then we add it into fused constants as it is. if (cst.ConstantValue == 1.0) { continue; // ONE doesn't change anything so we bypass it } double?SucceededConstant = null; double ower = 0; foreach (var p in SourceTerm.Constants) { ower = Math.Log(cst.ConstantValue, p.ConstantValue); if (ower == Math.Floor(ower)) { SucceededConstant = p.ConstantValue; break; } } if (SucceededConstant.HasValue) { if (SourceTerm.Coeffecient == SucceededConstant.Value) { SourceTerm._CoeffecientPowerTerm -= new SymbolicVariable(ower.ToString(CultureInfo.InvariantCulture)); } else { var rr = SourceTerm.FusedConstants[SucceededConstant.Value]; rr.SymbolicVariable -= new SymbolicVariable(ower.ToString(CultureInfo.InvariantCulture)); SourceTerm.FusedConstants[SucceededConstant.Value] = rr; } } else { SourceTerm.FusedConstants.Add( cst.ConstantValue, new HybridVariable { NumericalVariable = -1, // power }); } } } } } } }
private static SymbolicVariable ArithExpression(SymbolicExpressionOperator eop, out short skip) { SymbolicVariable left = eop.SymbolicExpression; string op = eop.Operation; SymbolicVariable right = eop.Next.SymbolicExpression; skip = 1; if (op == "|") { int p = (int)right.SymbolPower; string rp = right.Symbol; SymbolicVariable v = left; while (p > 0) { v = v.Differentiate(rp); p--; } return(v); } if (op == "^") { // This will be right associative operator // which means if more than one power appeared like this 3^2^4 then it will be processed like this 3^(2^4) if (eop.Next.Next != null) { if (eop.Next.Operation == "^") { short iskip; var powerResult = SymbolicVariable.SymbolicPower( left , ArithExpression(eop.Next, out iskip) ); skip += iskip; return(powerResult); } else { return(SymbolicVariable.SymbolicPower(left, right)); } } else { return(SymbolicVariable.SymbolicPower(left, right)); } } if (op == "*") { return(SymbolicVariable.Multiply(left, right)); } if (op == "/") { return(SymbolicVariable.Divide(left, right)); } if (op == "+") { return(SymbolicVariable.Add(left, right)); } if (op == "-") { return(SymbolicVariable.Subtract(left, right)); } throw new NotSupportedException("Not Supported Operator '" + op + "'"); }