/// <summary> /// Substitute variable with another variable /// </summary> /// <param name="variable"></param> /// <param name="value"></param> /// <returns></returns> public SymbolicVariable Substitute(string variable, SymbolicVariable value) { var s = this.ToString(); var ss = s.Replace(variable, "(" + value.ToString() + ")"); return(Parse(ss)); }
public override string ToString() { if (SymbolicVariable != null) { return(SymbolicVariable.ToString()); } else { return(NumericalVariable.ToString(CultureInfo.InvariantCulture)); } }
public SymbolicVariable Power(double power) { if (Math.Floor(power) == power) { return(Power((int)power)); } SymbolicVariable p = this.Clone(); if (p.IsOneTerm) { // raise the coeffecient and symbol if (!string.IsNullOrEmpty(p.Symbol)) { p.SymbolPower = power; } p.Coeffecient = Math.Pow(p.Coeffecient, power); } else { if (power == 0.5) { // return sqrt function of the multi term return(new SymbolicVariable("Sqrt(" + p.ToString() + ")")); } else if (power > 0 && power < 1) { // I don't have solution for this now throw new SymbolicException("I don't have solution for this type of power " + p.ToString() + "^ (" + power.ToString() + ")"); } else { // multi term that we can't raise it to the double return(p.RaiseToSymbolicPower(new SymbolicVariable(power.ToString()))); } } return(p); }
/// <summary> /// Factor the expression. /// </summary> /// <param name="sv"></param> /// <returns></returns> public static SymbolicVariable FactorWithCommonFactor(SymbolicVariable sv) { var map = sv.GetCommonFactorsMap(); // get all keys sorted by number of elements var keys = (from mk in map orderby mk.Value.Count descending where mk.Key.Equals(One) == false && mk.Value.Count > 1 && mk.Key.IsCoeffecientOnly == false select mk.Key).ToArray(); if (keys.Length == 0) { return(sv.Clone()); } // ignore the 1 key // imagine a*x+a*y result is a*(x+y) SymbolicVariable result = SymbolicVariable.One.Clone(); var term_key = keys[0]; // the biggest values count as shown above in the query statement var term_indices = map[term_key]; List <SymbolicVariable> Common_Factors_Keys = new List <SymbolicVariable>(); Common_Factors_Keys.Add(term_key); // find the other keys that has the same indices like this key for (int i = 1; i < keys.Length; i++) { var target_indices = map[keys[i]]; if (target_indices.Count == term_indices.Count) { // compare indices toghether foreach (var idc in term_indices) { if (!target_indices.Contains(idc)) { continue; } } // reaching this line indicates that the two arrays contains the same indices // so we save this key as another common factor for the expression Common_Factors_Keys.Add(keys[i]); } if (target_indices.Count < term_indices.Count) { break; // the array is ordered from higher count to low count so there is no point in comparing more results .. break the loop } } //Common_Factors_Keys now contains the factors that I will work on it. SymbolicVariable common_multipliers = SymbolicVariable.Zero.Clone(); SymbolicVariable rest_multipliers = SymbolicVariable.Zero.Clone(); for (int i = 0; i < sv.TermsCount; i++) { if (term_indices.Contains(i)) { // remove the common factor and add the result into the common_multipliers var term = sv[i].Clone(); foreach (SymbolicVariable ke in Common_Factors_Keys) { term = SymbolicVariable.Divide(term, ke); // divide by factor to remove it from the term. /* * if (term.Symbol == ke.Symbol) * { * term.SymbolPower = 0; * AdjustZeroPowerTerms(term); * } * else * { * // remove from the fused symbols * term._FusedSymbols.Remove(ke.ToString()); * } */ } common_multipliers += term; } else { // doesn't contain the variable we want to remove so we store the term into the rest of the expressions to be added at the end of this procedure rest_multipliers += sv[i].Clone(); } } // at last alter the symbolic variable instant so that it contains the new shape foreach (var ke in Common_Factors_Keys) { result = result * ke; } result.FusedSymbols.Add(common_multipliers.ToString(), new HybridVariable { NumericalVariable = 1.0 }); result = result + rest_multipliers; return(result); }