protected override SyntaxToken VisitFunction(FunctionSyntaxToken token)
        {
            SyntaxToken arg  = token.Arguments[0];
            SyntaxToken diff = this.Visit(arg);
            SyntaxToken one  = SyntaxToken.Constant(1);
            SyntaxToken two  = SyntaxToken.Constant(2);
            SyntaxToken result;

            switch (token.Type)
            {
            case FunctionType.Sin:
                result = SyntaxToken.Cos(arg);
                break;

            case FunctionType.Cos:
                result = SyntaxToken.Negate(SyntaxToken.Sin(arg));
                break;

            case FunctionType.Tan:
                result = SyntaxToken.Add(one, SyntaxToken.Pow(SyntaxToken.Tan(arg), two));
                break;

            case FunctionType.Cot:
                result = SyntaxToken.Negate(SyntaxToken.Add(one, SyntaxToken.Pow(SyntaxToken.Cot(arg), two)));
                break;

            case FunctionType.Asin:
                result = SyntaxToken.Divide(one, SyntaxToken.Root(SyntaxToken.Subtract(one, SyntaxToken.Pow(arg, two)), two));
                break;

            case FunctionType.Acos:
                result = -(one / SyntaxToken.Root(one - SyntaxToken.Pow(arg, two), two));
                break;

            case FunctionType.Atan:
                result = one / (one + SyntaxToken.Pow(arg, two));
                break;

            case FunctionType.Acot:
                result = -(one / (one + SyntaxToken.Pow(arg, two)));
                break;

            case FunctionType.Log:
                SyntaxToken b = token.Arguments[1];
                result = one / (arg * SyntaxToken.Ln(b));
                break;

            case FunctionType.Ln:
                result = one / arg;
                break;

            case FunctionType.Abs:
                result = arg / SyntaxToken.Abs(arg);
                break;

            case FunctionType.Unsupported:
            default: throw new NotSupportedException();
            }
            return(result * diff);
        }
        protected override SyntaxToken VisitBinary(BinarySyntaxToken token)
        {
            SyntaxToken leftDiff  = this.Visit(token.Left);
            SyntaxToken rightDiff = this.Visit(token.Right);

            switch (token.Type)
            {
            case BinaryOperationType.Add: return(leftDiff + rightDiff);

            case BinaryOperationType.Subtract: return(leftDiff - rightDiff);

            case BinaryOperationType.Multiply: return(leftDiff * token.Right + token.Left * rightDiff);

            case BinaryOperationType.Divide: return((leftDiff * token.Right - token.Left * rightDiff) / SyntaxToken.Pow(token.Right, SyntaxToken.Constant(2)));

            // TODO: implement
            case BinaryOperationType.Modulus: return(token);

            case BinaryOperationType.Power:
                if (!this.VarDetector.HasVariable(token.Right))
                {
                    return(token.Right * SyntaxToken.Pow(token.Left, token.Right - SyntaxToken.Constant(1)));
                }
                return(token * (leftDiff * token.Right / token.Left + rightDiff * SyntaxToken.Ln(token.Left)));

            default: throw new NotSupportedException();
            }
        }
Beispiel #3
0
 private SyntaxToken EvalUnary(ConstantSyntaxToken value, UnaryOperationType type)
 {
     switch (type)
     {
         case UnaryOperationType.Factorial: return SyntaxToken.Constant(MathEx.Factorial(value.Value));
         default: throw new NotSupportedException();
     }
 }
 protected override SyntaxToken VisitVariable(VariableSyntaxToken token)
 {
     if (SyntaxToken.Equals(this.Variable, token))
     {
         return(SyntaxToken.Constant(1));
     }
     return(SyntaxToken.Constant(0));
 }
Beispiel #5
0
        public EvaluationContext CreateEvaluationContext()
        {
            EvaluationContext context = new EvaluationContext();

            foreach (var item in this.Constants)
            {
                context.SetVariable(item.Key, SyntaxToken.Constant(item.Value));
            }
            return(context);
        }
Beispiel #6
0
 private SyntaxToken EvalBinary(ConstantSyntaxToken left, ConstantSyntaxToken right, BinaryOperationType type)
 {
     double lval = left.Value;
     double rval = right.Value;
     switch (type)
     {
         case BinaryOperationType.Add: return SyntaxToken.Constant(lval + rval);
         case BinaryOperationType.Subtract: return SyntaxToken.Constant(lval - rval);
         case BinaryOperationType.Multiply: return SyntaxToken.Constant(lval * rval);
         case BinaryOperationType.Divide: return SyntaxToken.Constant(lval / rval);
         case BinaryOperationType.Modulus: return SyntaxToken.Constant(lval % rval);
         case BinaryOperationType.Power: return SyntaxToken.Constant(Math.Pow(lval, rval));
         default: throw new NotSupportedException();
     }
 }
