[8703] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System.Linq;
|
---|
| 4 | using System.Text;
|
---|
| 5 | using System.Diagnostics.Contracts;
|
---|
| 6 |
|
---|
| 7 | namespace AutoDiff
|
---|
| 8 | {
|
---|
| 9 | /// <summary>
|
---|
| 10 | /// Base class for all automatically-differentiable terms.
|
---|
| 11 | /// </summary>
|
---|
| 12 | [Serializable]
|
---|
| 13 | [ContractClass(typeof(TermContacts))]
|
---|
| 14 | public abstract class Term
|
---|
| 15 | {
|
---|
| 16 | /// <summary>
|
---|
| 17 | /// Accepts a term visitor
|
---|
| 18 | /// </summary>
|
---|
| 19 | /// <param name="visitor">The term visitor to accept</param>
|
---|
| 20 | public abstract void Accept(ITermVisitor visitor);
|
---|
| 21 |
|
---|
| 22 | /// <summary>
|
---|
| 23 | /// Accepts a term visitor with a generic result
|
---|
| 24 | /// </summary>
|
---|
| 25 | /// <typeparam name="TResult">The type of the result from the visitor's function</typeparam>
|
---|
| 26 | /// <param name="visitor">The visitor to accept</param>
|
---|
| 27 | /// <returns>The result from the visitor's visit function.</returns>
|
---|
| 28 | public abstract TResult Accept<TResult>(ITermVisitor<TResult> visitor);
|
---|
| 29 |
|
---|
| 30 | /// <summary>
|
---|
| 31 | /// Converts a floating point constant to a constant term.
|
---|
| 32 | /// </summary>
|
---|
| 33 | /// <param name="value">The floating point constnat</param>
|
---|
| 34 | /// <returns>The resulting term.</returns>
|
---|
| 35 | public static implicit operator Term(double value)
|
---|
| 36 | {
|
---|
| 37 | return TermBuilder.Constant(value);
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | /// <summary>
|
---|
| 41 | /// Constructs a sum of the two given terms.
|
---|
| 42 | /// </summary>
|
---|
| 43 | /// <param name="left">First term in the sum</param>
|
---|
| 44 | /// <param name="right">Second term in the sum</param>
|
---|
| 45 | /// <returns>A term representing the sum of <paramref name="left"/> and <paramref name="right"/>.</returns>
|
---|
| 46 | public static Term operator+(Term left, Term right)
|
---|
| 47 | {
|
---|
| 48 | if (left is Zero && right is Zero)
|
---|
| 49 | return new Zero();
|
---|
| 50 | else if (left is Zero)
|
---|
| 51 | return right;
|
---|
| 52 | else if (right is Zero)
|
---|
| 53 | return left;
|
---|
| 54 | else
|
---|
| 55 | return TermBuilder.Sum(left, right);
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | /// <summary>
|
---|
| 59 | /// Constructs a product term of the two given terms.
|
---|
| 60 | /// </summary>
|
---|
| 61 | /// <param name="left">The first term in the product</param>
|
---|
| 62 | /// <param name="right">The second term in the product</param>
|
---|
| 63 | /// <returns>A term representing the product of <paramref name="left"/> and <paramref name="right"/>.</returns>
|
---|
| 64 | public static Term operator*(Term left, Term right)
|
---|
| 65 | {
|
---|
| 66 | return TermBuilder.Product(left, right);
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | /// <summary>
|
---|
| 70 | /// Constructs a fraction term of the two given terms.
|
---|
| 71 | /// </summary>
|
---|
| 72 | /// <param name="numerator">The numerator of the fraction. That is, the "top" part.</param>
|
---|
| 73 | /// <param name="denominator">The denominator of the fraction. That is, the "bottom" part.</param>
|
---|
| 74 | /// <returns>A term representing the fraction <paramref name="numerator"/> over <paramref name="denominator"/>.</returns>
|
---|
| 75 | public static Term operator/(Term numerator, Term denominator)
|
---|
| 76 | {
|
---|
| 77 | return TermBuilder.Product(numerator, TermBuilder.Power(denominator, -1));
|
---|
| 78 | }
|
---|
| 79 |
|
---|
| 80 | /// <summary>
|
---|
| 81 | /// Constructs a difference of the two given terms.
|
---|
| 82 | /// </summary>
|
---|
| 83 | /// <param name="left">The first term in the difference</param>
|
---|
| 84 | /// <param name="right">The second term in the difference.</param>
|
---|
| 85 | /// <returns>A term representing <paramref name="left"/> - <paramref name="right"/>.</returns>
|
---|
| 86 | public static Term operator-(Term left, Term right)
|
---|
| 87 | {
|
---|
| 88 | return left + (-1) * right;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | /// <summary>
|
---|
| 92 | /// Constructs a negated term
|
---|
| 93 | /// </summary>
|
---|
| 94 | /// <param name="term">The term to negate</param>
|
---|
| 95 | /// <returns>A term representing <c>-term</c>.</returns>
|
---|
| 96 | public static Term operator-(Term term)
|
---|
| 97 | {
|
---|
| 98 | return (-1) * term;
|
---|
| 99 | }
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | [ContractClassFor(typeof(Term))]
|
---|
| 103 | abstract class TermContacts : Term
|
---|
| 104 | {
|
---|
| 105 | public override void Accept(ITermVisitor visitor)
|
---|
| 106 | {
|
---|
| 107 | Contract.Requires(visitor != null);
|
---|
| 108 | }
|
---|
| 109 |
|
---|
| 110 | public override TResult Accept<TResult>(ITermVisitor<TResult> visitor)
|
---|
| 111 | {
|
---|
| 112 | Contract.Requires(visitor != null);
|
---|
| 113 | return default(TResult);
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | }
|
---|