Пример #1
0
        /// <summary>
        /// Check for inequality.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// A value representing true if not equal.
        /// </returns>
        public override Derivatives <Expression> NotEqual(Derivatives <Expression> b)
        {
            var result = new ExpressionTreeDerivatives();

            result[0] = Expression.Condition(Expression.NotEqual(this[0], b[0]), One, Zero);
            return(result);
        }
Пример #2
0
        /// <summary>
        /// Subtract derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The difference.
        /// </returns>
        public override Derivatives <Expression> Subtract(Derivatives <Expression> b)
        {
            var size   = Math.Max(Count, b.Count);
            var result = new ExpressionTreeDerivatives(size);

            for (var i = 0; i < size; i++)
            {
                if (this[i] == null)
                {
                    if (b[i] == null)
                    {
                        result[i] = null;
                    }
                    else
                    {
                        result[i] = Expression.Negate(b[i]);
                    }
                }
                else
                {
                    if (b[i] == null)
                    {
                        result[i] = this[i];
                    }
                    else
                    {
                        result[i] = Expression.Subtract(this[i], b[i]);
                    }
                }
            }
            return(result);
        }
Пример #3
0
        /// <summary>
        /// Multiply derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The multiplied result.
        /// </returns>
        public override Derivatives <Func <double> > Multiply(Derivatives <Func <double> > b)
        {
            var size   = Math.Max(Count, b.Count);
            var result = new DoubleDerivatives(size);
            var a0     = this[0];
            var b0     = b[0];

            result[0] = () => a0() * b0();
            for (var i = 1; i < size; i++)
            {
                var arg1 = this[i];
                var arg2 = b[i];
                if (arg1 != null && arg2 != null)
                {
                    result[i] = () => b0() * arg1() + arg2() * a0();
                }
                else if (arg1 != null)
                {
                    result[i] = () => arg1() * b0();
                }
                else if (arg2 != null)
                {
                    result[i] = () => a0() * arg2();
                }
            }
            return(result);
        }
Пример #4
0
        /// <summary>
        /// Nots the equal.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        public override Derivatives <Func <double> > NotEqual(Derivatives <Func <double> > other)
        {
            var result = new DoubleDerivatives();
            var arg1   = this[0];
            var arg2   = other[0];

            result[0] = () => arg1().Equals(arg2()) ? 0 : 1;
            return(result);
        }
Пример #5
0
        /// <summary>
        /// And the derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The derivatives.
        /// </returns>
        public override Derivatives <Func <double> > And(Derivatives <Func <double> > b)
        {
            var result = new DoubleDerivatives();
            var arg1   = this[0];
            var arg2   = b[0];

            result[0] = () => arg1().Equals(0.0) || arg2().Equals(0.0) ? 0 : 1;
            return(result);
        }
Пример #6
0
        /// <summary>
        /// Modulo operation on derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The remainder of the division.
        /// </returns>
        public override Derivatives <Func <double> > Modulo(Derivatives <Func <double> > b)
        {
            var result = new DoubleDerivatives();
            var a0     = this[0];
            var b0     = b[0];

            result[0] = () => a0() % b0();
            return(result);
        }
Пример #7
0
        /// <summary>
        /// Check greater than.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// A value representing true if this is greater.
        /// </returns>
        public override Derivatives <Func <double> > GreaterThan(Derivatives <Func <double> > b)
        {
            var result = new DoubleDerivatives();
            var a0     = this[0];
            var b0     = b[0];

            result[0] = () => a0() > b0() ? 1 : 0;
            return(result);
        }
Пример #8
0
        /// <summary>
        /// Check less or equal.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// A value representing true if this is less or equal.
        /// </returns>
        public override Derivatives <Func <double> > LessOrEqual(Derivatives <Func <double> > b)
        {
            var result = new DoubleDerivatives();
            var a0     = this[0];
            var b0     = b[0];

            result[0] = () => a0() <= b0() ? 1 : 0;
            return(result);
        }
Пример #9
0
        /// <summary>
        /// And the derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The derivatives.
        /// </returns>
        public override Derivatives <Expression> And(Derivatives <Expression> b)
        {
            var result = new ExpressionTreeDerivatives();

            result[0] = Expression.Condition(
                Expression.Or(
                    Expression.Equal(this[0], Zero),
                    Expression.Equal(b[0], Zero)), Zero, One);
            return(result);
        }
