using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
namespace AutoDiff
{
///
/// A collection of static methods to build new terms
///
public static class TermBuilder
{
///
/// Builds a new constant term.
///
/// The constant value
/// The constant term.
public static Term Constant(double value)
{
Contract.Ensures(Contract.Result() != null);
if (value == 0)
return new Zero();
else
return new Constant(value);
}
///
/// Builds a sum of given terms.
///
/// The collection of terms in the sum.
/// A term representing the sum of the terms in .
public static Sum Sum(IEnumerable terms)
{
Contract.Requires(terms.Where(term => !(term is Zero)).Count() >= 2); // require at-least two non-zero terms.
Contract.Requires(Contract.ForAll(terms, term => term != null));
Contract.Ensures(Contract.Result() != null);
terms = terms.Where(term => !(term is Zero));
return new Sum(terms);
}
///
/// Builds a sum of given terms.
///
/// The first term in the sum
/// The second term in the sum
/// The rest of the terms in the sum.
/// A term representing the sum of , and the terms in .
public static Sum Sum(Term v1, Term v2, params Term[] rest)
{
Contract.Requires(v1 != null);
Contract.Requires(v2 != null);
Contract.Requires(Contract.ForAll(rest, term => term != null));
Contract.Ensures(Contract.Result() != null);
var allTerms = new Term[] { v1, v2 }.Concat(rest);
return Sum(allTerms);
}
///
/// Builds a product of given terms.
///
/// The first term in the product
/// The second term in the product
/// The rest of the terms in the product
/// A term representing the product of , and the terms in .
public static Term Product(Term v1, Term v2, params Term[] rest)
{
Contract.Requires(v1 != null);
Contract.Requires(v2 != null);
Contract.Requires(Contract.ForAll(rest, term => term != null));
Contract.Ensures(Contract.Result() != null);
var result = new Product(v1, v2);
foreach (var item in rest)
result = new Product(result, item);
return result;
}
///
/// Builds a power terms given a base and a constant exponent
///
/// The power base term
/// The exponent
/// A term representing t^power.
public static Term Power(Term t, double power)
{
Contract.Requires(t != null);
Contract.Ensures(Contract.Result() != null);
return new ConstPower(t, power);
}
///
/// Builds a power term given a base term and an exponent term.
///
/// The base term
/// The exponent term
///
public static Term Power(Term baseTerm, Term exponent)
{
Contract.Requires(baseTerm != null);
Contract.Requires(exponent != null);
Contract.Ensures(Contract.Result() != null);
return new TermPower(baseTerm, exponent);
}
///
/// Builds a term representing the exponential function e^x.
///
/// The function's exponent
/// A term representing e^arg.
public static Term Exp(Term arg)
{
Contract.Requires(arg != null);
Contract.Ensures(Contract.Result() != null);
return new Exp(arg);
}
///
/// Builds a term representing the natural logarithm.
///
/// The natural logarithm's argument.
/// A term representing the natural logarithm of
public static Term Log(Term arg)
{
Contract.Requires(arg != null);
Contract.Ensures(Contract.Result() != null);
return new Log(arg);
}
///
/// Constructs a 2D quadratic form given the vector components x1, x2 and the matrix coefficients a11, a12, a21, a22.
///
/// First vector component
/// Second vector component
/// First row, first column matrix component
/// First row, second column matrix component
/// Second row, first column matrix component
/// Second row, second column matrix component
/// A term describing the quadratic form
public static Term QuadForm(Term x1, Term x2, Term a11, Term a12, Term a21, Term a22)
{
Contract.Requires(x1 != null);
Contract.Requires(x2 != null);
Contract.Requires(a11 != null);
Contract.Requires(a12 != null);
Contract.Requires(a21 != null);
Contract.Requires(a22 != null);
Contract.Ensures(Contract.Result() != null);
return Sum(a11 * Power(x1, 2), (a12 + a21) * x1 * x2, a22 * Power(x2, 2));
}
}
}