using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using System.Diagnostics.Contracts; namespace AutoDiff { /// /// Represents a term after it has been compiled for efficient evaluation/differentiation. /// [ContractClass(typeof(CompiledTermContract))] public interface ICompiledTerm { /// /// Evaluates the compiled term at the given point. /// /// The point at which to evaluate. /// The value of the function represented by the term at the given point. /// The number at arg[i] is the value assigned to the variable Variables[i]. double Evaluate(params double[] arg); /// /// Computes the gradient of the compiled term at the given point. /// /// The point at which to differentiate. /// A tuple, where the first item is the gradient at and the second item is /// the value at . That is, the second value is the same as running on /// . /// The number at arg[i] is the value assigned to the variable Variables[i]. Tuple Differentiate(T arg) where T : IList; /// /// Computes the gradient of the compiled term at the given point. /// /// The point at which to differentiate. /// A tuple, where the first item is the gradient at and the second item is /// the value at . That is, the second value is the same as running on /// . /// The number at arg[i] is the value assigned to the variable Variables[i]. Tuple Differentiate(params double[] arg); /// /// The collection of variables contained in this compiled term. /// /// /// The order of variables in this collection specifies the meaning of each argument in or /// . That is, the variable at Variables[i] corresponds to the i-th parameter of /// and . /// ReadOnlyCollection Variables { get; } } [ContractClassFor(typeof(ICompiledTerm))] abstract class CompiledTermContract : ICompiledTerm { public double Evaluate(params double[] arg) { Contract.Requires(arg != null); Contract.Requires(arg.Length == Variables.Count); return default(double); } public Tuple Differentiate(T arg) where T : IList { Contract.Requires(arg != null); Contract.Requires(arg.Count == Variables.Count); Contract.Ensures(Contract.Result>() != null); Contract.Ensures(Contract.Result>().Item1.Length == arg.Count); return null; } public Tuple Differentiate(params double[] arg) { Contract.Requires(arg != null); Contract.Requires(arg.Length == Variables.Count); Contract.Ensures(Contract.Result>() != null); Contract.Ensures(Contract.Result>().Item1.Length == arg.Length); return null; } public ReadOnlyCollection Variables { get { Contract.Ensures(Contract.Result>() != null); return null; } } } }