Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
 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;
 }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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;
                    }
                }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
 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());
 }
Example #11
0
 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;
 }
Example #12
0
        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);
        }
Example #13
0
 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);
 }
Example #14
0
        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;
        }
Example #15
0
        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);
        }
Example #16
0
        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);
        }
Example #17
0
        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;
        }
Example #18
0
        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);
        }
Example #19
0
        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);
                    }
                }
            }


        
        }
Example #20
0
        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;
        }
Example #21
0
 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);
 }
Example #22
0
        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);
        }
Example #23
0
        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);
        }
Example #24
0
 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;
 }