コード例 #1
0
ファイル: MultiplyTests.cs プロジェクト: QuantumCores/Mathema
        public void Multiply_Number_FlatAdd()
        {
            //Arrange
            var expected = new FlatAddExpression();

            expected.Add(new VariableExpression("u", 2));
            expected.Add(new NumberExpression(3));
            expected.Count = new Complex(12, 0);
            expected.Execute();

            var c = new NumberExpression(3);
            var n = new FlatAddExpression();

            n.Add(new VariableExpression("u", 2));
            n.Add(new NumberExpression(3));
            n.Count = new Complex(4, 0);
            var expr = new BinaryExpression(c, OperatorTypes.Multiply, n);

            //Act
            var actual = expr.Execute();

            //Assert
            Assert.AreEqual(expected.Count.Re.ToNumber(), actual.Count.Re.ToNumber());
            Assert.AreEqual(expected.Count.Im.ToNumber(), actual.Count.Im.ToNumber());
        }
コード例 #2
0
ファイル: CloneTests.cs プロジェクト: QuantumCores/Mathema
        public void Clone_FlatAddExpression()
        {
            //Arrange
            var expression = new FlatAddExpression();

            expression.Add(new VariableExpression("x", 1));
            expression.Add(new NumberExpression(3));

            //Act
            var clone = (FlatAddExpression)expression.Clone();

            //Assert
            Assert.IsTrue(DimensionKey.Compare(expression.DimensionKey, clone.DimensionKey));
            Assert.IsTrue(FlatExpression.Compare(expression, clone));
        }
コード例 #3
0
ファイル: CloneTests.cs プロジェクト: QuantumCores/Mathema
        public void Clone_FlatAddExpression_Inversed()
        {
            //Arrange
            var flatAdd = new FlatAddExpression();

            flatAdd.Add(new VariableExpression("x", 1));
            flatAdd.Add(new NumberExpression(3));
            var expression = (FlatAddExpression)(new BinaryExpression(flatAdd, OperatorTypes.Power, new NumberExpression(-1)).Execute());

            //Act
            var clone = (FlatAddExpression)expression.Clone();

            //Assert
            Assert.IsTrue(DimensionKey.Compare(expression.DimensionKey, clone.DimensionKey));
            Assert.IsTrue(FlatExpression.Compare(expression, clone));
        }
コード例 #4
0
        private IExpression Delta(IExpression a, IExpression b, IExpression c)
        {
            var b2  = new BinaryExpression(b, Enums.Operators.OperatorTypes.Power, new NumberExpression(2));
            var ac4 = new FlatMultExpression();

            ac4.Add(new NumberExpression(-4));
            ac4.Add(a);
            ac4.Add(c);

            var d2 = new FlatAddExpression();

            d2.Add(b2);
            d2.Add(ac4);

            return(d2);
        }
コード例 #5
0
        private IExpression X1X2(IExpression b, IExpression dsqrt, IExpression a, bool isAdd)
        {
            var oneOvera2 = new BinaryExpression(new BinaryExpression(new NumberExpression(2), Enums.Operators.OperatorTypes.Multiply, a), Enums.Operators.OperatorTypes.Power, new NumberExpression(-1));

            var bds = new FlatAddExpression();

            bds.Add(new UnaryExpression(Enums.Operators.OperatorTypes.Sign, b));

            if (isAdd)
            {
                bds.Add(dsqrt);
            }
            else
            {
                bds.Add(new UnaryExpression(Enums.Operators.OperatorTypes.Sign, dsqrt));
            }

            return(new BinaryExpression(bds, Enums.Operators.OperatorTypes.Multiply, oneOvera2));
        }
コード例 #6
0
        public void RecognizesVariable()
        {
            //Arrange
            var text     = "2 + x";
            var expected = new FlatAddExpression();

            expected.Add(new NumberExpression(1));
            var x = new VariableExpression("x", 1m);

            expected.Add(new UnaryExpression(Mathema.Enums.Operators.OperatorTypes.Sign, x));

            //Act
            var rpn    = RPNParser.Parse(text);
            var actual = (FlatAddExpression)(ExpressionBuilder.BuildFlat(rpn.Output).Execute());

            //Assert
            Assert.IsTrue(actual.Expressions.ContainsKey(Dimensions.Number) || actual.Expressions.ContainsKey(Dimensions.Complex));
            Assert.IsTrue(actual.Expressions.ContainsKey("x"));
        }
