using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics.Contracts; namespace AutoDiff { /// /// Represents a custom binary function term. The user provides custom delegates /// to evaluate and compute the gradient of the function. /// public class BinaryFunc : Term { private readonly Func eval; private readonly Func> diff; private readonly Term left; private readonly Term right; /// /// Initializes a new instance of the class. /// /// The evaluation method for the custom function. /// The differentiation method for the custom function. /// The left argument term for the binary function. /// The right argument term for the binary function. public BinaryFunc( Func eval, Func> diff, Term left, Term right) { Contract.Requires(eval != null); Contract.Requires(diff != null); Contract.Requires(left != null); Contract.Requires(right != null); Contract.Ensures(Eval == eval); Contract.Ensures(Diff == diff); Contract.Ensures(Left == left); Contract.Ensures(Right == right); this.eval = eval; this.diff = diff; this.left = left; this.right = right; } /// /// Constructs a factory delegate that creates similary binary functions for different terms. /// /// The evaluation method for the custom function. /// The differentiation method for the custom function. /// The described factory delegate public static Func Factory(Func eval, Func> diff) { Contract.Requires(eval != null); Contract.Requires(diff != null); Contract.Ensures(Contract.Result < Func>() != null); Func result = (left, right) => new BinaryFunc(eval, diff, left, right); return result; } /// /// Gets the evaluation delegate /// public Func Eval { get { return eval; } } /// /// Gets the differentiation delegate /// public Func> Diff { get { return diff; } } /// /// Gets the function's left argument term /// public Term Left { get { return left; } } /// /// Gets the function's right argument term /// public Term Right { get { return right; } } /// /// Accepts a term visitor /// /// The term visitor to accept public override void Accept(ITermVisitor visitor) { visitor.Visit(this); } /// /// Accepts a term visitor with a generic result /// /// The type of the result from the visitor's function /// The visitor to accept /// The result from the visitor's visit function. public override TResult Accept(ITermVisitor visitor) { return visitor.Visit(this); } } }