public class DualNumber
{
#region Data Members
private double m_FunctionValue;
private double m_DerivativeValue;
private static readonly DualNumber m_Zero = new DualNumber(0, 0);
private static readonly DualNumber m_One = new DualNumber(1, 0);
#endregion
#region Constructors
public DualNumber(double functionValue,
double derivativeValue)
{
m_FunctionValue = functionValue;
m_DerivativeValue = derivativeValue;
}
public DualNumber(DualNumber source) :
this(source.FunctionValue,
source.DerivativeValue)
{
}
#endregion
#region Constants
public static DualNumber ONE
{
get
{
return m_One;
}
}
public static DualNumber ZERO
{
get
{
return m_Zero;
}
}
#endregion
#region Binary Methods
private DualNumber Add(DualNumber givenDual)
{
return new DualNumber(this.FunctionValue + givenDual.FunctionValue,
this.DerivativeValue + givenDual.DerivativeValue);
}
private DualNumber Sub(DualNumber givenDual)
{
return new DualNumber(this.FunctionValue - givenDual.FunctionValue,
this.DerivativeValue - givenDual.DerivativeValue);
}
private DualNumber Mul(DualNumber givenDual)
{
return new DualNumber(this.FunctionValue * givenDual.FunctionValue,
this.DerivativeValue * givenDual.FunctionValue+
this.FunctionValue * givenDual.DerivativeValue);
}
private DualNumber Div(DualNumber givenDual)
{
return new DualNumber(this.FunctionValue / givenDual.FunctionValue,
(this.DerivativeValue * givenDual.FunctionValue -
this.FunctionValue * givenDual.DerivativeValue)/
(givenDual.FunctionValue * givenDual.FunctionValue));
}
private DualNumber Power(int exp)
{
if (exp >= 0)
{
return this.PositivePower(exp);
}
else
{
return (this.Opposite.PositivePower(-exp));
}
}
private DualNumber Opposite
{
get
{
return new DualNumber(1/this.FunctionValue,
-this.DerivativeValue/(this.FunctionValue * this.FunctionValue));
}
}
private DualNumber PositivePower(int exp)
{
DualNumber powerResult = DualNumber.ONE;
DualNumber loopPower = new DualNumber(this);
int loopCurrentPower = exp;
while (loopCurrentPower != 0)
{
if (loopCurrentPower % 2 == 1)
{
powerResult = powerResult.Mul(loopPower);
}
loopPower = loopPower.Mul(loopPower);
loopCurrentPower /= 2;
}
return powerResult;
}
public override bool Equals(object obj)
{
if (!(obj is DualNumber))
{
return false;
}
else
{
DualNumber comparedDual = (DualNumber)obj;
return (this.FunctionValue.Equals(comparedDual.FunctionValue) &&
this.DerivativeValue.Equals(comparedDual.DerivativeValue));
}
}
public override int GetHashCode()
{
return (this.FunctionValue.GetHashCode() ^
this.DerivativeValue.GetHashCode());
}
#endregion
#region Unary Methods
public double FunctionValue
{
get
{
return m_FunctionValue;
}
}
public double DerivativeValue
{
get
{
return m_DerivativeValue;
}
}
#endregion
#region Operators
public static DualNumber operator +(DualNumber z1, DualNumber z2)
{
return z1.Add(z2);
}
public static DualNumber operator -(DualNumber z1, DualNumber z2)
{
return z1.Sub(z2);
}
public static DualNumber operator *(DualNumber z1, DualNumber z2)
{
return z1.Mul(z2);
}
public static DualNumber operator /(DualNumber z1, DualNumber z2)
{
return z1.Div(z2);
}
public static DualNumber operator ^(DualNumber z, int exp)
{
return z.Power(exp);
}
public static bool operator ==(DualNumber z1, DualNumber z2)
{
return z1.Equals(z2);
}
public static bool operator !=(DualNumber z1, DualNumber z2)
{
return (!z1.Equals(z2));
}
#endregion
#region Elementary functions
public static DualNumber Cos(DualNumber argument)
{
return new DualNumber(Math.Cos(argument.FunctionValue),
-Math.Sin(argument.FunctionValue)*
argument.DerivativeValue);
}
public static DualNumber Sin(DualNumber argument)
{
return new DualNumber(Math.Sin(argument.FunctionValue),
Math.Cos(argument.FunctionValue) *
argument.DerivativeValue);
}
public static DualNumber Exp(DualNumber argument)
{
return new DualNumber(Math.Exp(argument.FunctionValue),
Math.Exp(argument.FunctionValue) *
argument.DerivativeValue);
}
#endregion
}