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