Beispiel #1
0
        private void AddOutputVariable(GMacCbOutputVariable outputVar)
        {
            SteExpression rhsExpr;

            //An atomic expression or an undefined symbol is found for the variable's RHS side
            if (FollowExpression(outputVar.RhsExpr, out rhsExpr) || rhsExpr.IsAtomic)
            {
                outputVar.RhsExpr = rhsExpr;

                _outputVars.Add(outputVar);

                return;
            }

            //A compound expression is found for the variable's RHS side
            rhsExpr = ReshapePlus(rhsExpr);

            var rhsExprNewArgs = new SteExpression[rhsExpr.ArgumentsCount];

            for (var i = 0; i < rhsExpr.ArgumentsCount; i++)
            {
                rhsExprNewArgs[i] = ReduceSubExpression(rhsExpr[i]);
            }

            outputVar.RhsExpr = SteExpressionUtils.CreateFunction(rhsExpr.HeadText, rhsExprNewArgs);

            _outputVars.Add(outputVar);
        }
Beispiel #2
0
        /// <summary>
        /// Convert the given Mathematica Expr object into a SymbolicExpr object
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        public static SteExpression ToTextExpressionTree(this Expr expr)
        {
            var isNumber = expr.NumberQ();
            var isSymbol = expr.SymbolQ();

            if (isNumber)
            {
                return(isSymbol
                    ? SteExpressionUtils.CreateSymbolicNumber(expr.ToString())
                    : SteExpressionUtils.CreateLiteralNumber(expr.ToString()));
            }

            if (isSymbol)
            {
                return(SteExpressionUtils.CreateVariable(expr.ToString()));
            }

            if (expr.Args.Length == 0)
            {
                return(SteExpressionUtils.CreateFunction(expr.ToString()));
            }
            //return new SymbolicExpr(expr.ToString(), isSymbol, isNumber);

            var args = new SteExpression[expr.Args.Length];

            for (var i = 0; i < expr.Args.Length; i++)
            {
                args[i] = ToTextExpressionTree(expr.Args[i]);
            }

            return(SteExpressionUtils.CreateFunction(expr.Head.ToString(), args));
        }
Beispiel #3
0
        /// <summary>
        /// For example, convert Plus[a, b, c, d] expression into Plus[Plus[a, b, c], d]
        /// </summary>
        /// <param name="expr"></param>
        /// <returns></returns>
        private SteExpression ReshapePlus(SteExpression expr)
        {
            if (expr.ArgumentsCount < 3 || expr.HeadText != "Plus")
            {
                return(expr);
            }

            var arg1 = SteExpressionUtils.CreateFunction(expr.HeadText, expr.Arguments.Take(expr.ArgumentsCount - 1).ToArray());
            var arg2 = expr.LastArgument;

            return(SteExpressionUtils.CreateFunction(expr.HeadText, arg1, arg2));
        }
        public override SteExpression Convert(SteExpression expr)
        {
            //A number
            if (expr.IsNumberLiteral)
            {
                return(ConvertNumber(expr));
            }
            //This has a problem with the Rational[] numbers
            //expr.CreateCopy();


            //A variable
            if (expr.IsVariable)
            {
                //Try convert a low-level Mathematica variable name into a target variable name
                GMacCbVariable targetVar;

                if (ActiveCodeBlock != null && ActiveCodeBlock.VariablesDictionary.TryGetValue(expr.HeadText, out targetVar))
                {
                    return(SteExpressionUtils.CreateVariable(targetVar.TargetVariableName));
                }

                return(expr.CreateCopy());
            }

            //A symbolic constant
            if (expr.IsNumberSymbol)
            {
                switch (expr.HeadText)
                {
                case "Pi":
                    return(SteExpressionUtils.CreateSymbolicNumber("Math.PI"));

                case "E":
                    return(SteExpressionUtils.CreateSymbolicNumber("Math.E"));
                }

                return(expr.CreateCopy());
            }

            //A function; the arguments are converted before creating the main function expression
            return(expr.IsFunction
                ? ConvertFunction(expr.HeadText, expr.Arguments.Select(Convert).ToArray())
                : expr.CreateCopy());
        }
