internal ScaleOffsetExpression(VectorParameterExpression operand, T scale, T offset)
     : base(UnaryElementWiseOperation.ScaleOffset, operand)
 {
     Operand = operand;
     Scale   = scale;
     Offset  = offset;
 }
Exemple #2
0
 public void AddBinaryElementWiseOperation <T>(VectorParameterExpression a, VectorParameterExpression b,
                                               VectorParameterExpression result, ExpressionType operation)
 {
     _operations.Add(
         Expression.Assign(result,
                           Expression.MakeBinary(operation, a, b))
         );
 }
 protected Expression VisitParameter(VectorParameterExpression variable, StringBuilder builder)
 {
     Write(variable.Name, builder);
     if (variable.ParameterType == Expressions.ParameterType.Argument)
     {
         Write(indexing, builder);
     }
     return(variable);
 }
Exemple #4
0
        public Expression AddInverseExpression(VectorParameterExpression a)
        {
            var paramA = a as ReferencingVectorParameterExpression <double>;

            if (paramA.IsScalar)
            {
                return(new ConstantExpression <double>(1 / paramA.ScalarValue));
            }
            return(AddLocalAssignment <double>(new ScaleInverseExpression <double>(a, 1)));
        }
Exemple #5
0
        public Expression AddHalfInverseSquareRootExpression(VectorParameterExpression a)
        {
            var paramA = a as ReferencingVectorParameterExpression <double>;

            if (paramA.IsScalar)
            {
                return(new ConstantExpression <double>(0.5 / Math.Sqrt(paramA.ScalarValue)));
            }
            var newLocal = AddLocalAssignment <double>(new ScaleInverseExpression <double>(a, 1));

            return(AddLocalAssignment <double>(new ScaleOffsetExpression <double>(newLocal, 0.5, 0)));
        }
        /// <summary>
        /// Performs reverse-mode (adjoint) automatic differentiation 
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="dependentVariable"></param>
        /// <param name="independentVariables"></param>
        public static void Differentiate(BlockExpressionBuilder builder, 
            out IList<Expression> derivativeExpressions,
            VectorParameterExpression dependentVariable,
            params VectorParameterExpression[] independentVariables)
        {
            if (independentVariables.Length == 0)
            {
                derivativeExpressions = null;
                return;
            }

            var block = builder.ToBlock();
            // change the numbering of variables; arguments first, then locals
            List<int>[] jLookup;
            Function[] f;

            // we want a list of functions which can be unary or binary (in principle high order if it makes sense) and a look-up
            // each function is associated with a parameter, which is either an argument or a local
            // for each function index we return a list of the indices of the functions that reference the parameter
            GetFunctions(block, out f, out jLookup);

            int N = dependentVariable.Index;

            bool[] derivativeRequired; int[] derivativeExpressionIndex;
            IdentifyNeccesaryDerivatives(N, jLookup, independentVariables, out derivativeRequired, out derivativeExpressionIndex);

            // the list of operations needed to calculate the derivatives (*all* derivatives)
            derivativeExpressions = new Expression[independentVariables.Length];
            var dxNdx = new Expression[N + 1];
            dxNdx[N] = new ConstantExpression<double>(1.0);
            for (int i = N - 1; i >= 0; i--)
            {
                if (!derivativeRequired[i]) continue;
                // dxN / dxi
                // need to find all operation indices j such that p(j) contains i
                // that is, all functions that have xi as an argument (these must therefore have a higher index than i)
                VectorParameterExpression total = new ConstantExpression<double>(0);
                var xi = f[i].Parameter;
                //need sum of dfj/dxi dXN/dxj
                foreach (var j in jLookup[i])
                {
                    var fj = f[j];
                    var dfjdxi = Differentiate(fj, xi, builder); // dfj/dxi
                    var dXNdxj = dxNdx[j]; // dXN/dxj
                    var product = builder.AddProductExpression(dfjdxi, dXNdxj);
                    total = builder.AddAdditionExpression(total, product);
                }
                dxNdx[i] = total;
                int targetIndex = derivativeExpressionIndex[i];
                if (targetIndex != -1) derivativeExpressions[targetIndex] = total;
            }
        }
