示例#1
0
        public object Clone()
        {
            QsFunction f      = (QsFunction)this.MemberwiseClone();
            var        fdname = f.FunctionDeclaration.Substring(0, f.FunctionDeclaration.IndexOf('('));

            f.FunctionDeclaration = f.FunctionDeclaration.Replace(fdname, "_");
            return(f);
        }
        /// <summary>
        /// Differentiate operation for function.
        /// </summary>
        /// <param name="value">object of <see cref="QsScalar"/> that hold <see cref="AnyQuantity&lt;SymbolicVariable&gt;"/></param>
        /// <returns></returns>
        public override QsValue DifferentiateOperation(QsValue value)
        {
            QsScalar sval = (QsScalar)value;

            if (sval.ScalarType == ScalarTypes.SymbolicQuantity)
            {
                var dsv = sval.SymbolicQuantity.Value;

                string fname         = "_";
                string WholeFunction = string.Empty;
                if (this.FunctionBodyToken[0].TokenClassType == typeof(CurlyBracketGroupToken))
                {
                    // vector differentiation
                    // take every term in the vector and differentiate it
                    var           vcs = QsVar.VectorComponents(this.FunctionBodyToken[0]);
                    StringBuilder sc  = new StringBuilder();
                    sc.Append(fname + "(" + RemoveRedundantParameters(this.ParametersNames) + ") = ");
                    sc.Append("{ ");
                    foreach (var c in vcs)
                    {
                        SymbolicVariable nsv = SymbolicVariable.Parse(c);
                        int times            = (int)dsv.SymbolPower;
                        while (times > 0)
                        {
                            nsv = nsv.Differentiate(dsv.Symbol);
                            times--;
                        }
                        sc.Append(nsv.ToString());
                        sc.Append(" ");
                    }
                    sc.Append("}");

                    WholeFunction = sc.ToString();
                }
                else
                {
                    SymbolicVariable nsv = ToSymbolicVariable();
                    int times            = (int)dsv.SymbolPower;
                    while (times > 0)
                    {
                        nsv = nsv.Differentiate(dsv.Symbol);
                        times--;
                    }

                    WholeFunction = fname + "(" + RemoveRedundantParameters(this.ParametersNames) + ") = " + nsv.ToString();
                }


                return(QsFunction.ParseFunction(QsEvaluator.CurrentEvaluator, WholeFunction));
            }
            else
            {
                return(base.DifferentiateOperation(value));
            }
        }
示例#3
0
        /// <summary>
        /// Get the default function.
        /// Default function is on the form f#2 f#3  without decoration for parameters.
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="nameSpace"></param>
        /// <param name="functionName"></param>
        /// <param name="parameterCount"></param>
        /// <returns></returns>
        public static QsFunction GetDefaultFunction(
            QsScope scope,
            string nameSpace,
            string functionName,
            int parametersCount)
        {
            string functionRealName = QsFunction.FormFunctionSymbolicName(functionName, parametersCount);

            QsFunction func = QsFunction.GetFunction(scope, nameSpace, functionRealName);

            return(func);
        }
        /// <summary>
        /// Join any set of given functions and returns the tokens of the new function along
        /// with the new function text.
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="functionDeclaration"></param>
        /// <param name="functions"></param>
        /// <returns></returns>
        internal static Token JoinFunctionsArrayTokensWithOperation(string operation, out string functionDeclaration, params QsFunction[] functions)
        {
            var fname = "_";

            var           fbody      = "";
            List <string> fparamList = new List <string>();

            foreach (var f in functions)
            {
                fbody += " " + f.FunctionBody + " " + operation;
                fparamList.AddRange(f.ParametersNames);
            }
            fbody = fbody.TrimEnd(operation.ToCharArray());

            string[] fparam = fparamList.ToArray();

            var fNameParamPart = fname + "(" + RemoveRedundantParameters(fparam) + ") =";

            functionDeclaration = fNameParamPart + fbody;

            Token fTokens = new Token();

            // add first part tokens
            foreach (var t in QsFunction.TokenizeFunction(fNameParamPart))
            {
                fTokens.AppendSubToken(t);
            }

            for (int i = 0; i < functions.Length; i++)
            {
                // prepare function body tokens
                foreach (var t in functions[i].FunctionBodyToken)
                {
                    fTokens.AppendSubToken(t);
                }

                if (i < functions.Length - 1)
                {
                    fTokens.AppendSubToken(Token.ParseText(operation.Trim())[0]);                            //operation is only one charachter
                }
            }


            return(fTokens);
        }