コード例 #7
0
ファイル: CloneTests.cs プロジェクト: QuantumCores/Mathema
        public void Clone_FlatAddExpression()
        {
            //Arrange
            var expected = new FlatAddExpression();

            expected.Add(new VariableExpression("x", 1));
            expected.Add(new VariableExpression("y", 1));
            expected.Count = new Complex(3, 2);

            //Act
            var actual = (FlatAddExpression)expected.Clone();

            //Assert
            Assert.IsTrue(!Object.ReferenceEquals(actual, expected));
            CollectionAssert.AreEquivalent(expected.Expressions, actual.Expressions);
            Assert.AreEqual(expected.Count.Re.Numerator, actual.Count.Re.Numerator);
            Assert.AreEqual(expected.Count.Re.Denominator, actual.Count.Re.Denominator);
            Assert.AreEqual(expected.Count.Im.Numerator, actual.Count.Im.Numerator);
            Assert.AreEqual(expected.Count.Im.Denominator, actual.Count.Im.Denominator);
        }
コード例 #8
0
ファイル: Solver.cs プロジェクト: QuantumCores/Mathema
        private static void RecursiveSolve(string variable, IEquationSolutions sols, IEquationSolutions newSols)
        {
            var keys = sols.Solutions.Keys.ToList();

            foreach (var k in keys)
            {
                if (k != variable)
                {
                    var s = sols.Solutions[k];
                    foreach (var e in s.Item2)
                    {
                        var tmpEq = new FlatAddExpression();
                        tmpEq.Add(s.Item1);
                        tmpEq.Add(new UnaryExpression(Enums.Operators.OperatorTypes.Sign, e));
                        var emp = tmpEq.Execute();

                        var c   = EquationClassifier.Classify(emp, variable);
                        var tmp = Solve(variable, tmpEq, c);
                        foreach (var ns in tmp.Solutions)
                        {
                            RecursiveSolve(variable, tmp, newSols);
                        }
                    }
                }
                else
                {
                    var s = sols.Solutions[k];
                    if (!newSols.Solutions.ContainsKey(variable))
                    {
                        newSols.Solutions.Add(variable, new Tuple <IExpression, List <IExpression> >(s.Item1, new List <IExpression>()));
                    }

                    newSols.Solutions[variable].Item2.AddRange(s.Item2);
                }
            }
        }
コード例 #9
0
        public IEquationSolutions Solve(IExpression expression, string variable, IClassificationResult classification)
        {
            var res = new EquationSolutions();

            if (expression is FlatAddExpression fa)
            {
                IExpression        a  = null;
                IExpression        b  = null;
                IExpression        c  = null;
                List <IExpression> ca = new List <IExpression>();

                for (int i = 0; i < fa.Expressions.Count; i++)
                {
                    var kv   = fa.Expressions.ElementAt(i);
                    var deg  = kv.Value[0].DimensionKey.Value;
                    var key  = kv.Value[0].DimensionKey.Key;
                    var expr = kv.Value[0];

                    if (deg.ToNumber() == 2 && key == variable)
                    {
                        if (expr is VariableExpression)
                        {
                            a = new ComplexExpression(expr.Count);
                        }
                        else if (expr is IFunctionExpression)
                        {
                            a = new ComplexExpression(expr.Count);
                        }
                        else
                        {
                            var tmp = (FlatExpression)expr.Clone();
                            tmp.Remove(variable, 2);
                            a = tmp;
                        }
                    }
                    else if (deg.ToNumber() == 1 && key == variable)
                    {
                        if (expr is VariableExpression)
                        {
                            b = new ComplexExpression(expr.Count);
                        }
                        else if (expr is IFunctionExpression)
                        {
                            b = new ComplexExpression(expr.Count);
                        }
                        else
                        {
                            var tmp = (FlatExpression)expr.Clone();
                            tmp.Remove(variable, 2);
                            b = tmp;
                        }
                    }
                    else
                    {
                        ca.Add(kv.Value[0]);
                    }
                }

                if (ca.Count > 1)
                {
                    c = new FlatAddExpression();
                    var ct = (FlatAddExpression)c;
                    foreach (var ci in ca)
                    {
                        ct.Add(ci);
                    }
                }
                else if (ca.Count == 1)
                {
                    c = ca[0];
                }

                if (a != null && c != null)
                {
                    var delta = this.Delta(a, b, c);
                    var ds    = new BinaryExpression(delta, Enums.Operators.OperatorTypes.Power, new NumberExpression(new Fraction(1, 2)));

                    var dsqrt = ds.Execute();

                    var r1 = X1X2(b, dsqrt, a, true);
                    var r2 = X1X2(b, dsqrt, a, false);

                    res.Solutions.Add(variable, new Tuple <IExpression, List <IExpression> >(classification.SearchResult[variable].Item1, new List <IExpression>()
                    {
                        r1.Execute()
                    }));
                    res.Solutions[variable].Item2.Add(r2.Execute());
                }
            }

            return(res);
        }