Пример #10
0
        /// <summary>
        /// Divide derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The divided result.
        /// </returns>
        public override Derivatives <Expression> Divide(Derivatives <Expression> b)
        {
            var size   = Math.Max(Count, b.Count);
            var result = new ExpressionTreeDerivatives(size);

            Expression a0 = this[0], b0 = b[0];

            if (a0 == null)
            {
                return(null);
            }
            if (b0 == null)
            {
                throw new DivideByZeroException();
            }
            result[0] = Expression.Call(Division, a0, b0);
            for (var i = 1; i < size; i++)
            {
                if (this[i] == null)
                {
                    if (b[i] == null)
                    {
                        result[i] = null;
                    }
                    else
                    {
                        // (a/gx)' = -a/gx^2*g'x
                        result[i] = Expression.Call(Division,
                                                    Expression.Negate(Expression.Multiply(a0, b[i])),
                                                    Expression.Call(SquareInfo, b0));
                    }
                }
                else
                {
                    if (b[i] == null)
                    {
                        // (fx/b)' = f'x/b
                        result[i] = Expression.Call(Division, this[i], b0);
                    }
                    else
                    {
                        // (fx/gx)' = (f'x*gx-fx*g'x)/gx^2
                        result[i] = Expression.Call(Division,
                                                    Expression.Subtract(
                                                        Expression.Multiply(this[i], b0),
                                                        Expression.Multiply(a0, b[i])),
                                                    Expression.Call(SquareInfo, b0));
                    }
                }
            }
            return(result);
        }
Пример #11
0
        /// <summary>
        /// Check greater or equal.
        /// </summary>
        /// <param name="b">The operand.</param>
        /// <returns>
        /// A value representing true if this is greater or equal.
        /// </returns>
        public override Derivatives <Expression> GreaterOrEqual(Derivatives <Expression> b)
        {
            var        result = new ExpressionTreeDerivatives();
            Expression a0 = this[0], b0 = b[0];

            if (a0 == null && b0 == null)
            {
                return(result);
            }
            a0        = a0 ?? Zero;
            b0        = b0 ?? Zero;
            result[0] = Expression.Condition(Expression.GreaterThanOrEqual(a0, b0), One, Zero); return(result);
        }
Пример #12
0
        /// <summary>
        /// Conditional derivatives.
        /// </summary>
        /// <param name="iftrue">Argument if true.</param>
        /// <param name="iffalse">Argument if false.</param>
        /// <returns>
        /// The derivatives.
        /// </returns>
        public override Derivatives <Func <double> > IfThenElse(Derivatives <Func <double> > iftrue, Derivatives <Func <double> > iffalse)
        {
            var size   = Math.Max(iftrue.Count, iffalse.Count);
            var result = new DoubleDerivatives(size);
            var arg    = this[0];

            for (var i = 0; i < size; i++)
            {
                var arg2 = iftrue[i] ?? (() => 0.0);
                var arg3 = iffalse[i] ?? (() => 0.0);
                result[i] = () => arg().Equals(0.0) ? arg3() : arg2();
            }
            return(result);
        }
Пример #13
0
 /// <summary>
 /// Check equality.
 /// </summary>
 /// <param name="obj">The other object.</param>
 /// <returns></returns>
 public bool Equals(Derivatives <T> obj)
 {
     if (obj.Count != Count)
     {
         return(false);
     }
     for (var i = 0; i < Count; i++)
     {
         if (!this[i].Equals(obj[i]))
         {
             return(false);
         }
     }
     return(true);
 }
Пример #14
0
        /// <summary>
        /// Modulo operation on derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The remainder of the division.
        /// </returns>
        public override Derivatives <Expression> Modulo(Derivatives <Expression> b)
        {
            var result = new ExpressionTreeDerivatives();

            if (this[0] == null)
            {
                return(result);
            }
            if (b[0] == null)
            {
                throw new Exception("Modulo by 0");
            }
            result[0] = Expression.Modulo(this[0], b[0]);
            return(result);
        }