示例#5
0
        /// <summary>
        /// Get the function that is stored in the scope.
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="realName"></param>
        /// <returns></returns>
        public static QsFunction GetFunction(QsScope scope, string qsNamespace, string functionName)
        {
            if (string.IsNullOrEmpty(qsNamespace))
            {
                // no namespace included then it is from the local scope.


                // I am adding the mathmatical functions in the root namespace
                // so I will test for the function namespace and

                QsFunction function = (QsFunction)MathNamespace.GetValueOrNull(functionName);

                // built int math functions will be overwrite any other functions
                if (function != null)
                {
                    return(function);
                }
                else
                {
                    function = (QsFunction)QsEvaluator.GetScopeValueOrNull(scope, qsNamespace, functionName);
                }

                return(function);
            }
            else
            {
                try
                {
                    QsNamespace ns = QsNamespace.GetNamespace(scope, qsNamespace);


                    return((QsFunction)ns.GetValue(functionName));
                }
                catch (QsVariableNotFoundException)
                {
                    return(null);
                }
            }
        }
        /// <summary>
        /// Take the value and operation in text and return the current function operationed by value.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="operation"></param>
        /// <returns></returns>
        private QsFunction FOperation(QsValue value, string operation)
        {
            if (value is QsFunction)
            {
                QsFunction fn2 = (QsFunction)value;

                string fParameters = RemoveRedundantParameters(this.ParametersNames.Union(fn2.ParametersNames).ToArray());

                string thisFunctionBody = this.FunctionBody;
                foreach (string p in this.ParametersNames)
                {
                    thisFunctionBody = thisFunctionBody.Replace(p, "$" + p);
                }

                string targetFunctionBody = fn2.FunctionBody;
                foreach (string p in fn2.ParametersNames)
                {
                    targetFunctionBody = targetFunctionBody.Replace(p, "$" + p);
                }

                // form the expressions that will be parsed.
                string fpt = "(" + thisFunctionBody + ")" + operation + "(" + targetFunctionBody + ")";

                fpt = fpt.Replace("!", "__FAC__"); // replacing the ! sign with __FAC__ to include the '!' sign into the calculations {because '!' is operator in parsing so it doesn't enter the algebraic calculations}
                //evaulate fpt

                try
                {
                    QsScalar sc            = (QsScalar)QsEvaluator.CurrentEvaluator.SilentEvaluate(fpt);
                    string   FuncBody      = sc.SymbolicQuantity.Value.ToString().Replace("__FAC__", "!");
                    string   WholeFunction = "_(" + fParameters + ") = " + FuncBody;
                    return(QsFunction.ParseFunction(QsEvaluator.CurrentEvaluator, WholeFunction));
                }
                catch (QsIncompleteExpression)
                {
                    // something happened make the operation in old fashion
                    string WholeFunction;
                    Token  FunctionToken = JoinFunctionsArrayTokensWithOperation(operation, out WholeFunction, this, fn2);
                    return(QsFunction.ParseFunction(QsEvaluator.CurrentEvaluator, WholeFunction, FunctionToken));
                }
            }
            else if (value is QsScalar)
            {
                QsScalar svl = (QsScalar)value;

                var fname = "_";

                var fbody = this.FunctionBody;
                if (svl.ScalarType == ScalarTypes.SymbolicQuantity)
                {
                    fbody = "(" + fbody + ")" + operation + "(" + svl.SymbolicQuantity.Value.ToString() + ")";
                }
                else if (svl.ScalarType == ScalarTypes.NumericalQuantity)
                {
                    fbody = "(" + fbody + ")" + operation + svl.NumericalQuantity.Value.ToString();
                }
                else if (svl.ScalarType == ScalarTypes.RationalNumberQuantity)
                {
                    fbody = "(" + fbody + ")" + operation + svl.RationalQuantity.Value.Value.ToString();
                }
                else if (svl.ScalarType == ScalarTypes.FunctionQuantity)
                {
                    fbody = "(" + fbody + ")" + operation + "(" + svl.FunctionQuantity.Value.FunctionBody + ")";
                }
                else
                {
                    throw new QsException("Operation '" + operation + "' for the target scalar type (" + svl.ScalarType + ") is not supported");
                }


                QsScalar fb = SymbolicVariable.Parse(fbody).ToQuantity().ToScalar();

                string FuncBody = string.Empty;
                if (fb.ScalarType == ScalarTypes.SymbolicQuantity)
                {
                    FuncBody = fb.SymbolicQuantity.Value.ToString().Replace("__FAC__", "!");
                }
                else
                {
                    FuncBody = fb.ToExpressionParsableString();
                }

                string[] functionParametersArray = this.ParametersNames; // this is the available parameters for the original function.

                if (svl.ScalarType == ScalarTypes.SymbolicQuantity)
                {
                    List <string> newParametersList = new List <string>(functionParametersArray);

                    newParametersList.AddRange(svl.SymbolicQuantity.Value.InvolvedSymbols);

                    functionParametersArray = newParametersList.ToArray();
                }

                if (svl.ScalarType == ScalarTypes.FunctionQuantity)
                {
                    List <string> newParametersList = new List <string>(functionParametersArray);

                    newParametersList.AddRange(svl.FunctionQuantity.Value.ParametersNames);

                    functionParametersArray = newParametersList.ToArray();
                }

                var f = fname + "(" + RemoveRedundantParameters(functionParametersArray) + ") = " + FuncBody;
                return(QsFunction.ParseFunction(QsEvaluator.CurrentEvaluator, f));
            }

            else
            {
                throw new NotImplementedException();
            }
        }
