public static Expr Mock2() { var expr1 = new CompositeExpr(WellKnownSym.plus, new Expr[] { new IntegerNumber("16"), new IntegerNumber("9") }); var expr2 = new CompositeExpr(WellKnownSym.power, new Expr[] { new LetterSym('d'), new IntegerNumber("2") }); var compositeExpr = new CompositeExpr(WellKnownSym.equals, new Expr[] { expr2, expr1 }); return(compositeExpr); }
public static Expr Mock3_1() { var expr1 = new CompositeExpr(WellKnownSym.plus, new Expr[] { new IntegerNumber("3"), new IntegerNumber("4") }); var expr2 = new CompositeExpr(WellKnownSym.root, new Expr[] { new IntegerNumber("2"), expr1 }); var expr3 = new CompositeExpr(WellKnownSym.equals, new Expr[] { new LetterSym('d'), expr2 }); return(expr3); }
public static Expr Mock6() { var expr11 = new CompositeExpr(WellKnownSym.divide, new Expr[] { 0.5 }); var expr1 = new CompositeExpr(WellKnownSym.times, new Expr[] { -1, expr11 }); var expr2 = new CompositeExpr(WellKnownSym.equals, new Expr[] { new LetterSym('m'), expr1 }); return(expr2); }
static public Expr genMMA(Expr ep0, ArrayExpr ep1, String op, Parser.ParseResult pr) { if (op == "All") { if (!(ep0 is CompositeExpr)) return ep0; CompositeExpr ce = ep0 as CompositeExpr; if (ce.Head == WellKnownSym.power && ce.Args[1] is WordSym && ce.Args[0] is ArrayExpr) { pr.matrixOperationResult = new CompositeExpr(ce.Args[1], new ArrayExpr((Array)(ce.Args[0] as ArrayExpr).Elts.Clone())); return pr.matrixOperationResult; } int c = ce.Args.Length; Expr[] newExprElts = new Expr[c]; for (int i = 0; i < c; i++) newExprElts[i] = genMMA(ce.Args[i], null, "All", pr); return new CompositeExpr(ce.Head, newExprElts); } Expr newExpr = new CompositeExpr(new WordSym(op), new ArrayExpr((Array)ep1.Elts.Clone())); if (ep0.Equals(ep1) && op == "No Matrix Operation") return ep1; else if (ep0.Equals(ep1) && op != "No Matrix Operation") return newExpr; if (ep0 is CompositeExpr) { CompositeExpr ce = ep0 as CompositeExpr; if (ce.Head == new LetterSym('⇒') || ce.Head == new LetterSym('→')) { if (ce.Args[0].Equals(ep1) || ce.Args[0] is CompositeExpr && (ce.Args[0] as CompositeExpr).Head == WellKnownSym.power && (ce.Args[0] as CompositeExpr).Args[0].Equals(ep1)) return op != "No Matrix Operation" ? newExpr : ep1; else return genMMA(ce.Args[0], ep1, op, null); } else if (ce.Head == WellKnownSym.power && ce.Args[0] is ArrayExpr) { if (ce.Args[0].Equals(ep1)) return op != "No Matrix Operation" ? new CompositeExpr(new WordSym(op), ce.Args[0]) : ce.Args[0]; else if (!(ce.Args[1] is WordSym)) return ce; else return (ce.Args[1] as WordSym).Word != "No Matrix Operation" ? new CompositeExpr(ce.Args[1], ce.Args[0]) : ce.Args[0]; } int c = (ep0 as CompositeExpr).Args.Length; Expr[] newExprElts = new Expr[c]; for (int i = 0; i < c; i++) newExprElts[i] = genMMA((ep0 as CompositeExpr).Args[i], ep1, op, null); return new CompositeExpr((ep0 as CompositeExpr).Head, newExprElts); } return ep0; }
public static Expr ToExpr(this PointSymbol ps) { var xExpr = ToCoord(ps.SymXCoordinate); var yExpr = ToCoord(ps.SymYCoordinate); if (ps.Shape.Label == null) { //var comp = new CompositeExpr(new WordSym("comma"), new Expr[] { }); var cc = new CompositeExpr(new WordSym(""), new Expr[] { xExpr, yExpr }); return(cc); } else { var comp = new CompositeExpr(new WordSym(ps.Shape.Label), new Expr[] { xExpr, yExpr }); return(comp); } //return Text.Convert(form); }
public static Expr Mock4() { //(y-3)/(4-2) = 5 var expr0 = new CompositeExpr(WellKnownSym.minus, new Expr[] { new IntegerNumber("3") }); var expr1 = new CompositeExpr(WellKnownSym.plus, new Expr[] { new LetterSym('y'), expr0 }); var expr2 = new CompositeExpr(WellKnownSym.minus, new Expr[] { new IntegerNumber("2") }); var expr4 = new CompositeExpr(WellKnownSym.plus, new Expr[] { new IntegerNumber("4"), expr2 }); var expr5 = new CompositeExpr(WellKnownSym.divide, new Expr[] { expr4 }); var expr6 = new CompositeExpr(WellKnownSym.times, new Expr[] { expr1, expr5 }); var expr7 = new CompositeExpr(WellKnownSym.equals, new Expr[] { expr6, new IntegerNumber("5") }); return(expr7); }
static public void UpdateMath(IEnumerable <Parser.ParseResult> results) { foreach (Parser.ParseResult pr in results) { if (pr != null && pr.expr is CompositeExpr && !pr.parseError) { CompositeExpr ce = pr.expr as CompositeExpr; # if false if (/*(pr.parseError && ce.Head != WellKnownSym.equals && ce.Args.Length != 1) ||*/ (ce.Head == WellKnownSym.equals && (ce.Args.Length != 2 || ce.Args[0] is Parse2.SyntaxErrorExpr || !(ce.Args[1] is Parse2.SyntaxErrorExpr)))) { if (ce.Args.Length > 1) { Expr theMath = SubstMathVars(results, ce.Args[1]); pr.isNum = (Engine.Current is BuiltInEngine) ? (Engine.Current as BuiltInEngine).IsNum(theMath) : false; } continue; } #endif if (ce != null && (/*ce.Head == WellKnownSym.equals || */ ce.Head == new LetterSym(Unicode.R.RIGHTWARDS_DOUBLE_ARROW) || ce.Head == new LetterSym('→'))) { Expr theMath = SubstMathVars(results, ce.Args[0]); //pr.finalSimp = ce.Head == new LetterSym('→') ? Engine.Simplify(theMath.Clone()) : EvaluateExprFunc(theMath.Clone(), constants, true); pr.finalSimp = ce.Head == new LetterSym('→') ? Engine.Simplify(genMMA(theMath.Clone(), null, "All", pr)) : EvaluateExprFunc(genMMA(theMath.Clone(), null, "All", pr), constants, true); if (pr.matrixOperationResult != null) { pr.matrixOperationResult = pr.finalSimp; } pr.isNum = (Engine.Current is BuiltInEngine) ? (Engine.Current as BuiltInEngine).IsNum(pr.finalSimp) : false; } else { //Expr theMath = SubstMathVars(results, pr.expr); //pr.isNum = (Engine.Current is BuiltInEngine) ? (Engine.Current as BuiltInEngine).IsNum(theMath) : false; } }
public void Test_5() { var expr0 = new CompositeExpr(WellKnownSym.times, new Expr[] { new LetterSym('m'), new IntegerNumber(1) }); var expr11 = new CompositeExpr(WellKnownSym.divide, new Expr[] { 0.5 }); var expr1 = new CompositeExpr(WellKnownSym.times, new Expr[] { -1, expr11 }); var expr2 = new CompositeExpr(WellKnownSym.equals, new Expr[] { expr0, expr1 }); object obj; bool result = expr0.IsExpression(out obj); Assert.True(result); result = expr2.IsEquationLabel(out obj); Assert.True(result); }
public void Test_numerics_7() { var expr1 = new CompositeExpr(WellKnownSym.plus, new Expr[] { new IntegerNumber("16"), new IntegerNumber("9") }); var expr2 = new CompositeExpr(WellKnownSym.root, new Expr[] { new IntegerNumber("2"), expr1 }); var expr3 = new CompositeExpr(WellKnownSym.equals, new Expr[] { new LetterSym('d'), expr2 }); object obj; bool result = expr2.IsExpression(out obj); Assert.True(result); var gTerm = obj as Term; Assert.NotNull(gTerm); result = expr3.IsEquation(out obj); Assert.True(result); var gEquation = obj as Equation; Assert.NotNull(gEquation); }
private Expr CanonicalizeTimes(CompositeExpr e) { Hashtable bases = new Hashtable(); Hashtable baseCounts = new Hashtable(); bool degrees = false; List<Expr> arrays = new List<Expr>(); foreach (Expr term in e.Args) { if (term == _degree) { degrees = true; continue; } if (IsNum(term)) { if (!baseCounts.Contains("unitless")) baseCounts.Add("unitless", Num(term)); else baseCounts["unitless"] = Num(Mult((Expr)baseCounts["unitless"], term)); } else if (term is ArrayExpr) { arrays.Add(term); } else switch (head(term)) { case WKSID.power: Expr baseTerm = Ag(term, 0); Expr baseExp = Ag(term, 1); if (bases.Contains(baseTerm)) { // a^x a^y -> a^(x+y) Expr pow = (Expr)bases[baseTerm]; bases[baseTerm] = Canonicalize(Plus(pow, baseExp)); } else { bases.Add(baseTerm, baseExp); baseCounts.Add(baseTerm, (Expr)1); } break; default: if (!bases.Contains(term)) { bases.Add(term, (Expr)1); // a^1 baseCounts.Add(term, (Expr)1); // 1 * a } else { // a ^ x * a -> a ^ (x + 1) bases[term] = Canonicalize(Plus((Expr)bases[term], 1)); } break; } } List<Expr> mterms = new List<Expr>(); if (baseCounts.Contains("unitless")) { if ((baseCounts["unitless"] is IntegerNumber)) { BigInt unitless = (baseCounts["unitless"] as IntegerNumber).Num; if (unitless == 0) if (degrees) { arrays.Insert(0, 0); arrays.Insert(1, _degree); return Mult(arrays.ToArray()); } else return 0; if (unitless != 1) mterms.Add((Expr)baseCounts["unitless"]); } else mterms.Add((Expr)baseCounts["unitless"]); } foreach (DictionaryEntry de in bases) { Expr count = (baseCounts[de.Key] as Expr); Expr pow = (de.Value as Expr); Expr t = !(pow is IntegerNumber) || (int)pow != 1 ? Canonicalize(Power((Expr)de.Key, pow)) : (Expr)de.Key; if (count is IntegerNumber && (int)count == 1) count = null; if (t is IntegerNumber && (int)t == 1) t = null; if (t != null && count != null) t = Mult(count, t); else if (t == null) t = count; if (t is ComplexNumber && mterms.Count == 1 && mterms[0] is IntegerNumber) { IntegerNumber rei = (t as ComplexNumber).Re as IntegerNumber; DoubleNumber red = (t as ComplexNumber).Re as DoubleNumber; IntegerNumber iei = (t as ComplexNumber).Im as IntegerNumber; DoubleNumber ied = (t as ComplexNumber).Im as DoubleNumber; IntegerNumber mi = mterms[0] as IntegerNumber; if ((rei != null || red != null) && (ied != null || iei != null)) mterms[0] = new ComplexNumber((RealNumber)(rei != null ? (Expr)(rei.Num * mi.Num) : (Expr)new DoubleNumber(red.Num * (double)mi.Num)), (RealNumber)(iei != null ? (Expr)(iei.Num * mi.Num) : (Expr)new DoubleNumber(ied.Num * (double)mi.Num))); else mterms.Add(t); } else if (t != null) mterms.Add(t); } Expr ret = null; if (mterms.Count == 0) ret = 1; if (mterms.Count == 1) ret = mterms[0]; if (ret != null) { if (degrees || arrays.Count == 0 || ret != 1) { arrays.Insert(0, ret); if (degrees) arrays.Insert(1, _degree); } return MaybeMult(arrays.ToArray()); } ret = Mult(mterms.ToArray()); foreach (Expr term in e.Args) if (head(term) == WKSID.plus) { // distribute addition terms: List<Expr> mults = new List<Expr>(); mults.Add(null); foreach (Expr t in e.Args) if (t != term) mults.Add(t); List<Expr> adds = new List<Expr>(); foreach (Expr t in Args(term)) { mults[0] = t; adds.Add(Canonicalize(Mult(mults.ToArray()))); } Expr ret2 = Canonicalize(Plus(adds.ToArray())); if (Text.InputConvert(ret2).Length < Text.InputConvert(ret).Length) ret = ret2; break; } if (arrays.Count == 0 || ret != 1) arrays.Insert(0, ret); return MaybeMult(arrays.ToArray()); }
public List<Expr> flattenMults(CompositeExpr e) { // flatten out all multiplications List<Expr> termList = new List<Expr>(); if (head(e) != WKSID.times) return null; foreach (Expr term in e.Args) { if (head(term) == WKSID.times) { foreach (Expr t in Args(term)) termList.Add(t); } else if (head(term) == WKSID.power && (head(Ag(term, 0)) == WKSID.times)) { foreach (Expr mterm in Args(Ag(term, 0))) termList.Add(Power(mterm, Ag(term, 1))); } else if (head(term) == WKSID.divide) { if (head(Ag(term, 0)) == WKSID.times) { foreach (Expr t in Args(Ag(term, 0))) termList.Add(Power(t, -1)); } else termList.Add(Power(Ag(term, 0), -1)); } else if (head(term) == WKSID.minus && head(Ag(term, 0)) == WKSID.times) { bool first = true; foreach (Expr t in Args(Ag(term, 0))) if (first) { first = false; if (t is IntegerNumber) termList.Add(-(t as IntegerNumber).Num); else if (t is RationalNumber) termList.Add(-(t as RationalNumber).Num); else if (t is DoubleNumber) termList.Add(-(t as DoubleNumber).Num); else termList.Add(Minus(t)); } else termList.Add(t); } else termList.Add(term); } if (termList.Count > e.Args.Length) return flattenMults(Mult(termList.ToArray())); return termList; }
private Expr _Numericize(CompositeExpr e) { Expr[] args = new Expr[e.Args.Length]; for (int i = 0; i < e.Args.Length; i++) if ((i != 0 || head(e) != WKSID.index) && !(i == 0 && e.Head == WellKnownSym.summation && e.Args.Length > 1)) args[i] = Numericize(e.Args[i]); else args[i] = e.Args[i]; Expr val = Ag(e, 0); if (e.Head is WellKnownSym) { DoubleNumber dn1 = null; DoubleNumber dn2 = null; IntegerNumber in1 = null; IntegerNumber in2 = null; ComplexNumber cn1 = null; ComplexNumber cn2 = null; if (args.Length > 0) { dn1 = args[0] as DoubleNumber; cn1 = args[0] as ComplexNumber; in1 = args[0] as IntegerNumber; } if (args.Length > 1) { dn2 = args[1] as DoubleNumber; cn2 = args[1] as ComplexNumber; in2 = args[1] as IntegerNumber; } double d1 = 0; double d2 = 0; if (in2 != null) d2 = (double)in2.Num; if (in1 != null) d1 = (double)in1.Num; if (dn2 != null) d2 = dn2.Num; if (dn1 != null) d1 = dn1.Num; bool num1 = dn1 != null || in1 != null; bool num2 = dn2 != null || in2 != null; WKSID id = ((WellKnownSym)e.Head).ID; switch (id) { case WKSID.im: Trace.Assert(args.Length == 1); if (args[0] is RealNumber) return 0.0; else if (args[0] is ComplexNumber) return ((ComplexNumber)args[0]).Im; break; case WKSID.magnitude: if (in1 != null) return in1.Num.abs(); if (dn1 != null) return Math.Abs(dn1.Num); if (cn1 != null) return Numericize(new CompositeExpr(WellKnownSym.root, 2, new CompositeExpr(WellKnownSym.plus, new CompositeExpr(WellKnownSym.power, cn1.Re, 2), new CompositeExpr(WellKnownSym.power, cn1.Im, 2)))); break; case WKSID.minus: Trace.Assert(args.Length == 1); if (num1) if (in1 != null) return new IntegerNumber(-in1.Num); else return -d1; else if (args[0] is ComplexNumber) return NMinus((ComplexNumber)args[0]); else if (args[0] is ArrayExpr) { ArrayExpr ae = new ArrayExpr((Array)((ArrayExpr)args[0]).Elts.Clone()); foreach (int[] i in ae.Indices) ae[i] = Numericize(Minus(ae[i])); if (!args[0].Annotations.Contains("Force Parentheses") || !args[0].Annotations["Force Parentheses"].Equals(0)) ae.Annotations["Force Parentheses"] = 1; return ae; } break; case WKSID.plus: { Trace.Assert(args.Length > 0); if (args.Length == 1) { return args[0]; } if (Array.TrueForAll(args, delegate(Expr a) { return a is ArrayExpr; })) { ArrayExpr[] aes = Array.ConvertAll<Expr, ArrayExpr>(args, delegate(Expr a) { return (ArrayExpr)a; }); int[] dims = aes[0].Dims; bool isok = true; for (int i = 1; isok && i < args.Length; i++) { int[] dd = aes[i].Dims; if (dd.Length != dims.Length) isok = false; for (int j = 0; isok && j < dims.Length; j++) if (dims[j] != dd[j]) isok = false; } if (isok) { ArrayExpr newae = new ArrayExpr((Array)aes[0].Elts.Clone()); foreach (int[] ix in newae.Indices) { newae[ix] = Numericize(Plus(Array.ConvertAll<ArrayExpr, Expr>(aes, delegate(ArrayExpr ae) { return ae[ix]; }))); } newae.Annotations["Force Parentheses"] = 1; return newae; } } List<Expr> leftover = new List<Expr>(); double rsum = 0; double isum = 0; IntegerNumber risum = 0; bool anyd = false, anyc = false, anyi = false; foreach (Expr p in args) { DoubleNumber dn = p as DoubleNumber; IntegerNumber inn = p as IntegerNumber; ComplexNumber cn = p as ComplexNumber; if (dn != null) { if (anyi) { rsum = dn.Num + (double)risum.Num; anyi = false; } else rsum += dn.Num; anyd = true; } else if (inn != null) { if (anyd) rsum += (double)inn.Num; else { risum = risum.Num + inn.Num; anyi = true; } } else if (cn != null) { DoubleNumber red = cn.Re as DoubleNumber; DoubleNumber imd = cn.Im as DoubleNumber; if (red != null && imd != null) { if (anyi) rsum = red.Num + (double)risum.Num; else rsum += red.Num; isum += imd.Num; anyd = true; anyc = true; anyi = false; } else leftover.Add(p); } else leftover.Add(p); } Number rn = anyd ? (Number)new DoubleNumber(rsum) : (Number)risum; Number n = anyc ? (Number)new ComplexNumber(rsum, isum) : (Number)rn; if (leftover.Count == 0) return n; else { if (anyd || anyi || anyc) leftover.Add(n); return new CompositeExpr(e.Head, leftover.ToArray()); } } case WKSID.mod: if (args.Length != 2) break; if (in1 != null && in2 != null) return new IntegerNumber(in1.Num % in2.Num); else if (in1 != null && dn2 != null) return Math.IEEERemainder(in1.Num.AsDouble(), dn2.Num); else if (dn1 != null && in2 != null) return Math.IEEERemainder(dn1.Num, in2.Num.AsDouble()); else if (dn1 != null && dn2 != null) return Math.IEEERemainder(dn1.Num, dn2.Num); break; case WKSID.power: if (args.Length < 2) break; Trace.Assert(args.Length == 2); if (num1 && (d1 >= 0 || in2 != null) && num2) { double pow = Math.Pow(d1, d2); return in1 != null && in2 != null && d2 > 0 ? (Expr)new IntegerNumber((int)pow) : (Expr)new DoubleNumber(pow); } else { if (num1) cn1 = new ComplexNumber(d1, 0.0); if (num2) cn2 = new ComplexNumber(d2, 0.0); if (cn1 != null && cn2 != null) return NPower(cn1, cn2); } if (num2 && d2 == 0) return new DoubleNumber(1); if (num2 && d2 == 1) return args[0]; if (args[0] is ArrayExpr && args[1] == new LetterSym('T')) { // matrix transpose // FIXME: actually, this should probably be turned into a wellknownsym "transpose" by parse2. Issue there is how to know T isn't being // used as a variable? ArrayExpr ae = (ArrayExpr)args[0]; if (ae.Elts.Rank == 1) { Expr[,] n = new Expr[ae.Elts.Length, 1]; for (int i = 0; i < ae.Elts.Length; i++) { n[i, 0] = ae[i]; } ae = new ArrayExpr(n); ae.Annotations["Force Parentheses"] = 1; } else if (ae.Elts.Rank == 2) { int h = ae.Elts.GetLength(0); int w = ae.Elts.GetLength(1); Expr[,] n = new Expr[w, h]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { n[j, i] = ae[i, j]; } } ae = new ArrayExpr(n); ae.Annotations["Force Parentheses"] = 1; return ae; } } break; case WKSID.re: Trace.Assert(args.Length == 1); if (num1) return args[0]; else if (cn1 != null) return cn1.Re; break; case WKSID.times: Trace.Assert(args.Length > 0); if (args.Length == 1) { return args[0]; } else { List<Expr> leftover = new List<Expr>(); int start = 0; while (start < args.Length) { int end; bool isarray = args[start] is ArrayExpr; for (end = start + 1; end < args.Length; end++) { if (isarray != (args[end] is ArrayExpr)) break; } leftover.AddRange(isarray ? NMultiplyArrays(args, start, end) : NMultiplyScalars(args, start, end)); start = end; } if (leftover.Count == 1) { return leftover[0]; } else { leftover = this.NMultipyAll(args, e); if (leftover.Count == 1) return leftover[0]; else return new CompositeExpr(e.Head, leftover.ToArray()); } //original code before matrix scalar computations //if(leftover.Count == 1) return leftover[0]; //else //return new CompositeExpr(e.Head, leftover.ToArray()); } case WKSID.divide: Trace.Assert(args.Length == 1); if (num1) return 1 / d1; else if (args[0] is ComplexNumber) return NReciprocal((ComplexNumber)args[0]); break; case WKSID.ln: Trace.Assert(args.Length == 1); if (num1) { if (d1 >= 0) return Math.Log(d1); return NLog(d1); } else if (args[0] is ComplexNumber) return NLog((ComplexNumber)args[0]); break; case WKSID.log: /* log takes base then value to take the logarithm of */ if (args.Length == 1) { dn2 = dn1; in2 = in1; cn2 = cn1; d2 = d1; num2 = num1; d1 = 10; dn1 = 10; in1 = null; cn1 = null; num1 = true; } if (num1 && num2) { if (d1 >= 0 && num2 && d2 >= 0) return Math.Log(d2, d1); else return double.NaN; } else { if (num1) cn1 = new ComplexNumber(d1, 0.0); if (num2) cn2 = new ComplexNumber(d2, 0.0); if (cn1 != null && cn2 != null) return NTimes(NLog(cn2), NReciprocal(NLog(cn1))); } break; case WKSID.root: /* takes root number (eg 2 for square root), value to take the root of */ Trace.Assert(args.Length == 2); if (num1 && num2 && d2 >= 0) return Math.Pow(d2, 1 / d1); else { if (num1) cn1 = new ComplexNumber(d1, 0.0); if (num2) cn2 = new ComplexNumber(d2, 0.0); if (cn1 != null && cn2 != null) return NPower(cn2, NReciprocal(cn1)); } if (head(args[1]) == WKSID.power) return Numericize(Power(Ag(args[1], 0), Mult(Ag(args[1], 1), Divide(args[0])))); break; case WKSID.index: { bool didnumericize = false; if (!(args[0] is ArrayExpr)) { args[0] = Numericize(args[0]); didnumericize = true; } ArrayExpr aex = null, aix = null; if (!IsArrayIndex(e, ref aex, ref aix)) { if (!didnumericize) args[0] = Numericize(args[0]); break; } int[] ix = ConvertToInd(aix, ExprToInd); if (ix == null) { if (!didnumericize) args[0] = Numericize(args[0]); break; } return Numericize(aex[ix]); } case WKSID.sin: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.sin, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return Math.Sin(d1); else if (cn1 != null) return NSin(cn1); break; case WKSID.cos: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.cos, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return Math.Cos(d1); else if (cn1 != null) return NCos(cn1); break; case WKSID.tan: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.tan, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return Math.Tan(d1); else if (cn1 != null) return NTan(cn1); break; case WKSID.sec: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.sec, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return 1 / Math.Cos(d1); else if (cn1 != null) return NReciprocal(NCos(cn1)); break; case WKSID.csc: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.csc, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return 1 / Math.Sin(d1); else if (args[0] is ComplexNumber) return NReciprocal(NSin(cn1)); break; case WKSID.cot: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.cot, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return 1 / Math.Tan(d1); if (cn1 != null) return NReciprocal(NTan(cn1)); break; case WKSID.asin: Trace.Assert(args.Length == 1); if (num1) return Math.Asin(d1); if (cn1 != null) return NArcSin(cn1); break; case WKSID.acos: Trace.Assert(args.Length == 1); if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Numericize(new CompositeExpr(WellKnownSym.acos, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (num1) return Math.Acos(d1); if (cn1 != null) return NArcCos(cn1); break; case WKSID.atan: Trace.Assert(args.Length == 1); if (num1) return Math.Atan(d1); if (cn1 != null) return NArcTan(cn1); break; case WKSID.asec: Trace.Assert(args.Length == 1); if (num1) return Math.Acos(1 / d1); if (cn1 != null) return NArcCos(NReciprocal(cn1)); break; case WKSID.acsc: Trace.Assert(args.Length == 1); if (num1) return Math.Asin(1 / d1); if (cn1 != null) return NArcSin(NReciprocal(cn1)); break; case WKSID.acot: Trace.Assert(args.Length == 1); if (num1) return Math.Atan(1 / d1); if (cn1 != null) return NArcTan(NReciprocal(cn1)); break; case WKSID.sinh: Trace.Assert(args.Length == 1); if (num1) return Math.Sinh(d1); if (cn1 != null) return NSinH(cn1); break; case WKSID.cosh: Trace.Assert(args.Length == 1); if (num1) return Math.Cosh(d1); if (cn1 != null) return NCosH(cn1); break; case WKSID.tanh: Trace.Assert(args.Length == 1); if (num1) return Math.Tanh(d1); if (cn1 != null) return NTanH(cn1); break; case WKSID.sech: Trace.Assert(args.Length == 1); if (num1) return 1 / Math.Cosh(d1); if (cn1 != null) return NReciprocal(NCosH(cn1)); break; case WKSID.csch: Trace.Assert(args.Length == 1); if (num1) return 1 / Math.Sinh(d1); if (cn1 != null) return NReciprocal(NSinH(cn1)); break; case WKSID.coth: Trace.Assert(args.Length == 1); if (num1) return 1 / Math.Tanh(d1); if (cn1 != null) return NReciprocal(NTanH(cn1)); break; case WKSID.asinh: case WKSID.acosh: case WKSID.atanh: case WKSID.asech: case WKSID.acsch: case WKSID.acoth: /* C# library doesn't contain these functions */ break; case WKSID.factorial: Trace.Assert(args.Length == 1); if (in1 != null && in1.Num >= 0) return Factorial(in1.Num); break; case WKSID.summation: Trace.Assert(args.Length > 0 && args.Length < 4); if (args.Length == 3 && num2 && e.Args[0] is CompositeExpr && !(e.Args[2] is NullExpr)) { CompositeExpr ce = e.Args[0] as CompositeExpr; Expr key = new NullExpr(); d1 = 0; if (ce != null && ce.Head == WellKnownSym.equals && (ce.Args[0] is LetterSym || ce.Args[0] is WellKnownSym)) { key = ce.Args[0].Clone(); Expr start = Numericize(ce.Args[1]); IntegerNumber sinn = start as IntegerNumber; DoubleNumber sdn = start as DoubleNumber; d1 = (sinn != null) ? (double)sinn.Num : sdn != null ? sdn.Num : double.NaN; } Expr res = new IntegerNumber(0); for (int d = (int)d1; d1 <= d2 && d <= (int)d2; d++) { Expr newB = (Expr)e.Args[2].Clone(); newB = Numericize(_Substitute(newB, key, d)); res = Plus(res, newB); res = Numericize(_Simplify(res)); } return res; } break; } } return new CompositeExpr(Numericize(e.Head), args); }
private Expr _Substitute(CompositeExpr e) { Expr[] args = new Expr[e.Args.Length]; for (int i = 0; i < e.Args.Length; i++) args[i] = Substitute(e.Args[i]); return new CompositeExpr(Substitute(e.Head), args); }
private List<Expr> NMultipyAll(Expr[] leftover, CompositeExpr e) { List<Expr> result = new List<Expr>(); int start = 0; int end = 1; while (end < leftover.Length) { if (leftover[start] is ArrayExpr && leftover[end] is ArrayExpr) { List<Expr> product = new List<Expr>(); Expr[] args = new Expr[2]; args[0] = leftover[start]; args[1] = leftover[end]; product = this.NMultiplyArrays(args, 0, 2); if (product.Count == 1) { leftover[start] = product[0]; if (end == leftover.Length - 1) result.Insert(0, leftover[start]); } else { if (end != leftover.Length - 1 || result.Count == 0) result.AddRange(product); else result.Add(leftover[end]); start = end + 1; if (start == leftover.Length - 1) result.Add(leftover[start]); end++; } } else if (leftover[start] is ArrayExpr != true && leftover[end] is ArrayExpr != true) { List<Expr> product = new List<Expr>(); Expr[] args = new Expr[2]; args[0] = leftover[start]; args[1] = leftover[end]; product = this.NMultiplyScalars(args, 0, 2); if (product.Count == 1) { leftover[start] = product[0]; } else { leftover[start] = new CompositeExpr(e.Head, product.ToArray()); } if (end == leftover.Length - 1) result.Insert(0, leftover[start]); if (product.Count == 2) result = product; else { leftover[start] = product[0]; if (end == leftover.Length - 1) result.Insert(0, leftover[start]); } } else { List<Expr> product = new List<Expr>(); product = this.NMultiplyScalarMatrix(leftover, start, end, e); leftover[start] = product[0]; if (end == leftover.Length - 1) result.Insert(0, leftover[start]); } end++; } return result; }
private Expr _Canonicalize(CompositeExpr e) { if (IsNum(e)) return Num(e); List<Expr> termList = new List<Expr>(); if (head(e) == WKSID.times) termList = flattenMults(e as CompositeExpr); // don't canonicalize args to preserve factors else if (head(e) == WKSID.plus) { bool recurse = false; foreach (Expr term in e.Args) { // flatten out all additions if (head(term) == WKSID.plus) { foreach (Expr t in Args(term)) { termList.Add(t); recurse = true; } } else { Expr canon = Canonicalize(term); if (canon != term) recurse = true; termList.Add(canon); } } if (recurse) return Canonicalize(Plus(termList.ToArray())); } else foreach (Expr term in e.Args) termList.Add(Canonicalize(term)); Expr[] args = termList.ToArray(); switch (head(e)) { case WKSID.times: Expr r = CanonicalizeTimes(Mult(args)); if (head(r) == WKSID.times) { // after simplifying, we now want to canonicalize any remaining terms to see if we can simplify further termList.Clear(); foreach (Expr term in Args(r)) termList.Add(Canonicalize(term)); r = CanonicalizeTimes(Mult(termList.ToArray())); } else r = Canonicalize(r); return r; case WKSID.minus: if (head(args[0]) == WKSID.minus) return args[0]; // convert - - (expr) to (expr) if (args[0] is IntegerNumber && (int)args[0] < 0) return -(int)args[0]; return Canonicalize(Mult((Expr)(-1), args[0])); case WKSID.divide: if (head(args[0]) == WKSID.power) return Power(Ag(args[0], 0), Canonicalize(Mult(Ag(args[0], 1), -1))); else return Power(args[0], -1); case WKSID.power: if (args[0] == WellKnownSym.i) { if (IsNum(args[1])) { Expr n = Num(args[1]); if (n is IntegerNumber) { if ((int)((n as IntegerNumber).Num + 2) / 4.0 == (int)((n as IntegerNumber).Num + 2) / 4) return -1; if ((int)((n as IntegerNumber).Num + 1) / 4.0 == (int)((n as IntegerNumber).Num + 1) / 4) return new ComplexNumber(0, new IntegerNumber(-1)); if ((int)(n as IntegerNumber).Num / 4.0 == (int)(n as IntegerNumber).Num / 4) return 1; return new ComplexNumber(0, new IntegerNumber(1)); } } } if (args[0] == WellKnownSym.e && head(args[1]) == WKSID.ln) return Ag(args[1], 0); if (head(args[0]) == WKSID.power && ( (args[1] is IntegerNumber) || (head(Ag(args[0], 1)) == WKSID.divide && head(args[1]) == WKSID.divide))) // can't return Canonicalize(Power(Ag(args[0], 0), Canonicalize(Mult(Ag(args[0], 1), args[1])))); IntegerNumber qex1 = null; if (IsNum(args[1])) { // simplify ^0 && ^ Expr qex = Num(args[1]); if (qex is IntegerNumber) { qex1 = (qex as IntegerNumber); if (qex1.Num == 1) return args[0]; else if (qex1.Num == 0) return 1; } } IntegerNumber qex0 = null; if (IsNum(args[0])) { // simplify 0^ && 1^ Expr qex = Num(args[0]); if (qex is IntegerNumber) { qex0 = (qex as IntegerNumber); if (qex0.Num == 0) return 0; if (qex0.Num == 1) return 1; } } if (qex0 != null && qex1 != null && qex1.Num >= 0) return new BigInt(FSBigInt.Pow(qex0.Num.Num, (int)qex1.Num.Num)); if (head(args[0]) == WKSID.times) { // expand (ab)^x to a^x b^x List<Expr> tterms = new List<Expr>(); foreach (Expr t in Args(args[0])) tterms.Add(Canonicalize(Power(t, args[1]))); return Canonicalize(Mult(tterms.ToArray())); } return new CompositeExpr(WellKnownSym.power, args); case WKSID.root: return Canonicalize(Power(args[1], Divide(args[0]))); case WKSID.cos: { Expr val = args[0]; if (head(val) == WKSID.times && Ag(val, 1) == _degree && Ag(val, 0) is IntegerNumber) { int n = (int)Ag(val, 0); if ((double)(n - 90) / 180 == (n - 90) / 180) return 0; if ((double)n / 360 == n / 360) return 1; if ((double)(n - 180) / 360 == (n - 180) / 360) return -1; if ((double)(n - 60) / 360 == (n - 60) / 360) return Mult(1, Divide(2)); if ((double)(n - 120) / 360 == (n - 120) / 360) return Mult(-1, Divide(2)); if ((double)(n - 240) / 360 == (n - 240) / 360) return Mult(-1, Divide(2)); if ((double)(n - 300) / 360 == (n - 300) / 360) return Mult(1, Divide(2)); } if (val == WellKnownSym.pi) // cos(pi) -> -1 return -1; if (val == Mult(Divide(2), WellKnownSym.pi)) // cos(pi/2) -> 0 return 0; if (head(val) == WKSID.times && Ag(val, 1) == WellKnownSym.pi) { // cos(x * pi) ... Expr m = Ag(val, 0); int mval = (int)m; if (m is IntegerNumber) // cos(int * pi) ... if (mval / 2.0 == mval / 2) // cos(evenInt *pi)-> 1 return 1; else return -1; // cos(oddInt *pi) -> -1 if (head(m) == WKSID.times && (Ag(m, 0) is IntegerNumber) && Ag(m, 1) == Divide(2)) { // cos(int *pi / 2) -> 0 return 0; } if (head(m) == WKSID.times && (Ag(m, 0) is IntegerNumber) && Ag(m, 1) == Divide(3)) { // sin(int *pi / 2) ... int n = (int)Ag(m, 0); if ((n - 1) / 3.0 == (n - 1) / 3 || ((n - 5) / 3.0 == (n - 5) / 3)) return Mult(1, Divide(2)); if ((n - 2) / 3.0 == (n - 2) / 3 || ((n - 4) / 3.0 == (n - 4) / 3)) return Mult(-1, Divide(2)); } } break; } case WKSID.ln: { if (args[0] == WellKnownSym.e) return 1; break; } case WKSID.tan: { Expr val = args[0]; if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Canonicalize(new CompositeExpr(WellKnownSym.tan, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); break; } case WKSID.index: { Expr[] canoned = Array.ConvertAll<Expr, Expr>(args, Canonicalize); return new CompositeExpr(WellKnownSym.index, canoned); } case WKSID.sin: { Expr val = args[0]; if (head(val) == WKSID.times && Ag(val, 1) == _degree && Ag(val, 0) is IntegerNumber) { int n = (int)Ag(val, 0); if ((double)n / 180 == n / 180) return 0; if ((double)(n - 90) / 360 == (n - 90) / 360) return 1; if ((double)(n + 90) / 360 == (n + 90) / 360) return -1; if ((double)(n - 30) / 360 == (n - 30) / 360) return Mult(1, Divide(2)); if ((double)(n - 150) / 360 == (n - 150) / 360) return Mult(1, Divide(2)); if ((double)(n - 210) / 360 == (n - 210) / 360) return Mult(-1, Divide(2)); if ((double)(n - 330) / 360 == (n - 330) / 360) return Mult(-1, Divide(2)); } if (head(val) == WKSID.times && Ag(val, 1) == _degree) return Canonicalize(new CompositeExpr(WellKnownSym.sin, Mult(WellKnownSym.pi, Num(Mult(Ag(val, 0), Divide(180)))))); if (val == WellKnownSym.pi) //sin(pi) -> 0 return 0; if (val == Mult(Divide(2), WellKnownSym.pi)) // sin(pi/2) -> 1 return 1; if (head(val) == WKSID.times && Ag(val, 1) == WellKnownSym.pi) { // sin(x * pi) ... Expr m = Ag(val, 0); if (m is IntegerNumber) // sin(int * pi) -> 0 return 0; if (head(m) == WKSID.times && (Ag(m, 0) is IntegerNumber) && Ag(m, 1) == Divide(2)) { // sin(int *pi / 2) ... int n = (int)Ag(m, 0); if ((n - 1) / 4.0 == (n - 1) / 4) return 1; // sin(1, 5, 9...*pi/2) -> 1 else return -1; // sin(3, 7, 11 ...*pi/2) -> -1 } if (head(m) == WKSID.times && (Ag(m, 0) is IntegerNumber) && Ag(m, 1) == Divide(6)) { // sin(int *pi / 2) ... int n = (int)Ag(m, 0); if ((n - 1) / 6.0 == (n - 1) / 6 || ((n - 5) / 6.0 == (n - 5) / 6)) return Mult(1, Divide(2)); if ((n - 7) / 6.0 == (n - 7) / 6 || ((n - 11) / 6.0 == (n - 11) / 6)) return Mult(-1, Divide(2)); } } break; } case WKSID.plus: Hashtable terms = new Hashtable(); foreach (Expr t in args) { if (t is ComplexNumber) { if (terms.Contains("unitless")) terms["unitless"] = Num(Plus((Expr)terms["unitless"], (t as ComplexNumber).Re)); else terms.Add("unitless", (t as ComplexNumber).Re); } if (IsNum(t)) { if (terms.Contains("unitless")) terms["unitless"] = Num(Plus((Expr)terms["unitless"], t)); else terms.Add("unitless", Num(t)); } else if (t is LetterSym || t is WellKnownSym || head(t) == WKSID.plusminus) { if (terms.Contains(t)) terms[t] = Canonicalize(Plus((Expr)terms[t], 1)); else terms.Add(t, (Expr)1); } else if (t is ArrayExpr) { terms.Add(t, (Expr)1); } else { Expr swVal = t is ComplexNumber ? Mult((t as ComplexNumber).Im, WellKnownSym.i) : t; switch (head(swVal)) { case WKSID.times: List<Expr> syms = new List<Expr>(); List<Expr> nums = new List<Expr>(); foreach (Expr tt in Args(swVal)) if (IsNum(tt)) nums.Add(tt); else syms.Add(tt); Expr baseTerm = syms.Count == 1 ? syms[0] : Mult(syms.ToArray()); Expr baseNum = 1; if (nums.Count == 1) baseNum = nums[0]; else if (nums.Count > 1) baseNum = Num(Mult(nums.ToArray())); if (terms.Contains(baseTerm)) terms[baseTerm] = Canonicalize(Plus((Expr)terms[baseTerm], baseNum)); else terms.Add(baseTerm, baseNum); break; case WKSID.magnitude: case WKSID.factorial: case WKSID.summation: case WKSID.power: if (terms.Contains(swVal)) terms[swVal] = Canonicalize(Plus((Expr)terms[swVal], 1)); else terms.Add(swVal, (Expr)1); break; } } } List<Expr> plTerms = new List<Expr>(); List<Expr> plNumTerms = new List<Expr>(); foreach (DictionaryEntry de in terms) { if (de.Key is string && (string)de.Key == "unitless") { if (!(de.Value is IntegerNumber) || (int)(Expr)de.Value != 0) plNumTerms.Add((Expr)de.Value); } else { Expr baseCount = (de.Value as Expr); if (baseCount is IntegerNumber && (int)baseCount == 0) continue; if (baseCount is IntegerNumber && (int)baseCount == 1) plTerms.Add((Expr)de.Key); else plTerms.Add(Mult((Expr)de.Value, (Expr)de.Key)); } } Expr plNum = null; if (plNumTerms.Count == 1) plNum = plNumTerms[0]; else if (plNumTerms.Count > 1) plNum = Num(Plus(plNumTerms.ToArray())); if (plNum != null) plTerms.Add(plNum); if (plTerms.Count == 0) return 0; else if (plTerms.Count == 1) return plTerms[0]; else return Plus(plTerms.ToArray()); case WKSID.floor: if (args.Length == 1) { if (args[0] is IntegerNumber) return args[0]; else if (args[0] is RationalNumber) { RationalNumber rn = (RationalNumber)args[0]; var divmod = new FSBigInt(); FSBigInt q = FSBigInt.DivRem(rn.Num.Num.Num, rn.Num.Denom.Num, out divmod); FSBigInt qq = q, rr = divmod; return new BigInt(qq - (qq.Sign * rr.Sign == -1 ? FSBigInt.One : FSBigInt.Zero)); } else if (args[0] is DoubleNumber) { DoubleNumber dn = (DoubleNumber)args[0]; return Math.Floor(dn.Num); } } break; case WKSID.magnitude: if (args.Length == 1) { if (args[0] is IntegerNumber) return (args[0] as IntegerNumber).Num.abs(); else if (args[0] is DoubleNumber) return Math.Abs(((DoubleNumber)args[0]).Num); else return new CompositeExpr(WellKnownSym.magnitude, args); } break; case WKSID.ceiling: if (args.Length == 1) { if (args[0] is IntegerNumber) return args[0]; else if (args[0] is RationalNumber) { RationalNumber rn = (RationalNumber)args[0]; FSBigInt divmod = new FSBigInt(); FSBigInt q = FSBigInt.DivRem(rn.Num.Num.Num, rn.Num.Denom.Num, out divmod); FSBigInt qq = q, rr = divmod; return new BigInt(qq + (qq.Sign * rr.Sign == 1 ? FSBigInt.One : FSBigInt.Zero)); } else if (args[0] is DoubleNumber) { DoubleNumber dn = (DoubleNumber)args[0]; return Math.Floor(dn.Num); } } break; } return new CompositeExpr(Canonicalize(e.Head), args); }
static public Expr genMMA(Expr ep0, ArrayExpr ep1, String op, Parser.ParseResult pr) { if (op == "All") { if (!(ep0 is CompositeExpr)) { return(ep0); } CompositeExpr ce = ep0 as CompositeExpr; if (ce.Head == WellKnownSym.power && ce.Args[1] is WordSym && ce.Args[0] is ArrayExpr) { pr.matrixOperationResult = new CompositeExpr(ce.Args[1], new ArrayExpr((Array)(ce.Args[0] as ArrayExpr).Elts.Clone())); return(pr.matrixOperationResult); } int c = ce.Args.Length; Expr[] newExprElts = new Expr[c]; for (int i = 0; i < c; i++) { newExprElts[i] = genMMA(ce.Args[i], null, "All", pr); } return(new CompositeExpr(ce.Head, newExprElts)); } Expr newExpr = new CompositeExpr(new WordSym(op), new ArrayExpr((Array)ep1.Elts.Clone())); if (ep0.Equals(ep1) && op == "No Matrix Operation") { return(ep1); } else if (ep0.Equals(ep1) && op != "No Matrix Operation") { return(newExpr); } if (ep0 is CompositeExpr) { CompositeExpr ce = ep0 as CompositeExpr; if (ce.Head == new LetterSym('⇒') || ce.Head == new LetterSym('→')) { if (ce.Args[0].Equals(ep1) || ce.Args[0] is CompositeExpr && (ce.Args[0] as CompositeExpr).Head == WellKnownSym.power && (ce.Args[0] as CompositeExpr).Args[0].Equals(ep1)) { return(op != "No Matrix Operation" ? newExpr : ep1); } else { return(genMMA(ce.Args[0], ep1, op, null)); } } else if (ce.Head == WellKnownSym.power && ce.Args[0] is ArrayExpr) { if (ce.Args[0].Equals(ep1)) { return(op != "No Matrix Operation" ? new CompositeExpr(new WordSym(op), ce.Args[0]) : ce.Args[0]); } else if (!(ce.Args[1] is WordSym)) { return(ce); } else { return((ce.Args[1] as WordSym).Word != "No Matrix Operation" ? new CompositeExpr(ce.Args[1], ce.Args[0]) : ce.Args[0]); } } int c = (ep0 as CompositeExpr).Args.Length; Expr[] newExprElts = new Expr[c]; for (int i = 0; i < c; i++) { newExprElts[i] = genMMA((ep0 as CompositeExpr).Args[i], ep1, op, null); } return(new CompositeExpr((ep0 as CompositeExpr).Head, newExprElts)); } return(ep0); }
private List<Expr> NMultiplyScalarMatrix(Expr[] leftover, int start, int end, CompositeExpr e) { Expr[,] curmat = null; Expr[] args = new Expr[2]; List<Expr> product = new List<Expr>(); List<Expr> result = new List<Expr>(); if (leftover[start] is ArrayExpr) { ArrayExpr array = (ArrayExpr)leftover[start]; curmat = (Expr[,])array.Elts; args[0] = leftover[end]; } else if (leftover[end] is ArrayExpr) { ArrayExpr array = (ArrayExpr)leftover[end]; curmat = (Expr[,])array.Elts; args[0] = leftover[start]; } int x = curmat.GetUpperBound(0); int y = curmat.GetUpperBound(1); for (int i = 0; i <= x; i++) { for (int j = 0; j <= y; j++) { args[1] = curmat[i, j]; product = this.NMultiplyScalars(args, 0, 2); if (product.Count == 1) { curmat[i, j] = product[0]; } else { curmat[i, j] = new CompositeExpr(e.Head, product.ToArray()); } } } if (curmat != null) result.Add(TempHackNewAE(curmat)); return result; }
public void Test_numerics_8() { var expr1 = new CompositeExpr(WellKnownSym.divide, new Expr[] { new DoubleNumber(0.5) }); var expr2 = new CompositeExpr(WellKnownSym.times, new Expr[] { -1, expr1 }); object obj; bool result = expr2.IsExpression(out obj); Assert.True(result); }
private void FilterOneAndZero(ref Expr expr, ref int output) { if (expr == null) { return; } if (output == 0 || output == 1) { return; } if (expr is starPadSDK.MathExpr.LetterSym || expr is starPadSDK.MathExpr.IntegerNumber) { return; } else if (expr is starPadSDK.MathExpr.CompositeExpr) { starPadSDK.MathExpr.CompositeExpr compositeExpr = expr as starPadSDK.MathExpr.CompositeExpr; if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.equals) { FilterOneAndZero(ref compositeExpr.Args[1], ref output); } for (int i = 0; i < compositeExpr.Args.Length; i++) { if (compositeExpr.Args[i] is starPadSDK.MathExpr.IntegerNumber) { starPadSDK.MathExpr.IntegerNumber number = compositeExpr.Args[i] as starPadSDK.MathExpr.IntegerNumber; if (number.Num.IsOne) { if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.plus) { //OR output = 1; return; } else if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.times) { //AND if (compositeExpr.Args.Length > 2) { Expr[] myArgs = new Expr[compositeExpr.Args.Length - 1]; Array.Copy(compositeExpr.Args, 0, myArgs, 0, i); Array.Copy(compositeExpr.Args, i + 1, myArgs, i, compositeExpr.Args.Length - i - 1); CompositeExpr notExpr = new CompositeExpr(starPadSDK.MathExpr.WellKnownSym.times, myArgs); expr = notExpr; } else if (compositeExpr.Args.Length == 2) { if (i == 0) { expr = compositeExpr.Args[1]; } else { expr = compositeExpr.Args[0]; } } output = 2; } else if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.xorGate) { //XOR Expr[] myArgs = new Expr[compositeExpr.Args.Length -1]; int t = 0; for(int j =0; j< compositeExpr.Args.Length; j++) { if(compositeExpr.Args[j] != compositeExpr.Args[i]) { myArgs[t++] = compositeExpr.Args[j]; } } CompositeExpr notExpr = new CompositeExpr(starPadSDK.MathExpr.WellKnownSym.power, myArgs); expr = notExpr; output = 2; } } else if (number.Num.IsZero) { if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.plus) { //OR if (compositeExpr.Args.Length > 2) { Expr[] myArgs = new Expr[compositeExpr.Args.Length - 1]; Array.Copy(compositeExpr.Args, 0, myArgs, 0, i); Array.Copy(compositeExpr.Args, i + 1, myArgs, i, compositeExpr.Args.Length - i - 1); CompositeExpr notExpr = new CompositeExpr(starPadSDK.MathExpr.WellKnownSym.plus, myArgs); expr = notExpr; } else if (compositeExpr.Args.Length == 2) { if (i == 0) { expr = compositeExpr.Args[1]; } else { expr = compositeExpr.Args[0]; } } output = 2; } else if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.times) { //AND output = 0; return; } else if (compositeExpr.Head == starPadSDK.MathExpr.WellKnownSym.xorGate) { //XOR if (compositeExpr.Args.Length > 2) { Expr[] myArgs = new Expr[compositeExpr.Args.Length - 1]; Array.Copy(compositeExpr.Args, 0, myArgs, 0, i); Array.Copy(compositeExpr.Args, i + 1, myArgs, i, compositeExpr.Args.Length - i - 1); CompositeExpr notExpr = new CompositeExpr(starPadSDK.MathExpr.WellKnownSym.xorGate, myArgs); expr = notExpr; } else if (compositeExpr.Args.Length == 2) { if (i == 0) { expr = compositeExpr.Args[1]; } else { expr = compositeExpr.Args[0]; } } output = 2; } } } else { FilterOneAndZero(ref compositeExpr.Args[i], ref output); } } } }
private static Expr Generate(Term term) { if (term.Op.Method.Name.Equals("Add")) { var head = WellKnownSym.plus; var lst = term.Args as List<object>; Debug.Assert(lst != null); var exprLst = new List<Expr>(); foreach (var obj in lst) { exprLst.Add(Generate(obj)); } return new CompositeExpr(head, exprLst.ToArray()); } else if (term.Op.Method.Name.Equals("Subtract")) { var head = WellKnownSym.plus; var lst = term.Args as List<object>; Debug.Assert(lst != null); var exprLst = new List<Expr>(); exprLst.Add(Generate(lst[0])); for (int i = 1; i < lst.Count; i++) { var tempExpr = Generate(lst[i]); var compExpr = new CompositeExpr(WellKnownSym.minus, tempExpr); exprLst.Add(compExpr); } return new CompositeExpr(head, exprLst.ToArray()); } else if (term.Op.Method.Name.Equals("Multiply")) { var head = WellKnownSym.times; var lst = term.Args as List<object>; Debug.Assert(lst != null); var exprLst = new List<Expr>(); foreach (var obj in lst) { exprLst.Add(Generate(obj)); } return new CompositeExpr(head, exprLst.ToArray()); } if (term.Op.Method.Name.Equals("Divide")) { var head = WellKnownSym.times; var lst = term.Args as List<object>; Debug.Assert(lst != null); var exprLst = new List<Expr>(); exprLst.Add(Generate(lst[0])); for (int i = 1; i < lst.Count; i++) { var tempExpr = Generate(lst[i]); var compExpr = new CompositeExpr(WellKnownSym.divide, tempExpr); exprLst.Add(compExpr); } return new CompositeExpr(head, exprLst.ToArray()); } if (term.Op.Method.Name.Equals("Power")) { var head = WellKnownSym.power; var lst = term.Args as List<object>; Debug.Assert(lst != null); var exprLst = new List<Expr>(); foreach (var obj in lst) { exprLst.Add(Generate(obj)); } return new CompositeExpr(head, exprLst.ToArray()); } //TODO return null; }
public static Expr ToExpr(this PointSymbol ps) { var xExpr = ToCoord(ps.SymXCoordinate); var yExpr = ToCoord(ps.SymYCoordinate); if (ps.Shape.Label == null) { //var comp = new CompositeExpr(new WordSym("comma"), new Expr[] { }); var cc = new CompositeExpr(new WordSym(""), new Expr[] { xExpr, yExpr }); return cc; } else { var comp = new CompositeExpr(new WordSym(ps.Shape.Label), new Expr[] { xExpr, yExpr }); return comp; } //return Text.Convert(form); }
private static Expr Generate(Term term) { if (term.Op.Method.Name.Equals("Add")) { var head = WellKnownSym.plus; var lst = term.Args as List <object>; Debug.Assert(lst != null); var exprLst = new List <Expr>(); foreach (var obj in lst) { exprLst.Add(Generate(obj)); } return(new CompositeExpr(head, exprLst.ToArray())); } else if (term.Op.Method.Name.Equals("Subtract")) { var head = WellKnownSym.plus; var lst = term.Args as List <object>; Debug.Assert(lst != null); var exprLst = new List <Expr>(); exprLst.Add(Generate(lst[0])); for (int i = 1; i < lst.Count; i++) { var tempExpr = Generate(lst[i]); var compExpr = new CompositeExpr(WellKnownSym.minus, tempExpr); exprLst.Add(compExpr); } return(new CompositeExpr(head, exprLst.ToArray())); } else if (term.Op.Method.Name.Equals("Multiply")) { var head = WellKnownSym.times; var lst = term.Args as List <object>; Debug.Assert(lst != null); var exprLst = new List <Expr>(); foreach (var obj in lst) { exprLst.Add(Generate(obj)); } return(new CompositeExpr(head, exprLst.ToArray())); } if (term.Op.Method.Name.Equals("Divide")) { var head = WellKnownSym.times; var lst = term.Args as List <object>; Debug.Assert(lst != null); var exprLst = new List <Expr>(); exprLst.Add(Generate(lst[0])); for (int i = 1; i < lst.Count; i++) { var tempExpr = Generate(lst[i]); var compExpr = new CompositeExpr(WellKnownSym.divide, tempExpr); exprLst.Add(compExpr); } return(new CompositeExpr(head, exprLst.ToArray())); } if (term.Op.Method.Name.Equals("Power")) { var head = WellKnownSym.power; var lst = term.Args as List <object>; Debug.Assert(lst != null); var exprLst = new List <Expr>(); foreach (var obj in lst) { exprLst.Add(Generate(obj)); } return(new CompositeExpr(head, exprLst.ToArray())); } //TODO return(null); }
public void Test1() { var expr0 = new CompositeExpr(WellKnownSym.times, new Expr[] { new LetterSym('m'), new IntegerNumber(1) }); object output; bool result = expr0.IsLabel(out output); Assert.True(result); }
private List<Expr> NMultiplyArrays(Expr[] args, int start, int end) { #if false Expr[] a2 = new Expr[end-start]; Array.Copy(args, start, a2, 0, end-start); return new List<Expr>(a2); #endif List<Expr> leftover = new List<Expr>(); int i; Expr[,] curmat = null; for (i = start; i < end; i++) { ArrayExpr ae = (ArrayExpr)args[i]; if (ae.Elts.Rank == 2) { if (curmat == null) { curmat = (Expr[,])ae.Elts; } else { Expr[,] m2 = (Expr[,])ae.Elts; if (curmat.GetUpperBound(1) != m2.GetUpperBound(0)) { leftover.Add(TempHackNewAE(curmat)); curmat = m2; } else { int m = curmat.GetUpperBound(0) + 1; int n = m2.GetUpperBound(1) + 1; int o = curmat.GetUpperBound(1) + 1; Expr[,] result = new Expr[m, n]; for (int j = 0; j < m; j++) { for (int k = 0; k < n; k++) { Expr[] sum = new Expr[o]; for (int l = 0; l < o; l++) { sum[l] = new CompositeExpr(WellKnownSym.times, curmat[j, l], m2[l, k]); } result[j, k] = Numericize(Canonicalize(new CompositeExpr(WellKnownSym.plus, sum))); } } curmat = result; } } } else { if (curmat != null) { leftover.Add(TempHackNewAE(curmat)); curmat = null; } leftover.Add(ae); } } if (curmat != null) leftover.Add(TempHackNewAE(curmat)); return leftover; }