Пример #15
0
        /// <summary>
        /// Raises the derivatives to a power.
        /// </summary>
        /// <param name="exponent">The exponent.</param>
        /// <returns>
        /// The raised power.
        /// </returns>
        public override Derivatives <Expression> Pow(Derivatives <Expression> exponent)
        {
            var        size = Math.Max(Count, exponent.Count);
            var        result = new ExpressionTreeDerivatives(size);
            Expression a0 = this[0], b0 = exponent[0];

            if (a0 == null && b0 == null)
            {
                // This doesn't make much sense (0^0 is invalid) but Math.Pow does it like that so we will too
                result[0] = One;
                return(result);
            }
            if (a0 == null)
            {
                a0 = Zero;
            }
            if (b0 == null)
            {
                // (fx)^0 = 1
                result[0] = One;
                return(result);
            }
            result[0] = Expression.Call(PowInfo, a0, b0);
            if (a0 != One && a0 != Zero)
            {
                a0 = Expression.Call(AbsInfo, a0);
            }
            for (var i = 1; i < size; i++)
            {
                // (fx^b)' = b * fx^(b-1) * f'x
                if (this[i] != null)
                {
                    result[i] = Expression.Multiply(b0, Expression.Multiply(this[i],
                                                                            Expression.Call(PowInfo, a0, Expression.Subtract(b0, One))));
                }

                // (fx^gx)' = (e^(gx*ln(fx)))'
                // = fx^(gx-1)*f'x + fx^gx*ln(fx)*g'x
                if (exponent[i] != null)
                {
                    var contribution = Expression.Multiply(Expression.Call(PowInfo, a0, b0),
                                                           Expression.Multiply(Expression.Call(LogInfo, a0), exponent[i]));
                    result[i] = result[i] == null ? contribution :
                                Expression.Add(result[i], contribution);
                }
            }
            return(result);
        }
Пример #16
0
        /// <summary>
        /// Raises the derivatives to a power.
        /// </summary>
        /// <param name="exponent">The exponent.</param>
        /// <returns>The raised power.</returns>
        public override Derivatives <Func <double> > Pow(Derivatives <Func <double> > exponent)
        {
            var size   = Math.Max(Count, exponent.Count);
            var result = new DoubleDerivatives(size);
            var a0     = this[0];
            var b0     = exponent[0];

            result[0] = () => SafePow(a0(), b0());
            for (var i = 1; i < size; i++)
            {
                if (this[i] != null && exponent[i] != null)
                {
                    // (fx^gx)' = (e^(gx*ln(fx)))'
                    // = gx*fx^(gx-1)*f'x + fx^gx*ln(fx)*g'x
                    var ai = this[i];
                    var bi = exponent[i];
                    result[i] = () =>
                    {
                        var tmpa0 = Math.Abs(a0());
                        var tmpb0 = b0();
                        return(SafePow(tmpa0, tmpb0 - 1) * tmpb0 * ai() + SafePow(tmpa0, tmpb0) * Math.Log(tmpa0) * bi());
                    };
                }
                else if (this[i] != null)
                {
                    // (fx^b)' = b * fx^(b-1) * f'x
                    var ai = this[i];
                    result[i] = () =>
                    {
                        var tmpa0 = Math.Abs(a0());
                        var tmpb0 = b0();
                        return(SafePow(tmpa0, tmpb0 - 1) * tmpb0 * ai());
                    };
                }
                else if (exponent[i] != null)
                {
                    // (a^gx)' = a^gx * ln(a) * g'x
                    var bi = exponent[i];
                    result[i] = () =>
                    {
                        var tmpa0 = Math.Abs(a0());
                        var tmpb0 = b0();
                        return(SafePow(tmpa0, tmpb0) * Math.Log(tmpa0) * bi());
                    };
                }
            }
            return(result);
        }
