using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
namespace AutoDiff
{
///
/// Represents a parametric term after it has been compiled for efficient evaluation/differentiation. A parametric
/// term has some variables that function as "constant parameters" and others that function as actual variables.
///
[ContractClass(typeof(ParametricCompiledTermContract))]
public interface IParametricCompiledTerm
{
///
/// Evaluates the compiled term at the given point.
///
/// The point at which to evaluate..
/// The parameter values
/// 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(double[] arg, double[] parameters);
///
/// Computes the gradient of the compiled term at the given point.
///
/// The point at which to differentiate.
/// The parameter values
/// 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
/// and .
/// The number at arg[i] is the value assigned to the variable Variables[i].
Tuple Differentiate(double[] arg, double[] parameters);
///
/// 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 element in the arg parameter of
/// and .
///
ReadOnlyCollection Variables { get; }
///
/// The collection of parameter 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 element in the parameters parameter of
/// and .
///
ReadOnlyCollection Parameters { get; }
}
[ContractClassFor(typeof(IParametricCompiledTerm))]
abstract class ParametricCompiledTermContract : IParametricCompiledTerm
{
public double Evaluate(double[] arg, double[] parameters)
{
Contract.Requires(arg != null);
Contract.Requires(arg.Length == Variables.Count);
Contract.Requires(parameters != null);
Contract.Requires(parameters.Length == Parameters.Count);
return default(double);
}
public Tuple Differentiate(double[] arg, double[] parameters)
{
Contract.Requires(arg != null);
Contract.Requires(arg.Length == Variables.Count);
Contract.Requires(parameters != null);
Contract.Requires(parameters.Length == Parameters.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;
}
}
public ReadOnlyCollection Parameters
{
get
{
Contract.Ensures(Contract.Result>() != null);
return null;
}
}
}
}