示例#7
0
 /// <summary>
 /// if we consider the <see cref="ParameterRawText"/> as a function name.
 /// then this function will get the actual function name which include parameters count.
 /// This function is only used in making expressions.
 /// </summary>
 /// <param name="paramCount"></param>
 /// <returns></returns>
 public string GetTrueFunctionName(int paramCount)
 {
     return(QsFunction.FormFunctionSymbolicName(ParameterRawText, paramCount));
 }
示例#8
0
        public static QsFunction ParseFunction(QsEvaluator qse, string functionDeclaration, Token functionToken)
        {
            int nsidx = 0; // surve as a base for indexing token if there is namespace it will be 1 otherwise remain 0

            // specify the namespaces end token.
            string functionNamespace = "";

            foreach (var tok in functionToken)
            {
                if (tok.TokenClassType == typeof(NamespaceToken))
                {
                    nsidx++;
                    functionNamespace += tok.TokenValue;
                }
                else
                {
                    break;
                }
            }

            if (
                functionToken[nsidx].TokenClassType == typeof(WordToken) &&
                (functionToken.Count > (nsidx + 1) ? functionToken[nsidx + 1].TokenClassType == typeof(ParenthesisGroupToken) : false) &&
                (functionToken.Count > (nsidx + 2) ? functionToken[nsidx + 2].TokenClassType == typeof(EqualToken) : false)
                )
            {
                //get function name
                // will be the first token after excluding namespace.

                string functionName = string.Empty;


                functionName = functionToken[nsidx].TokenValue;

                //remove the last : from namespace
                functionNamespace = functionNamespace.TrimEnd(':');

                List <string>      textParams = new List <string>();
                List <QsParamInfo> prms       = new List <QsParamInfo>();
                foreach (var c in functionToken[nsidx + 1])
                {
                    if (
                        c.TokenValue.StartsWith("(") ||
                        c.TokenValue.StartsWith(")") ||
                        c.TokenValue.StartsWith(",") ||
                        c.TokenClassType == typeof(MultipleSpaceToken)
                        )
                    {
                        //ignore these things.
                    }
                    else
                    {
                        if (char.IsLetter(c.TokenValue[0]))
                        {
                            textParams.Add(c.TokenValue);
                            prms.Add(new QsParamInfo {
                                Name = c.TokenValue, Type = QsParamType.Value
                            });
                        }
                        else
                        {
                            throw new QsSyntaxErrorException("Parameter name must statrt with a letter");
                        }
                    }
                }

                //declared for first time a default function.
                QsFunction qf = new QsFunction(functionDeclaration)
                {
                    FunctionNamespace = functionNamespace,
                    FunctionName      = functionName,
                    Parameters        = prms.ToArray()
                };


                //LambdaBuilder lb = Utils.Lambda(typeof(QsValue), functionName);
                SimpleLambdaBuilder lb = SimpleLambdaBuilder.Create(typeof(QsValue), functionName);

                foreach (QsParamInfo prm in prms)
                {
                    lb.Parameter(typeof(QsParameter), prm.Name);
                }

                List <Expression> statements = new List <Expression>();

                qf.FunctionBody = functionDeclaration.Substring(functionToken[nsidx + 2].IndexInText + functionToken[nsidx + 2].TokenValueLength).Trim();

                Token functionBodyTokens;
                QsVar qv = new QsVar(qse, qf.FunctionBody, qf, lb, out functionBodyTokens);

                statements.Add(qv.ResultExpression);   //making the variable expression itself make it the return value of the function.

                lb.Body = Expression.Block(statements);



                LambdaExpression lbe = lb.MakeLambda();

                qf.FunctionExpression = lbe;

                qf.FunctionBodyToken = functionBodyTokens;

                return(qf);
            }
            else
            {
                return(null);
            }
        }