Beispiel #7
0
 private SyntaxToken EvalFunction(ConstantSyntaxToken[] values, FunctionType type)
 {
     switch (type)
     {
         case FunctionType.Sin: return SyntaxToken.Constant(Math.Sin(values[0].Value));
         case FunctionType.Cos: return SyntaxToken.Constant(Math.Cos(values[0].Value));
         case FunctionType.Tan: return SyntaxToken.Constant(Math.Tan(values[0].Value));
         case FunctionType.Cot: return SyntaxToken.Constant(MathEx.Cot(values[0].Value));
         case FunctionType.Asin: return SyntaxToken.Constant(Math.Asin(values[0].Value));
         case FunctionType.Acos: return SyntaxToken.Constant(Math.Acos(values[0].Value));
         case FunctionType.Atan: return SyntaxToken.Constant(Math.Atan(values[0].Value));
         case FunctionType.Acot: return SyntaxToken.Constant(MathEx.Acot(values[0].Value));
         case FunctionType.Log: return SyntaxToken.Constant(Math.Log(values[0].Value, values[1].Value));
         case FunctionType.Ln: return SyntaxToken.Constant(Math.Log(values[0].Value));
         case FunctionType.Abs: return SyntaxToken.Constant(Math.Abs(values[0].Value));
         default: throw new NotSupportedException();
     }
 }
 protected override SyntaxToken VisitConstant(ConstantSyntaxToken token)
 {
     return(SyntaxToken.Constant(0));
 }
Beispiel #9
0
 protected override SyntaxToken VisitNamedConstant(NamedConstantSyntaxToken token)
 {
     return SyntaxToken.Constant(token.Value);
 }
Beispiel #10
0
        protected override SyntaxToken VisitBinary(BinarySyntaxToken token)
        {
            SyntaxToken left = this.Visit(token.Left);
            SyntaxToken right = this.Visit(token.Right);
            BinaryOperationType type = token.Type;
            if (left.TokenType == SyntaxTokenType.Constant && right.TokenType == SyntaxTokenType.Constant)
            {
                return this.EvalBinary((ConstantSyntaxToken)left, (ConstantSyntaxToken)right, type);
            }
            // swap constant to the right
            if ((type == BinaryOperationType.Add || type == BinaryOperationType.Multiply) && (left.TokenType == SyntaxTokenType.Constant))
            {
                SyntaxToken temp = right;
                right = left;
                left = temp;
            }
            // add
            if (type == BinaryOperationType.Add)
            {
                if (right.HasValue(0))
                {
                    return left;
                }
            }
            // subtract
            else if (type == BinaryOperationType.Subtract)
            {
                if (right.HasValue(0))
                {
                    return left;
                }
                if (SyntaxToken.Equals(left, right))
                {
                    return SyntaxToken.Constant(0);
                }
            }
            // multiply
            else if (type == BinaryOperationType.Multiply)
            {
                if (right.HasValue(0))
                {
                    return SyntaxToken.Constant(0);
                }
                if (right.HasValue(1))
                {
                    return left;
                }
                if (left.TokenType == SyntaxTokenType.Binary && right.TokenType == SyntaxTokenType.Binary)
                {
                    BinarySyntaxToken bl = (BinarySyntaxToken)left;
                    BinarySyntaxToken br = (BinarySyntaxToken)right;
                    if (bl.Type == BinaryOperationType.Power && br.Type == BinaryOperationType.Power && SyntaxToken.Equals(bl.Left, br.Left))
                    {
                        return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Add(bl.Right, br.Right)));
                    }
                }
            }
            // divide
            else if (type == BinaryOperationType.Divide)
            {
                if (left.HasValue(0))
                {
                    return SyntaxToken.Constant(0);
                }
                if (SyntaxToken.Equals(left, right))
                {
                    return SyntaxToken.Constant(1);
                }
            }
            // modulus
            else if (type == BinaryOperationType.Modulus)
            {
                if (left.HasValue(0))
                {
                    return SyntaxToken.Constant(0);
                }
                if (SyntaxToken.Equals(left, right))
                {
                    return SyntaxToken.Constant(0);
                }
            }
            // pow
            else if (type == BinaryOperationType.Power)
            {
                if (right.HasValue(0))
                {
                    return SyntaxToken.Constant(1);
                }
                if (right.HasValue(1))
                {
                    return left;
                }
                if (left.HasValue(0))
                {
                    return SyntaxToken.Constant(1);
                }
                if (left.TokenType == SyntaxTokenType.Binary)
                {
                    BinarySyntaxToken bl = (BinarySyntaxToken)left;
                    if (bl.Type == BinaryOperationType.Power)
                    {
                        return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Multiply(bl.Right, right)));
                    }
                }
            }

            return SyntaxToken.Binary(left, right, type);
        }