コード例 #10
0
        public static IExpression BuildFlat(List <ISymbol> RPNStack)
        {
            List <IExpression> stack = new List <IExpression>();
            var i = 0;

            try
            {
                for (i = 0; i < RPNStack.Count; i++)
                {
                    var s = RPNStack[i];
                    if (s.Type != SymbolTypes.Number && s.Type != SymbolTypes.Variable && s.Type != SymbolTypes.Imaginary)
                    {
                        if (s.Type == SymbolTypes.BinaryOperator)
                        {
                            var type = Operators.Get(s.Value).Type;

                            if (type == OperatorTypes.Add)
                            {
                                var tmp = new FlatAddExpression();
                                if (stack[stack.Count - 1] is FlatAddExpression)
                                {
                                    tmp = (FlatAddExpression)stack[stack.Count - 1] + stack[stack.Count - 2];
                                }
                                else if (stack[stack.Count - 2] is FlatAddExpression)
                                {
                                    tmp = (FlatAddExpression)stack[stack.Count - 2] + stack[stack.Count - 1];
                                }
                                else
                                {
                                    tmp.Add(stack[stack.Count - 1]);
                                    tmp.Add(stack[stack.Count - 2]);
                                }

                                stack.RemoveAt(stack.Count - 1);
                                stack.RemoveAt(stack.Count - 1);
                                stack.Add(tmp);
                            }
                            else if (type == OperatorTypes.Subtract)
                            {
                                var tmp = new FlatAddExpression();
                                if (stack[stack.Count - 1] is FlatAddExpression)
                                {
                                    tmp = (FlatAddExpression)stack[stack.Count - 1] + stack[stack.Count - 2];
                                }
                                else if (stack[stack.Count - 2] is FlatAddExpression)
                                {
                                    tmp = (FlatAddExpression)stack[stack.Count - 2] + new UnaryExpression(OperatorTypes.Sign, stack[stack.Count - 1]);
                                }
                                else
                                {
                                    tmp.Add(new UnaryExpression(OperatorTypes.Sign, stack[stack.Count - 1]));
                                    tmp.Add(stack[stack.Count - 2]);
                                }

                                stack.RemoveAt(stack.Count - 1);
                                stack.RemoveAt(stack.Count - 1);
                                stack.Add(tmp);
                            }
                            else if (type == OperatorTypes.Multiply)
                            {
                                var tmp = new FlatMultExpression();
                                if (stack[stack.Count - 1] is FlatMultExpression)
                                {
                                    ((FlatMultExpression)stack[stack.Count - 1]).Add(stack[stack.Count - 2]);
                                    tmp = (FlatMultExpression)stack[stack.Count - 1];
                                }
                                else if (stack[stack.Count - 2] is FlatMultExpression)
                                {
                                    ((FlatMultExpression)stack[stack.Count - 2]).Add(stack[stack.Count - 1]);
                                    tmp = (FlatMultExpression)stack[stack.Count - 2];
                                }
                                else
                                {
                                    tmp.Add(stack[stack.Count - 1]);
                                    tmp.Add(stack[stack.Count - 2]);
                                }

                                stack.RemoveAt(stack.Count - 1);
                                stack.RemoveAt(stack.Count - 1);
                                stack.Add(tmp);
                            }
                            else if (type == OperatorTypes.Divide)
                            {
                                var tmp = new FlatMultExpression();
                                //TODO when both are flatmult
                                if (stack[stack.Count - 1] is FlatMultExpression)
                                {
                                    tmp.Add(stack[stack.Count - 2]);
                                    tmp.Add(new BinaryExpression(stack[stack.Count - 1], OperatorTypes.Power, new NumberExpression(-1)));
                                }
                                else if (stack[stack.Count - 2] is FlatMultExpression)
                                {
                                    tmp = ((FlatMultExpression)stack[stack.Count - 2]);
                                    tmp.Add(new BinaryExpression(stack[stack.Count - 1], OperatorTypes.Power, new NumberExpression(-1)));
                                }
                                else
                                {
                                    //we add inversion and expr to flatmult
                                    tmp.Add(new BinaryExpression(stack[stack.Count - 1], OperatorTypes.Power, new NumberExpression(-1)));
                                    tmp.Add(stack[stack.Count - 2]);
                                }

                                stack.RemoveAt(stack.Count - 1);
                                stack.RemoveAt(stack.Count - 1);
                                stack.Add(tmp);
                            }
                            else
                            {
                                var tmp = new BinaryExpression(stack[stack.Count - 2], Operators.Get(s.Value).Type, stack[stack.Count - 1]);
                                stack.RemoveAt(stack.Count - 1);
                                stack.RemoveAt(stack.Count - 1);
                                stack.Add(tmp);
                            }
                        }
                        else if (s.Type == SymbolTypes.UnaryOperator)
                        {
                            var tmp = new UnaryExpression(Operators.Get(s.Value).Type, stack[stack.Count - 1]);
                            stack.RemoveAt(stack.Count - 1);
                            stack.Add(tmp);
                        }
                        else if (s.Type == SymbolTypes.Function)
                        {
                            var tmp = Functions.Get(s.Value, stack[stack.Count - 1]);
                            stack.RemoveAt(stack.Count - 1);
                            stack.Add(tmp);
                        }
                    }
                    else
                    {
                        if (s.Type == SymbolTypes.Number)
                        {
                            stack.Add(new NumberExpression(s.Value));
                        }
                        else if (s.Type == SymbolTypes.Variable)
                        {
                            stack.Add(new VariableExpression(s.Value, 1m));
                        }
                        else if (s.Type == SymbolTypes.Imaginary)
                        {
                            stack.Add(new ComplexExpression(1m));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                var msg = "I couldn't undertand what you mean by '" + RPNStack[i].Value + "' after " + string.Join(" ", stack);
                throw new WrongSyntaxException(msg, ex);
            }

            if (stack.Count > 1)
            {
                var msg = "I couldn't understand what you mean. Please rephrase your equation. What I understood " + Environment.NewLine + stack[0].ToString();
                throw new WrongSyntaxException(msg);
            }

            return(stack[0]);
        }
コード例 #11
0
        public IEquationSolutions Solve(IExpression expression, string variable, IClassificationResult classification)
        {
            var res = new EquationSolutions();
            List <IExpression> al = new List <IExpression>();
            List <IExpression> bl = new List <IExpression>();
            List <IExpression> cl = new List <IExpression>();


            if (expression is FlatAddExpression fa)
            {
                foreach (var kv in fa.Expressions)
                {
                    var expr = kv.Value[0];

                    if (expr is IFunctionExpression)
                    {
                        if (expr is CosExpression)
                        {
                            al.Add(expr);
                        }
                        else if (expr is SinExpression)
                        {
                            al.Add(expr);
                        }
                        else if (expr is TanExpression)
                        {
                            al.Add(expr);
                        }
                        else if (expr is CotExpression)
                        {
                            al.Add(expr);
                        }
                        else
                        {
                            bl.Add(expr);
                        }
                    }
                    else if (expr is FlatExpression fe)
                    {
                        if (fe.Expressions.Any(e => e.Key == variable))
                        {
                            bl.Add(expr);
                        }
                        else
                        {
                            cl.Add(expr);
                        }
                    }
                    else if (expr.DimensionKey.Key == variable)
                    {
                        bl.Add(expr);
                    }
                    else
                    {
                        cl.Add(expr);
                    }
                }

                if (bl.Count > 0)
                {
                    //General way of solving
                }

                if (al.Count > 1)
                {
                    //General way of solving ?
                }

                if (al.Count == 1)
                {
                    var expr = (IFunctionExpression)al[0];

                    if (expr.InverseFunction != 0)
                    {
                        var arg = new FlatAddExpression();
                        foreach (var e in cl)
                        {
                            arg.Add(new UnaryExpression(Enums.Operators.OperatorTypes.Sign, e).Execute());
                        }
                        arg.Execute();

                        var sol    = Functions.Get(expr.InverseFunction.ToString(), arg).Execute();
                        var solFor = expr.Argument.DimensionKey.Key;
                        res.Solutions.Add(solFor, new Tuple <IExpression, List <IExpression> >(expr.Argument, new List <IExpression>()
                        {
                            sol
                        }));
                    }
                    else
                    {
                        //No inverse function => Numeric solution ?
                    }
                }
            }

            return(res);
        }
コード例 #12
0
        public static IExpression Multiply(IExpression lhe, IExpression rhe)
        {
            var res = lhe.Clone();
            var lc  = (IFlatExpression)res;

            if (rhe is INumberExpression)
            {
                lc.Count.Multiply(rhe.Count);

                return(res);
            }
            //else if (rhe is IVariableExpression)
            //{
            //    var tmp = rhe.DimensionKey.Key;
            //    if (lc.Expressions.ContainsKey(tmp))
            //    {
            //        lc.Expressions[tmp].Add(rhe);
            //    }
            //    else
            //    {
            //        lc.Expressions.Add(tmp, new List<IExpression>() { rhe });
            //    }

            //    foreach (var key in rhe.DimensionKey.Key)
            //    {
            //        res.DimensionKey.Add(key.Key, key.Value);
            //    }

            //    return res;
            //}
            //else if (rhe is IFlatMultExpression)
            //{
            //    foreach (var key in rhe.DimensionKey.Key)
            //    {
            //        res.DimensionKey.Add(key.Key, key.Value);
            //    }

            //    return res;
            //}
            else if (rhe is FlatAddExpression rc)
            {
                var ret = new FlatAddExpression();
                if (lc.DimensionKey.Key == rc.DimensionKey.Key)
                {
                    lc.DimensionKey.Value += (Fraction)rc.DimensionKey.Value;

                    if (lc.DimensionKey.Value.Numerator == 0)
                    {
                        return(new NumberExpression(1));
                    }

                    return(lc);
                }
                else
                {
                    foreach (var expl in lc.Expressions)
                    {
                        foreach (var li in expl.Value)
                        {
                            foreach (var expr in rc.Expressions)
                            {
                                foreach (var ri in expr.Value)
                                {
                                    var tmp = li.BinaryOperations[OperatorTypes.Multiply](li, ri);
                                    ret.Add(tmp);
                                }
                            }
                        }
                    }
                }

                return(ret);
            }

            return(null);
        }
コード例 #13
0
        public IEquationSolutions Solve(IExpression expression, string variable, IClassificationResult classification)
        {
            var                res = new EquationSolutions();
            IExpression        a   = null;
            IExpression        b   = null;
            List <IExpression> ba  = new List <IExpression>();

            if (expression is FlatAddExpression fa)
            {
                foreach (var expr in fa.Expressions)
                {
                    if (expr.Value[0] is FlatExpression fe)
                    {
                        if (fe.Expressions.Any(e => e.Key == variable))
                        {
                            if (expr.Value[0] is VariableExpression)
                            {
                                a = new ComplexExpression(expr.Value[0].Count);
                            }
                            else
                            {
                                var tmp = (FlatExpression)expr.Value[0].Clone();
                                tmp.Remove(variable, 1);
                                a = tmp;
                            }
                        }
                    }
                    else if (expr.Key == variable)
                    {
                        if (expr.Value[0] is VariableExpression)
                        {
                            a = new ComplexExpression(expr.Value[0].Count);
                        }
                        else
                        {
                            var tmp = (FlatExpression)expr.Value[0].Clone();
                            tmp.Remove(variable, 1);
                            a = tmp;
                        }
                    }
                    else
                    {
                        ba.Add(expr.Value[0]);
                    }
                }

                if (ba.Count > 1)
                {
                    b = new FlatAddExpression();
                    var ct = (FlatAddExpression)b;
                    foreach (var ci in ba)
                    {
                        ct.Add(ci);
                    }
                }
                else if (ba.Count == 1)
                {
                    b = ba[0];
                }

                var sol = new BinaryExpression(new UnaryExpression(Enums.Operators.OperatorTypes.Sign, b), Enums.Operators.OperatorTypes.Divide, a).Execute();
                res.Solutions.Add(variable, new Tuple <IExpression, List <IExpression> >(classification.SearchResult[variable].Item1, new List <IExpression>()
                {
                    sol
                }));
            }

            return(res);
        }