using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics.Contracts; namespace AutoDiff { /// /// Static methods that operate on terms. /// public static class TermUtils { /// /// Creates a compiled representation of a given term that allows efficient evaluation of the value/gradient. /// /// The term to compile. /// The variables contained in the term. /// A compiled representation of that assigns values to variables in the same order /// as in /// /// The order of the variables in is important. Each call to ICompiledTerm.Evaluate or /// ICompiledTerm.Differentiate receives an array of numbers representing the point of evaluation. The i'th number in this array corresponds /// to the i'th variable in variables. /// public static ICompiledTerm Compile(this Term term, params Variable[] variables) { return Compile(term, variables); } /// /// Creates a compiled representation of a given term that allows efficient evaluation of the value/gradient. /// /// The term to compile. /// The variables contained in the term. /// A compiled representation of that assigns values to variables in the same order /// as in /// /// The order of the variables in is important. Each call to ICompiledTerm.Evaluate or /// ICompiledTerm.Differentiate receives an array of numbers representing the point of evaluation. The i'th number in this array corresponds /// to the i'th variable in variables. /// public static ICompiledTerm Compile(this Term term, T variables) where T : IList { Contract.Requires(variables != null); Contract.Requires(term != null); Contract.Ensures(Contract.Result() != null); Contract.Ensures(Contract.Result().Variables.Count == variables.Count); Contract.Ensures(Contract.ForAll(0, variables.Count, i => variables[i] == Contract.Result().Variables[i])); return new CompiledDifferentiator(term, variables); } /// /// Creates a compiled representation of a given term that allows efficient evaluation of the value/gradient where part of the variables serve as function /// inputs and other variables serve as constant parameters. /// /// The term to compile. /// The variables contained in the term. /// The constant parameters in the term. /// A compiled representation of that assigns values to variables in the same order /// as in and /// /// The order of the variables in is important. Each call to ICompiledTerm.Evaluate or /// ICompiledTerm.Differentiate receives an array of numbers representing the point of evaluation. The i'th number in this array corresponds /// to the i'th variable in variables. /// public static IParametricCompiledTerm Compile(this Term term, Variable[] variables, Variable[] parameters) { Contract.Requires(variables != null); Contract.Requires(parameters != null); Contract.Requires(term != null); Contract.Ensures(Contract.Result() != null); Contract.Ensures(Contract.Result().Variables.Count == variables.Length); Contract.Ensures(Contract.ForAll(0, variables.Length, i => variables[i] == Contract.Result().Variables[i])); Contract.Ensures(Contract.Result().Parameters.Count == parameters.Length); Contract.Ensures(Contract.ForAll(0, parameters.Length, i => parameters[i] == Contract.Result().Parameters[i])); return new ParametricCompiledTerm(term, variables, parameters); } /// /// Evaluates the function represented by a given term at a given point. /// /// The term representing the function to evaluate. /// The variables used in . /// The values assigned to the variables in /// The value of the function represented by at the point represented by /// and . /// The i'th value in point corresponds to the i'th variable in variables. public static double Evaluate(this Term term, Variable[] variables, double[] point) { Contract.Requires(term != null); Contract.Requires(variables != null); Contract.Requires(point != null); Contract.Requires(variables.Length == point.Length); return term.Compile(variables).Evaluate(point); } /// /// Computes the gradient of the function represented by a given term at a given point. /// /// The term representing the function to differentiate. /// The variables used in . /// The values assigned to the variables in /// The gradient of the function represented by at the point represented by /// and . /// The i'th value in point corresponds to the i'th variable in variables. In addition, the i'th value /// in the resulting array is the partial derivative with respect to the i'th variable in variables. public static double[] Differentiate(this Term term, Variable[] variables, double[] point) { Contract.Requires(term != null); Contract.Requires(variables != null); Contract.Requires(point != null); Contract.Requires(variables.Length == point.Length); Contract.Ensures(Contract.Result() != null); Contract.Ensures(Contract.Result().Length == variables.Length); var result = term.Compile(variables).Differentiate(point).Item1; return result; } } }