Пример #17
0
        /// <summary>
        /// Multiply derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The multiplied result.
        /// </returns>
        public override Derivatives <Expression> Multiply(Derivatives <Expression> b)
        {
            var        size = Math.Max(Count, b.Count);
            var        result = new ExpressionTreeDerivatives(size);
            Expression a0 = this[0], b0 = b[0];

            if (a0 == null || b0 == null)
            {
                return(result); // x*0 = 0 and so is all its derivatives
            }
            else
            {
                result[0] = Expression.Multiply(a0, b0);
            }

            for (var i = 1; i < size; i++)
            {
                if (this[i] == null)
                {
                    if (b[i] == null)
                    {
                        result[i] = null;
                    }
                    else
                    {
                        // (a*gx)' = a*g'x
                        result[i] = Expression.Multiply(a0, b[i]);
                    }
                }
                else
                {
                    if (b[i] == null)
                    {
                        // (fx*b)' = f'x*b
                        result[i] = Expression.Multiply(this[i], b0);
                    }
                    else
                    {
                        // (fx*gx)' = fx*g'x + f'x*gx
                        result[i] = Expression.Add(
                            Expression.Multiply(a0, b[i]),
                            Expression.Multiply(this[i], b0));
                    }
                }
            }
            return(result);
        }
Пример #18
0
        /// <summary>
        /// Conditional derivatives.
        /// </summary>
        /// <param name="iftrue">Argument if true.</param>
        /// <param name="iffalse">Argument if false.</param>
        /// <returns>
        /// The derivatives.
        /// </returns>
        public override Derivatives <Expression> IfThenElse(Derivatives <Expression> iftrue, Derivatives <Expression> iffalse)
        {
            if (this[0] == null)
            {
                return(iffalse);
            }
            var size         = Math.Max(iftrue.Count, iffalse.Count);
            var result       = new ExpressionTreeDerivatives(size);
            var notcondition = Expression.Equal(this[0], Zero);

            for (var i = 0; i < size; i++)
            {
                var iftruei  = iftrue[i];
                var iffalsei = iffalse[i];
                if (iftruei == null && iffalsei == null)
                {
                    continue;
                }
                result[i] = Expression.Condition(notcondition, iffalsei ?? Zero, iftruei ?? Zero);
            }
            return(result);
        }
Пример #19
0
        /// <summary>
        /// Divide derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The divided result.
        /// </returns>
        public override Derivatives <Func <double> > Divide(Derivatives <Func <double> > b)
        {
            var size   = Math.Max(Count, b.Count);
            var result = new DoubleDerivatives(size);
            var a0     = this[0];
            var b0     = b[0];

            result[0] = () => SafeDivide(a0(), b0());
            for (var i = 1; i < size; i++)
            {
                var ai = this[i];
                var bi = b[i];
                if (ai != null && bi != null)
                {
                    result[i] = () =>
                    {
                        var denom = b0();
                        return(SafeDivide(denom * ai() - a0() * bi(), denom * denom));
                    }
                }
                ;
                else if (ai != null)
                {
                    result[i] = () => SafeDivide(ai(), b0());
                }
                else if (bi != null)
                {
                    result[i] = () =>
                    {
                        var denom = b0();
                        return(-SafeDivide(a0() * bi(), denom * denom));
                    }
                }
                ;
            }
            return(result);
        }
Пример #20
0
        /// <summary>
        /// Subtract derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The difference.
        /// </returns>
        public override Derivatives <Func <double> > Subtract(Derivatives <Func <double> > b)
        {
            var size   = Math.Max(Count, b.Count);
            var result = new DoubleDerivatives(size);

            for (var i = 0; i < size; i++)
            {
                var arg1 = this[i];
                var arg2 = b[i];
                if (arg1 != null && arg2 != null)
                {
                    result[i] = () => arg1() - arg2();
                }
                else if (arg1 != null)
                {
                    result[i] = arg1;
                }
                else if (arg2 != null)
                {
                    result[i] = () => - arg2();
                }
            }
            return(result);
        }
Пример #21
0
        /// <summary>
        /// Add derivatives.
        /// </summary>
        /// <param name="b">The other operand.</param>
        /// <returns>
        /// The sum.
        /// </returns>
        public override Derivatives <Func <double> > Add(Derivatives <Func <double> > b)
        {
            var size   = Math.Max(Count, b.Count);
            var result = new DoubleDerivatives(size);

            for (var i = 0; i < size; i++)
            {
                var ai = this[i];
                var bi = b[i];
                if (ai != null && bi != null)
                {
                    result[i] = () => ai() + bi();
                }
                else if (ai != null)
                {
                    result[i] = ai;
                }
                else if (bi != null)
                {
                    result[i] = bi;
                }
            }
            return(result);
        }
