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;
}
}
}