Beispiel #5
0
        /// <summary>
        /// Reduce a complex expression into a simpler one by refactoring all of the sub-expressions into
        /// temp variables. If the initial expression is already simple just return it as is.
        /// </summary>
        /// <param name="initialExpr"></param>
        /// <returns></returns>
        private SteExpression ReduceSubExpression(SteExpression initialExpr)
        {
            string        initialExprText = initialExpr.ToString();
            SteExpression reducedExpr;

            //Try to find the initial expression in the cache
            if (_reducedSubExpressionsCache.TryGetValue(initialExprText, out reducedExpr))
            {
                return(reducedExpr);
            }

            //An atomic expression or an undefined symbol is found for the sub-expression
            if (FollowExpression(initialExpr, out reducedExpr) || reducedExpr.IsAtomic)
            {
                _reducedSubExpressionsCache.Add(initialExprText, reducedExpr);

                return(reducedExpr);
            }

            //A compound expression is found for the sub-expression
            reducedExpr = ReshapePlus(reducedExpr);

            var rhsExprNewArgs = new SteExpression[reducedExpr.ArgumentsCount];

            //Convert all arguments into simple constants, undefined symbols, or temp variable symbols
            for (var i = 0; i < reducedExpr.ArgumentsCount; i++)
            {
                rhsExprNewArgs[i] = ReduceSubExpression(reducedExpr[i]);
            }

            //Create a new RHS expression from the converted arguments
            reducedExpr = SteExpressionUtils.CreateFunction(reducedExpr.HeadText, rhsExprNewArgs);

            //Find or create a temp variable to hold the new RHS expression
            var tempVar = GetTempVariable(reducedExpr);

            //Return the final temp variable symbol expression
            reducedExpr = SteExpressionUtils.CreateVariable(tempVar.LowLevelName);

            //Add reduced expression to cache
            _reducedSubExpressionsCache.Add(initialExprText, reducedExpr);

            return(reducedExpr);
        }
        private static SteExpression ConvertNumber(SteExpression numberExpr)
        {
            var rationalHeadIndex = numberExpr.HeadText.IndexOf(@"Rational[", StringComparison.Ordinal);

            //This is an ordinary number, return as-is
            if (rationalHeadIndex < 0)
            {
                return(numberExpr.CreateCopy());
            }

            //This is a rational atomic number; for example Rational[1, 2].
            //Extract components and convert to floating point
            var numberTextFull = numberExpr.HeadText.Substring(@"Rational[".Length);
            var commaIndex     = numberTextFull.IndexOf(',');
            var bracketIndex   = numberTextFull.IndexOf(']');

            var num1Text = numberTextFull.Substring(0, commaIndex);
            var num2Text = numberTextFull.Substring(commaIndex + 1, bracketIndex - commaIndex - 1);

            return(SteExpressionUtils.CreateLiteralNumber(
                       double.Parse(num1Text) / double.Parse(num2Text)
                       ));
        }
Beispiel #7
0
 /// <summary>
 /// Create a literal number expression like "2", "-1.7" and "3.56e-4"
 /// </summary>
 /// <param name="number"></param>
 /// <returns></returns>
 public SteExpression LiteralNumber(float number)
 {
     return(SteExpressionUtils.CreateLiteralNumber(number));
 }
Beispiel #8
0
 /// <summary>
 /// Create an operator expression from a head and a set of expressions as its arguments
 /// </summary>
 /// <param name="head"></param>
 /// <param name="args"></param>
 /// <returns></returns>
 public SteExpression Operator(SteOperatorSpecs head, IEnumerable <SteExpression> args)
 {
     return(SteExpressionUtils.CreateOperator(head, args));
 }
Beispiel #9
0
 /// <summary>
 /// Create an operator expression from a head and a set of expressions as its arguments
 /// </summary>
 /// <param name="head"></param>
 /// <param name="args"></param>
 /// <returns></returns>
 public SteExpression Operator(SteOperatorSpecs head, params SteExpression[] args)
 {
     return(SteExpressionUtils.CreateOperator(head, args));
 }
Beispiel #10
0
 /// <summary>
 /// Create an operator expression without any arguments
 /// </summary>
 /// <param name="head"></param>
 /// <returns></returns>
 public SteExpression Operator(SteOperatorSpecs head)
 {
     return(SteExpressionUtils.CreateOperator(head));
 }
Beispiel #11
0
 /// <summary>
 /// Create an operator expression from a head and a set of expressions as its arguments
 /// </summary>
 /// <param name="head"></param>
 /// <param name="args"></param>
 /// <returns></returns>
 public SteExpression Function(string head, IEnumerable <SteExpression> args)
 {
     return(SteExpressionUtils.CreateFunction(head, args));
 }
Beispiel #12
0
 /// <summary>
 /// Create an operator expression from a head and a set of expressions as its arguments
 /// </summary>
 /// <param name="head"></param>
 /// <param name="args"></param>
 /// <returns></returns>
 public SteExpression Function(string head, params SteExpression[] args)
 {
     return(SteExpressionUtils.CreateFunction(head, args));
 }
Beispiel #13
0
 /// <summary>
 /// Create an operator expression without any arguments
 /// </summary>
 /// <param name="head"></param>
 /// <returns></returns>
 public SteExpression Function(string head)
 {
     return(SteExpressionUtils.CreateFunction(head));
 }
Beispiel #14
0
 /// <summary>
 /// Create a literal number expression like "2", "-1.7" and "3.56e-4"
 /// </summary>
 /// <param name="numberText"></param>
 /// <returns></returns>
 public SteExpression LiteralNumber(string numberText)
 {
     return(SteExpressionUtils.CreateLiteralNumber(numberText));
 }