Пример #22
0
 /// <summary>
 /// Check less than.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>A value representing true if this is less.</returns>
 public abstract Derivatives <T> LessThan(Derivatives <T> b);
Пример #23
0
 /// <summary>
 /// Subtract derivatives.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>The difference.</returns>
 public abstract Derivatives <T> Subtract(Derivatives <T> b);
Пример #24
0
 /// <summary>
 /// Multiply derivatives.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>The multiplied result.</returns>
 public abstract Derivatives <T> Multiply(Derivatives <T> b);
Пример #25
0
 /// <summary>
 /// Check greater or equal.
 /// </summary>
 /// <param name="b">The operand.</param>
 /// <returns>A value representing true if this is greater or equal.</returns>
 public abstract Derivatives <T> GreaterOrEqual(Derivatives <T> b);
Пример #26
0
 /// <summary>
 /// Divide derivatives.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>The divided result.</returns>
 public abstract Derivatives <T> Divide(Derivatives <T> b);
Пример #27
0
 /// <summary>
 /// Modulo operation on derivatives.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>The remainder of the division.</returns>
 public abstract Derivatives <T> Modulo(Derivatives <T> b);
Пример #28
0
 /// <summary>
 /// Check less or equal.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>A value representing true if this is less or equal.</returns>
 public abstract Derivatives <T> LessOrEqual(Derivatives <T> b);
Пример #29
0
 /// <summary>
 /// Check greater than.
 /// </summary>
 /// <param name="b">The other operand.</param>
 /// <returns>A value representing true if this is greater.</returns>
 public abstract Derivatives <T> GreaterThan(Derivatives <T> b);
Пример #30
0
        /// <summary>
        /// Execute an operator.
        /// </summary>
        /// <param name="op">The operator.</param>
        protected override void ExecuteOperator(Operator op)
        {
            Derivatives <Expression> a, b;

            switch (op)
            {
            case TernaryOperator to:
                b = _stack.Pop();
                a = _stack.Pop();
                _stack.Push(_stack.Pop().IfThenElse(a, b));
                break;

            case ClosingTernaryOperator _:
                break;

            case FunctionOperator fo:

                // Extract all arguments for the method
                var arguments = new Derivatives <Expression> [fo.Arguments];
                for (var i = fo.Arguments - 1; i >= 0; i--)
                {
                    arguments[i] = _stack.Pop();
                }
                var args = new FunctionFoundEventArgs <Derivatives <Expression> >(fo.Name, null, arguments);

                // Ask around for the result of this method
                FunctionFound?.Invoke(this, args);
                if (!args.Found || args.Result == null)
                {
                    throw new ParserException("Unrecognized method '{0}()'".FormatString(fo.Name), Input, Index);
                }
                _stack.Push(args.Result);
                break;

            case BracketOperator _:
                break;

            case ArgumentOperator _:
                break;

            case ArithmeticOperator ao:
                switch (ao.Type)
                {
                case OperatorType.Positive:
                    break;

                case OperatorType.Negative:
                    _stack.Push(_stack.Pop().Negate());
                    break;

                case OperatorType.Not:
                    _stack.Push(_stack.Pop().Not());
                    break;

                case OperatorType.Add:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Add(b));
                    break;

                case OperatorType.Subtract:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Subtract(b));
                    break;

                case OperatorType.Multiply:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Multiply(b));
                    break;

                case OperatorType.Divide:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Divide(b));
                    break;

                case OperatorType.Power:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Pow(b));
                    break;

                case OperatorType.ConditionalOr:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Or(b));
                    break;

                case OperatorType.ConditionalAnd:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().And(b));
                    break;

                case OperatorType.GreaterThan:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().GreaterThan(b));
                    break;

                case OperatorType.LessThan:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().LessThan(b));
                    break;

                case OperatorType.GreaterThanOrEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().GreaterOrEqual(b));
                    break;

                case OperatorType.LessThanOrEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().LessOrEqual(b));
                    break;

                case OperatorType.IsEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Equal(b));
                    break;

                case OperatorType.IsNotEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().NotEqual(b));
                    break;

                default:
                    throw new ParserException("Unimplemented arithmetic operator", Input, Index);
                }
                break;

            default:
                throw new ParserException("Unimplemented operator", Input, Index);
            }
        }