public static IExpression Multiply(IExpression lhe, IExpression rhe)
        {
            var res = lhe.Clone();

            if (rhe is IVariableExpression)
            {
                res.Count.Multiply(rhe.Count);

                if (rhe.DimensionKey.Key == res.DimensionKey.Key)
                {
                    res.DimensionKey.Value += (Fraction)rhe.DimensionKey.Value;

                    if (res.DimensionKey.Value.Numerator == 0)
                    {
                        return(FromCount(res.Count));
                    }

                    return(res);
                }
            }

            var tmp = new FlatMultExpression();

            tmp.Add(res);
            tmp.Add(rhe.Clone());
            var r = tmp.Execute();

            return(r);
        }
        public static IExpression Divide(IExpression lhe, IExpression rhe)
        {
            var res = lhe.Clone();

            if (rhe is IVariableExpression)
            {
                res.Count.Divide(rhe.Count);

                if (rhe.DimensionKey.Key == res.DimensionKey.Key)
                {
                    res.DimensionKey.Value -= (Fraction)rhe.DimensionKey.Value;

                    if (res.DimensionKey.Value.Numerator == 0)
                    {
                        return(new ComplexExpression(res.Count));
                    }

                    return(res);
                }
            }
            else if (rhe is NumberExpression || rhe is ComplexExpression)
            {
                res.Count.Divide(rhe.Count);
                return(res);
            }

            var tmp = new FlatMultExpression();

            tmp.Add(res);
            tmp.Add(new BinaryExpression(rhe.Clone(), OperatorTypes.Power, new NumberExpression(-1)));
            var r = tmp.Execute();

            return(r);
        }
Beispiel #3
0
        public void Multiply_Number_FlatMult()
        {
            //Arrange
            var expected = new FlatMultExpression();

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

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

            n.Add(new VariableExpression("u", 2));
            n.Add(new VariableExpression("y", 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());
        }
        public static IExpression Divide(IExpression lhe, IExpression rhe)
        {
            var res = lhe.Clone();

            if (rhe is INumberExpression)
            {
                res.Count.Divide(rhe.Count);

                return(ReduceExpression(res));
            }
            else if (rhe is ComplexExpression rc)
            {
                res.Count.Divide(rc.Count);

                return(ReduceExpression(res));
            }
            else
            {
                var tmp = new FlatMultExpression();
                tmp.Add(lhe);
                tmp.Add(new BinaryExpression(rhe.Clone(), OperatorTypes.Power, new NumberExpression(-1)));
                var r = tmp.Execute();
                return(r);
            }
        }
Beispiel #5
0
        public void Clone_FlatMultExpression()
        {
            //Arrange
            var expression = new FlatMultExpression();

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

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

            //Assert
            Assert.IsTrue(DimensionKey.Compare(expression.DimensionKey, clone.DimensionKey));
            Assert.IsTrue(FlatExpression.Compare(expression, clone));
        }
        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);
        }
        public void RecognizesVariable()
        {
            //Arrange
            var text     = "2 * x * y";
            var expected = new FlatMultExpression();

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

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

            //Assert
            Assert.IsTrue(actual.Count.Re.ToNumber() == 2);
            Assert.IsTrue(actual.Expressions.ContainsKey("x"));
            Assert.IsTrue(actual.Expressions.ContainsKey("y"));
        }
Beispiel #8
0
        public void Clone_FlatMultExpression()
        {
            //Arrange
            var expected = new FlatMultExpression();

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

            //Act
            var actual = (FlatMultExpression)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);
        }
        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]);
        }