Exemple #7
0
        public Expression AddGaussian(VectorParameterExpression a)
        {
            var paramA = a as ReferencingVectorParameterExpression <double>;

            if (paramA.IsScalar)
            {
                return(new ConstantExpression <double>(_gaussianScaling * Math.Exp(-paramA.ScalarValue * paramA.ScalarValue / 2)));
            }
            var newLocal1 = AddLocalAssignment <double>(Expression.MakeBinary(ExpressionType.Multiply, paramA, paramA));
            var newLocal2 = AddLocalAssignment <double>(new ScaleOffsetExpression <double>(newLocal1, -0.5, 0));
            var newLocal3 = AddLocalAssignment <double>(new UnaryMathsExpression(UnaryElementWiseOperation.Exp, newLocal2));

            return(AddLocalAssignment <double>(new ScaleOffsetExpression <double>(newLocal3, _gaussianScaling, 0)));
        }
Exemple #8
0
        /// <summary>
        /// Adds a division and negation expression efficiently; assumes that scalar independent variables can be combined
        /// i.e. that any differentiation has already occurred
        /// </summary>
        public Expression AddNegateDivideExpression(VectorParameterExpression a, VectorParameterExpression b)
        {
            var paramA = a as ReferencingVectorParameterExpression <double>;
            var paramB = b as ReferencingVectorParameterExpression <double>;

            if (paramA.IsScalar && paramB.IsScalar)
            {
                return(new ConstantExpression <double>(
                           -paramA.ScalarValue /
                           paramB.ScalarValue));
            }
            var newLocal = AddLocalAssignment <double>(Expression.Divide(a, b));

            return(AddLocalAssignment <double>(new ScaleOffsetExpression <double>(newLocal, -1, 0)));
        }
 public VectorOperationExpression(VectorParameterExpression result)
 {
     Result = result;
 }
Exemple #10
0
 public static ScaleOffsetExpression <T> ScaleOffset <T>(VectorParameterExpression operand, T scale, T offset)
 {
     return(new ScaleOffsetExpression <T>(operand, scale, offset));
 }
Exemple #11
0
 public static ScaleInverseExpression <T> ScaleInverse <T>(VectorParameterExpression operand, T scale)
 {
     return(new ScaleInverseExpression <T>(operand, scale));
 }
Exemple #12
0
 public static UnaryMathsExpression MakeUnary(UnaryElementWiseOperation unaryType, VectorParameterExpression operand)
 {
     return(new UnaryMathsExpression(unaryType, operand));
 }
Exemple #13
0
 internal UnaryMathsExpression(UnaryElementWiseOperation unaryType, VectorParameterExpression operand)
 {
     UnaryType = unaryType;
     Operand   = operand;
 }
Exemple #14
0
 public VectorOperationExpression(VectorParameterExpression result)
 {
     Result = result;
 }
 private static void UpdateOperationIndices(List<int>[] operationIndices, 
     VectorParameterExpression expression, int operationIndex)
 {
     if (expression.Index != -1) operationIndices[expression.Index].Add(operationIndex); // -1 indices a constant
 }
 private static void IdentifyNeccesaryDerivatives(int N, List<int>[] jLookup,
     VectorParameterExpression[] independentVariables,
     out bool[] derivativeRequired, out int[] derivativeExpressionIndex)
 {
     derivativeRequired = new bool[N + 1]; // true if the derivative expression is required
     derivativeExpressionIndex = Enumerable.Repeat(-1, N + 1).ToArray();
     // the index of the independent variable that the derivative expression refers to
     for (int i = 0; i < independentVariables.Length; ++i)
     {
         int expessionindex = independentVariables[i].Index;
         derivativeExpressionIndex[expessionindex] = i;
         derivativeRequired[expessionindex] = true;
     }
     for (int i = 0; i < N; i++)
     {
         if (derivativeRequired[i])
         {
             foreach (int j in jLookup[i])
             {
                 derivativeRequired[j] = true;
             }
         }
     }
 }
Exemple #17
0
 private static NArray <T> GetArray <T>(VectorParameterExpression expression)
 {
     return((expression as ReferencingVectorParameterExpression <T>).Array);
 }
Exemple #18
0
 internal ScaleInverseExpression(VectorParameterExpression operand, T scale)
     : base(UnaryElementWiseOperation.ScaleInverse, operand)
 {
     Scale = scale;
 }