148 lines
6.0 KiB
C#
148 lines
6.0 KiB
C#
|
|
/*
|
|||
|
|
Math.Nhtsa.Differentiation.cs
|
|||
|
|
|
|||
|
|
24 November 2009 - Adapted from old Dave codebase to generic DTS utility, with
|
|||
|
|
appropriate name change.
|
|||
|
|
|
|||
|
|
$Log: Math.Nhtsa.ChannelDifferentiation.cs,v $
|
|||
|
|
Revision 1.2 2007/04/20 17:40:42 Paul Hrissikopoulos
|
|||
|
|
Fixed bad range checking in sample rate property set accessor.
|
|||
|
|
|
|||
|
|
Revision 1.1 2007/02/05 17:17:08 Paul Hrissikopoulos
|
|||
|
|
Finished installing generic channel math framework + basic calculus operations.
|
|||
|
|
|
|||
|
|
Copyright <EFBFBD> 2007
|
|||
|
|
Diversified Technical Systems, Inc.
|
|||
|
|
All Rights Reserved
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Text;
|
|||
|
|
using DTS.Common.Utilities.DotNetProgrammingConstructs;
|
|||
|
|
|
|||
|
|
namespace DTS.Common.Utilities.Math.Nhtsa
|
|||
|
|
{
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
/// <summary>
|
|||
|
|
/// Representation of a NHTSA-based differentiation channel operation.
|
|||
|
|
/// </summary>
|
|||
|
|
public class Differentiation : DoubleListOperation
|
|||
|
|
{
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
/// <summary>
|
|||
|
|
/// Get/set the sample rate for this data to be differentiated.
|
|||
|
|
/// </summary>
|
|||
|
|
public double SampleRate
|
|||
|
|
{
|
|||
|
|
get => _SampleRate.Value;
|
|||
|
|
set => _SampleRate.Value = value;
|
|||
|
|
}
|
|||
|
|
private Property<double> _SampleRate
|
|||
|
|
= new Property<double>(
|
|||
|
|
typeof(Differentiation).FullName + ".SampleRate",
|
|||
|
|
0.0,
|
|||
|
|
false
|
|||
|
|
);
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
/// <summary>
|
|||
|
|
/// Initialize an instance of the ChannelDifferentiation class.
|
|||
|
|
/// </summary>
|
|||
|
|
///
|
|||
|
|
/// <param name="domain">
|
|||
|
|
/// The System.Collections.Generic.IList of <see cref="double"/> domain for
|
|||
|
|
/// this operation.
|
|||
|
|
/// </param>
|
|||
|
|
///
|
|||
|
|
public Differentiation(IList<double> domain)
|
|||
|
|
: base(domain)
|
|||
|
|
{ //
|
|||
|
|
// I'd prefer to do this statically, but I don't know of any C# way to place a constraint
|
|||
|
|
// on a generic type that's already been determined by some ancestor we're inheriting from,
|
|||
|
|
// so for now we'll have to dynamically check it on object instantiation.
|
|||
|
|
//
|
|||
|
|
if (!(domain is ICloneable))
|
|||
|
|
throw new InvalidCastException("the domain type for " + typeof(Differentiation).FullName + " must be ICloneable");
|
|||
|
|
}
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
/// <summary>
|
|||
|
|
/// Initialize an instance of the Iso.ChannelDifferentiation class.
|
|||
|
|
/// </summary>
|
|||
|
|
///
|
|||
|
|
/// <param name="domain">
|
|||
|
|
/// The System.Collections.Generic.IList of <see cref="double"/> domain for
|
|||
|
|
/// this operation.
|
|||
|
|
/// </param>
|
|||
|
|
///
|
|||
|
|
/// <param name="sampleRate">
|
|||
|
|
/// The <see cref="int"/> sample rate of the channel to be differentiated.
|
|||
|
|
/// </param>
|
|||
|
|
///
|
|||
|
|
public Differentiation(IList<double> domain, int sampleRate)
|
|||
|
|
: this(domain)
|
|||
|
|
{
|
|||
|
|
try { SampleRate = sampleRate; }
|
|||
|
|
catch (System.Exception ex)
|
|||
|
|
{
|
|||
|
|
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
/// <summary>
|
|||
|
|
/// Get the System.Collections.Generic.IList of <see cref="double"/> result of
|
|||
|
|
/// the operation on the target domain.
|
|||
|
|
/// </summary>
|
|||
|
|
public override IList<double> Range
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (null == Domain)
|
|||
|
|
throw new ArgumentNullException("attempted to differentiate null channel reference");
|
|||
|
|
|
|||
|
|
else if (0 >= SampleRate)
|
|||
|
|
throw new ArgumentOutOfRangeException("SampleRate must be greater than zero");
|
|||
|
|
|
|||
|
|
else if (!(Domain is ICloneable))
|
|||
|
|
throw new InvalidCastException("the domain type for " + typeof(Differentiation).FullName + " must be ICloneable");
|
|||
|
|
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
var IndexOfLastSample = Domain.Count - 1;
|
|||
|
|
var deltaT = SampleRate / 2;
|
|||
|
|
var range = ((ICloneable)Domain).Clone() as IList<double>;
|
|||
|
|
|
|||
|
|
for (var t = 1; t < IndexOfLastSample; t++)
|
|||
|
|
range[t] = (Domain[t + 1] - Domain[t - 1]) * deltaT;
|
|||
|
|
|
|||
|
|
range[0] = (-7 * Domain[0]
|
|||
|
|
+ 6 * Domain[1]
|
|||
|
|
+ 3 * Domain[2]
|
|||
|
|
- 2 * Domain[3]) * deltaT / 3;
|
|||
|
|
|
|||
|
|
range[IndexOfLastSample] = (-7 * Domain[IndexOfLastSample]
|
|||
|
|
+ 6 * Domain[IndexOfLastSample - 1]
|
|||
|
|
+ 3 * Domain[IndexOfLastSample - 2]
|
|||
|
|
- 2 * Domain[IndexOfLastSample - 3]) * deltaT / 3;
|
|||
|
|
return range;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
catch (System.Exception ex)
|
|||
|
|
{
|
|||
|
|
throw new Exception("encountered problem doing " + GetType().FullName + " operation", ex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
}
|
|||
|
|
////////////////////////////////////////////////////////////////////////////////
|
|||
|
|
}
|