Beispiel #15
0
 /// <summary>
 /// Create a symbolic number expression like "Pi" and "e".
 /// </summary>
 /// <param name="numberText"></param>
 /// <returns></returns>
 public SteExpression SymbolicNumber(string numberText)
 {
     return(SteExpressionUtils.CreateSymbolicNumber(numberText));
 }
Beispiel #16
0
 /// <summary>
 /// Create an atomic expression from a variable name
 /// </summary>
 /// <param name="varName"></param>
 /// <returns></returns>
 public SteExpression Variable(string varName)
 {
     return(SteExpressionUtils.CreateVariable(varName));
 }
        private static SteExpression ConvertFunction(string functionName, params SteExpression[] arguments)
        {
            switch (functionName)
            {
            //case "Rational":
            //    return SteExpressionUtils.CreateOperator(
            //        CSharpUtils.Operators.Divide,
            //        SteExpressionUtils.CreateLiteralNumber(arguments[0].ToString()),
            //        SteExpressionUtils.CreateLiteralNumber(arguments[1].ToString())
            //        );

            case "Plus":
                return(SteExpressionUtils.CreateOperator(
                           CSharpUtils.Operators.Add, arguments
                           ));

            case "Minus":
                return(SteExpressionUtils.CreateOperator(
                           CSharpUtils.Operators.UnaryMinus, arguments
                           ));

            case "Subtract":
                return(SteExpressionUtils.CreateOperator(
                           CSharpUtils.Operators.Subtract, arguments
                           ));

            case "Times":
                return(SteExpressionUtils.CreateOperator(
                           CSharpUtils.Operators.Multiply, arguments
                           ));

            case "Divide":
                return(SteExpressionUtils.CreateOperator(
                           CSharpUtils.Operators.Divide, arguments
                           ));

            case "Power":
                return(SteExpressionUtils.CreateFunction("Math.Pow", arguments));

            case "Abs":
                return(SteExpressionUtils.CreateFunction("Math.Abs", arguments));

            case "Exp":
                return(SteExpressionUtils.CreateFunction("Math.Exp", arguments));

            case "Sin":
                return(SteExpressionUtils.CreateFunction("Math.Sin", arguments));

            case "Cos":
                return(SteExpressionUtils.CreateFunction("Math.Cos", arguments));

            case "Tan":
                return(SteExpressionUtils.CreateFunction("Math.Tan", arguments));

            case "ArcSin":
                return(SteExpressionUtils.CreateFunction("Math.Asin", arguments));

            case "ArcCos":
                return(SteExpressionUtils.CreateFunction("Math.Acos", arguments));

            case "ArcTan":
                return(SteExpressionUtils.CreateFunction(
                           arguments.Length == 1 ? "Math.Atan" : "Math.Atan2",
                           arguments
                           ));

            case "Sinh":
                return(SteExpressionUtils.CreateFunction("Math.Sinh", arguments));

            case "Cosh":
                return(SteExpressionUtils.CreateFunction("Math.Cosh", arguments));

            case "Tanh":
                return(SteExpressionUtils.CreateFunction("Math.Tanh", arguments));

            case "Log":
                return(SteExpressionUtils.CreateFunction(
                           "Math.Log",
                           arguments.Length == 1 ? arguments : arguments.Reverse()
                           ));

            case "Log10":
                return(SteExpressionUtils.CreateFunction("Math.Log10", arguments));

            case "Sqrt":
                return(SteExpressionUtils.CreateFunction("Math.Sqrt", arguments));

            case "Floor":
                return(SteExpressionUtils.CreateFunction(
                           arguments.Length == 1 ? "Math.Floor" : "MathHelper.Floor",
                           arguments
                           ));

            case "Ceiling":
                return(SteExpressionUtils.CreateFunction(
                           arguments.Length == 1 ? "Math.Ceiling" : "MathHelper.Ceiling",
                           arguments
                           ));

            case "Round":
                return(SteExpressionUtils.CreateFunction(
                           arguments.Length == 1 ? "Math.Round" : "MathHelper.Round",
                           arguments
                           ));

            case "Min":
                return(SteExpressionUtils.CreateFunction(
                           arguments.Length == 1 ? "Math.Min" : "MathHelper.Min",
                           arguments
                           ));

            case "Max":
                return(SteExpressionUtils.CreateFunction(
                           arguments.Length == 1 ? "Math.Max" : "MathHelper.Max",
                           arguments
                           ));

            case "Sign":
                return(SteExpressionUtils.CreateFunction("Math.Sign", arguments));

            case "IntegerPart":
                return(SteExpressionUtils.CreateFunction("Math.Truncate", arguments));
            }

            return(SteExpressionUtils.CreateFunction("MathHelper." + functionName, arguments));
        }