Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Push a double value.
        /// </summary>
        /// <param name="value">The value.</param>
        protected override void PushValue(double value)
        {
            var d = new ExpressionTreeDerivatives();

            d[0] = Expression.Constant(value);
            _stack.Push(d);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Negate the derivatives.
        /// </summary>
        /// <returns>
        /// The derivatives.
        /// </returns>
        public override Derivatives <Expression> Negate()
        {
            var result = new ExpressionTreeDerivatives(Count);

            for (var i = 0; i < Count; i++)
            {
                if (this[i] != null)
                {
                    result[i] = Expression.Negate(this[i]);
                }
            }
            return(result);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Not (binary) the derivatives.
        /// </summary>
        /// <returns>
        /// The derivatives.
        /// </returns>
        public override Derivatives <Expression> Not()
        {
            var result = new ExpressionTreeDerivatives(Count);

            if (this[0] != null)
            {
                result[0] = Expression.Condition(Expression.Equal(this[0], Zero), One, Zero);
            }
            else
            {
                result[0] = One;
            }
            return(result);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Apply a derivative.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index"></param>
        /// <param name="derivative"></param>
        public override void Apply(Func <double> value, int index, double derivative)
        {
            var result = new ExpressionTreeDerivatives();

            // Specify the actual value
            if (value != null)
            {
                result[0] = Expression.Call(Expression.Constant(value), InvokeMethod);
            }

            // Specify the derivative
            if (index > 0)
            {
                result[index] = Expression.Constant(derivative);
            }
            Result = result;
        }
Ejemplo n.º 13
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);
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="property">The property.</param>
 public ExpressionTreeDerivativePropertyEventArgs(SpiceProperty property)
     : base(property)
 {
     Result = null;
 }