Compare commits

...

2 Commits

Author SHA1 Message Date
Christoph Ruegg d882558c85 Optimization: cleanup: naming 12 years ago
Christoph Ruegg d5b863945b Optimization: intitial csmpfit import 12 years ago
  1. 8
      LICENSE.md
  2. 6
      src/Numerics/Numerics.csproj
  3. 185
      src/Numerics/Optimization/DelimitedArray.cs
  4. 2519
      src/Numerics/Optimization/MPFit.cs
  5. 93
      src/Numerics/Optimization/MpConfig.cs
  6. 60
      src/Numerics/Optimization/MpFunc.cs
  7. 91
      src/Numerics/Optimization/MpResult.cs
  8. 98
      src/Numerics/Optimization/ParameterConstraint.cs
  9. 43
      src/UnitTests/OptimizationTests/CustomUserVariable.cs
  10. 138
      src/UnitTests/OptimizationTests/ForwardModels.cs
  11. 359
      src/UnitTests/OptimizationTests/TestMPFit.cs
  12. 3
      src/UnitTests/UnitTests.csproj

8
LICENSE.md

@ -92,3 +92,11 @@ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
MINPACK/MPFIT
-------------
* Original public domain version by B. Garbow, K. Hillstrom, J. More' (Argonne National Laboratory, MINPACK project, March 1980)
* Tranlation to C Language by [S. Moshier](moshier.net)
* Translation to C# Language by [D. Cuccia](http://davidcuccia.wordpress.com)
* Enhancements and packaging by C. Markwardt (comparable to [IDL fitting routine MPFIT](http://cow.physics.wisc.edu/~craigm/idl/idl.html))

6
src/Numerics/Numerics.csproj

@ -94,6 +94,12 @@
<Compile Include="Interpolation\Barycentric.cs" />
<Compile Include="Interpolation\CubicSpline.cs" />
<Compile Include="Interpolation\QuadraticSpline.cs" />
<Compile Include="Optimization\MpFit.cs" />
<Compile Include="Optimization\DelimitedArray.cs" />
<Compile Include="Optimization\MpConfig.cs" />
<Compile Include="Optimization\MpFunc.cs" />
<Compile Include="Optimization\MpResult.cs" />
<Compile Include="Optimization\ParameterConstraint.cs" />
<Compile Include="Precision.Comparison.cs" />
<Compile Include="Precision.Equality.cs" />
<Compile Include="Distributions\Bernoulli.cs" />

185
src/Numerics/Optimization/DelimitedArray.cs

@ -0,0 +1,185 @@
// <copyright file="DelimitedArray.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
// <contribution>
// MINPACK-1 Least Squares Fitting Library
// Original public domain version by B. Garbow, K. Hillstrom, J. More'
// (Argonne National Laboratory, MINPACK project, March 1980)
//
// Tranlation to C Language by S. Moshier (http://moshier.net)
// Translation to C# Language by D. Cuccia (http://davidcuccia.wordpress.com)
//
// Enhancements and packaging by C. Markwardt
// (comparable to IDL fitting routine MPFIT see http://cow.physics.wisc.edu/~craigm/idl/idl.html
// </contribution>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace MathNet.Numerics.Optimization
{
/// <summary>
/// Class that represents a "sub-array" within a larger array by implementing
/// appropriate indexing using an offset and sub-count. This was implemented in
/// the C# version in order to preserve the existing code semantics while also
/// allowing the code to be compiled w/o use of /unsafe compilation flag. This
/// permits execution of the code in low-trust environments, such as that required
/// by the CoreCLR runtime of Silverlight (Mac/PC) and Moonlight (Linux)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>Note - modifications to this structure will modify the parent (source) array!</remarks>
public class DelimitedArray<T> : IList<T> where T : struct
{
int _offset;
int _count;
readonly T[] _array;
public DelimitedArray(T[] array, int offset, int count)
{
_array = array;
_offset = offset;
_count = count;
}
public void SetOffset(int offset)
{
if (offset + _count > _array.Length)
{
throw new ArgumentOutOfRangeException();
}
_offset = offset;
}
public void SetOffsetAndCount(int offset, int count)
{
if (offset + count > _array.Length)
{
throw new ArgumentOutOfRangeException();
}
_offset = offset;
_count = count;
}
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
for (int i = _offset; i < _offset + _count; i++)
{
yield return _array[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region IList<T> Members
public int Count
{
get { return _count; }
}
public T this[int index]
{
get { return _array[_offset + index]; }
set { _array[_offset + index] = value; }
}
public int IndexOf(T item)
{
var query =
(from i in Enumerable.Range(_offset, _count)
where _array[i].Equals(item)
select i);
foreach (var i in query)
{
return i - _offset;
}
return -1;
}
public void Insert(int index, T item)
{
throw new NotImplementedException();
}
public void RemoveAt(int index)
{
throw new NotImplementedException();
}
#endregion
#region ICollection<T> Members
public bool Contains(T item)
{
return ((IEnumerable<T>)this).Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
Array.Copy(_array, _offset, array, arrayIndex, _count);
}
public bool IsReadOnly
{
get { return false; }
}
public void Add(T item)
{
throw new NotImplementedException();
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Remove(T item)
{
throw new NotImplementedException();
}
#endregion
}
}

2519
src/Numerics/Optimization/MPFit.cs

File diff suppressed because it is too large

93
src/Numerics/Optimization/MpConfig.cs

@ -0,0 +1,93 @@
// <copyright file="MpConfig.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
// <contribution>
// MINPACK-1 Least Squares Fitting Library
// Original public domain version by B. Garbow, K. Hillstrom, J. More'
// (Argonne National Laboratory, MINPACK project, March 1980)
//
// Tranlation to C Language by S. Moshier (http://moshier.net)
// Translation to C# Language by D. Cuccia (http://davidcuccia.wordpress.com)
//
// Enhancements and packaging by C. Markwardt
// (comparable to IDL fitting routine MPFIT see http://cow.physics.wisc.edu/~craigm/idl/idl.html
// </contribution>
namespace MathNet.Numerics.Optimization
{
public class MpConfig
{
/// <summary>Relative chi-square convergence criterium</summary>
public double ftol;
/// <summary>Relative parameter convergence criterium</summary>
public double xtol;
/// <summary>Orthogonality convergence criterium</summary>
public double gtol;
/// <summary>Finite derivative step size</summary>
public double epsfcn;
/// <summary>Initial step bound</summary>
public double stepfactor;
/// <summary>Range tolerance for covariance</summary>
public double covtol;
/// <summary>
/// Maximum number of iterations. If maxiter == 0,
/// then basic error checking is done, and parameter
/// errors/covariances are estimated based on input
/// parameter values, but no fitting iterations are done.
/// </summary>
public int MaxIterations;
/// <summary>Maximum number of function evaluations</summary>
public int MaxEvaluations;
/// <summary></summary>
public int nprint;
/// <summary>
/// Scale variables by user values?
/// 1 = yes, user scale values in diag;
/// 0 = no, variables scaled internally
/// </summary>
public int DoUserScale;
/// <summary>
/// Disable check for infinite quantities from user?
/// 0 = do not perform check
/// 1 = perform check
/// </summary>
public int NoFiniteCheck;
}
}

60
src/Numerics/Optimization/MpFunc.cs

@ -0,0 +1,60 @@
// <copyright file="MpFunc.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
// <contribution>
// MINPACK-1 Least Squares Fitting Library
// Original public domain version by B. Garbow, K. Hillstrom, J. More'
// (Argonne National Laboratory, MINPACK project, March 1980)
//
// Tranlation to C Language by S. Moshier (http://moshier.net)
// Translation to C# Language by D. Cuccia (http://davidcuccia.wordpress.com)
//
// Enhancements and packaging by C. Markwardt
// (comparable to IDL fitting routine MPFIT see http://cow.physics.wisc.edu/~craigm/idl/idl.html
// </contribution>
using System.Collections.Generic;
namespace MathNet.Numerics.Optimization
{
/// <summary>
/// User-function delegate structure required by MPFit.Solve
/// </summary>
/// <param name="a">I - Parameters</param>
/// <param name="fvec">O - function values</param>
/// <param name="dvec">
/// O - function derivatives (optional)
/// "Array of ILists" to accomodate DelimitedArray IList implementation
/// </param>
/// <param name="prv">I/O - function private data (cast to object type in user function)</param>
public delegate int MpFunc(double[] a, double[] fvec, IList<double>[] dvec, object prv);
//public delegate int MpFunc(int m, int npar, double[] x, double[] fvec, IList<double>[] dvec, object prv);$
}

91
src/Numerics/Optimization/MpResult.cs

@ -0,0 +1,91 @@
// <copyright file="MpResult.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
// <contribution>
// MINPACK-1 Least Squares Fitting Library
// Original public domain version by B. Garbow, K. Hillstrom, J. More'
// (Argonne National Laboratory, MINPACK project, March 1980)
//
// Tranlation to C Language by S. Moshier (http://moshier.net)
// Translation to C# Language by D. Cuccia (http://davidcuccia.wordpress.com)
//
// Enhancements and packaging by C. Markwardt
// (comparable to IDL fitting routine MPFIT see http://cow.physics.wisc.edu/~craigm/idl/idl.html
// </contribution>
namespace MathNet.Numerics.Optimization
{
/// <summary>
/// Definition of results structure, for when fit completes
/// </summary>
public class MpResult
{
/// <summary>Final chi^2</summary>
public double BestNorm;
/// <summary>Starting value of chi^2</summary>
public double OriginalNorm;
/// <summary>Number of iterations</summary>
public int Iterations;
/// <summary>Number of function evaluations</summary>
public int Evaluations;
/// <summary>Fitting status code</summary>
public int Status;
/// <summary>Total number of parameters</summary>
public int ParameterCount;
/// <summary>Number of free parameters</summary>
public int FreeParameterCount;
/// <summary>Number of pegged parameters</summary>
public int PeggedParameterCount;
/// <summary>Number of residuals (= num. of data points)</summary>
public int ResidualCount;
/// <summary>Final residuals nfunc-vector, or 0 if not desired</summary>
public double[] FinalResiduals;
/// <summary>Final parameter uncertainties (1-sigma) npar-vector, or 0 if not desired</summary>
public double[] FinalparameterUncertainties;
/// <summary>Final parameter covariance matrix npar x npar array, or 0 if not desired</summary>
public double[] FinalParameterCovarianceMatrix;
public MpResult(int numParameters)
{
FinalparameterUncertainties = new double[numParameters];
}
}
}

98
src/Numerics/Optimization/ParameterConstraint.cs

@ -0,0 +1,98 @@
// <copyright file="ParameterConstraint.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
// <contribution>
// MINPACK-1 Least Squares Fitting Library
// Original public domain version by B. Garbow, K. Hillstrom, J. More'
// (Argonne National Laboratory, MINPACK project, March 1980)
//
// Tranlation to C Language by S. Moshier (http://moshier.net)
// Translation to C# Language by D. Cuccia (http://davidcuccia.wordpress.com)
//
// Enhancements and packaging by C. Markwardt
// (comparable to IDL fitting routine MPFIT see http://cow.physics.wisc.edu/~craigm/idl/idl.html
// </contribution>
namespace MathNet.Numerics.Optimization
{
/// <summary>
/// Definition of a parameter constraint structure
/// </summary>
public class ParameterConstraint
{
/// <summary>1 = fixed; 0 = free</summary>
public int isFixed;
/// <summary>1 = low/upper limit; 0 = no limit</summary>
public int[] limited = new int[2];
/// <summary>lower/upper limit boundary value</summary>
public double[] limits = new double[2];
/// <summary>Name of parameter, or 0 for none</summary>
public string parname;
/// <summary>Step size for finite difference</summary>
public double step; /* */
/// <summary>Relative step size for finite difference</summary>
public double relstep;
/// <summary>
/// Sidedness of finite difference derivative
/// 0 - one-sided derivative computed automatically
/// 1 - one-sided derivative (f(x+h) - f(x) )/h
/// -1 - one-sided derivative (f(x) - f(x-h))/h
/// 2 - two-sided derivative (f(x+h) - f(x-h))/(2*h)
/// 3 - user-computed analytical derivatives
/// </summary>
public int side;
/// <summary>
/// Derivative debug mode: 1 = Yes; 0 = No;
///
/// If yes, compute both analytical and numerical
/// derivatives and print them to the console for
/// comparison.
///
/// NOTE: when debugging, do *not* set side = 3,
/// but rather to the kind of numerical derivative
/// you want to compare the user-analytical one to
/// (0, 1, -1, or 2).
///</summary>
public int deriv_debug;
/// <summary>Relative tolerance for derivative debug printout</summary>
public double deriv_reltol;
/// <summary>Absolute tolerance for derivative debug printout</summary>
public double deriv_abstol;
}
}

43
src/UnitTests/OptimizationTests/CustomUserVariable.cs

@ -0,0 +1,43 @@
// <copyright file="CustomUserVariable.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
/// <summary>
/// This is the a demo user-specific data structure which contains the data points
/// and their uncertainties
/// </summary>
public class CustomUserVariable
{
public double[] X;
public double[] Y;
public double[] Ey;
}
}

138
src/UnitTests/OptimizationTests/ForwardModels.cs

@ -0,0 +1,138 @@
// <copyright file="ForwardModels.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using System.Collections.Generic;
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
public static class ForwardModels
{
/*
* linear fit function
*
* m - number of data points
* n - number of parameters (2)
* p - array of fit parameters
* dy - array of residuals to be returned
* CustomUserVariable - private data (struct vars_struct *)
*
* RETURNS: error code (0 = success)
*/
public static int LinFunc(double[] p, double[] dy, IList<double>[] dvec, object vars)
{
int i;
double[] x, y, ey;
double f;
CustomUserVariable v = (CustomUserVariable)vars;
x = v.X;
y = v.Y;
ey = v.Ey;
for (i = 0; i < dy.Length; i++)
{
f = p[0] - p[1]*x[i]; /* Linear fit function */
dy[i] = (y[i] - f)/ey[i];
}
return 0;
}
/*
* quadratic fit function
*
* m - number of data points
* n - number of parameters (2)
* p - array of fit parameters
* dy - array of residuals to be returned
* CustomUserVariable - private data (struct vars_struct *)
*
* RETURNS: error code (0 = success)
*/
public static int QuadFunc(double[] p, double[] dy, IList<double>[] dvec, object vars)
{
int i;
double[] x, y, ey;
CustomUserVariable v = (CustomUserVariable)vars;
x = v.X;
y = v.Y;
ey = v.Ey;
/* Console.Write ("QuadFunc %f %f %f\n", p[0], p[1], p[2]); */
for (i = 0; i < dy.Length; i++)
{
dy[i] = (y[i] - p[0] - p[1]*x[i] - p[2]*x[i]*x[i])/ey[i];
}
return 0;
}
/*
* gaussian fit function
*
* m - number of data points
* n - number of parameters (4)
* p - array of fit parameters
* dy - array of residuals to be returned
* CustomUserVariable - private data (struct vars_struct *)
*
* RETURNS: error code (0 = success)
*/
public static int GaussFunc(double[] p, double[] dy, IList<double>[] dvec, object vars)
{
int i;
CustomUserVariable v = (CustomUserVariable)vars;
double[] x, y, ey;
double xc, sig2;
x = v.X;
y = v.Y;
ey = v.Ey;
sig2 = p[3]*p[3];
for (i = 0; i < dy.Length; i++)
{
xc = x[i] - p[2];
dy[i] = (y[i] - p[1]*Math.Exp(-0.5*xc*xc/sig2) - p[0])/ey[i];
}
return 0;
}
}
}

359
src/UnitTests/OptimizationTests/TestMPFit.cs

@ -0,0 +1,359 @@
// <copyright file="TestMPFit.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.Optimization;
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
public class TestMPFit
{
/* Main function which drives the whole thing */
public static void Main()
{
int i;
int niter = 1;
for (i = 0; i < niter; i++)
{
TestLinFit();
TestQuadFit();
TestQuadFix();
TestGaussFit();
TestGaussFix();
}
Console.ReadKey();
}
/* Test harness routine, which contains test data, invokes mpfit() */
static int TestLinFit()
{
double[] x =
{
-1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
-2.8394297E-01, 1.3416969E+00, 1.3757038E+00,
-1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
8.2065094E-01
};
double[] y =
{
1.9000429E-01, 6.5807428E+00, 1.4582725E+00,
2.7270851E+00, 5.5969253E+00, 5.6249280E+00,
0.787615, 3.2599759E+00, 2.9771762E+00,
4.5936475E+00
};
double[] ey = new double[10];
double[] p = { 1.0, 1.0 }; /* Initial conditions */
double[] pactual = { 3.20, 1.78 }; /* Actual values used to make data */
//double[] perror = { 0.0, 0.0 }; /* Returned parameter errors */
int i;
int status;
MpResult result = new MpResult(2);
//result.xerror = perror;
for (i = 0; i < 10; i++)
{
ey[i] = 0.07; /* Data errors */
}
CustomUserVariable v = new CustomUserVariable();
v.X = x;
v.Y = y;
v.Ey = ey;
/* Call fitting function for 10 data points and 2 parameters */
status = MpFit.Solve(ForwardModels.LinFunc, 10, 2, p, null, null, v, ref result);
Console.Write("*** TestLinFit status = {0}\n", status);
PrintResult(p, pactual, result);
return 0;
}
/* Test harness routine, which contains test quadratic data, invokes
Solve() */
static int TestQuadFit()
{
double[] x =
{
-1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
-2.8394297E-01, 1.3416969E+00, 1.3757038E+00,
-1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
8.2065094E-01
};
double[] y =
{
2.3095947E+01, 2.6449392E+01, 1.0204468E+01,
5.40507, 1.5787588E+01, 1.6520903E+01,
1.5971818E+01, 4.7668524E+00, 4.9337711E+00,
8.7348375E+00
};
double[] ey = new double[10];
double[] p = { 1.0, 1.0, 1.0 }; /* Initial conditions */
double[] pactual = { 4.7, 0.0, 6.2 }; /* Actual values used to make data */
//double[] perror = new double[3]; /* Returned parameter errors */
int i;
int status;
MpResult result = new MpResult(3);
//result.xerror = perror;
for (i = 0; i < 10; i++)
{
ey[i] = 0.2; /* Data errors */
}
CustomUserVariable v = new CustomUserVariable() { X = x, Y = y, Ey = ey };
/* Call fitting function for 10 data points and 3 parameters */
status = MpFit.Solve(ForwardModels.QuadFunc, 10, 3, p, null, null, v, ref result);
Console.Write("*** TestQuadFit status = {0}\n", status);
PrintResult(p, pactual, result);
return 0;
}
/* Test harness routine, which contains test quadratic data;
Example of how to fix a parameter
*/
static int TestQuadFix()
{
double[] x =
{
-1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
-2.8394297E-01, 1.3416969E+00, 1.3757038E+00,
-1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
8.2065094E-01
};
double[] y =
{
2.3095947E+01, 2.6449392E+01, 1.0204468E+01,
5.40507, 1.5787588E+01, 1.6520903E+01,
1.5971818E+01, 4.7668524E+00, 4.9337711E+00,
8.7348375E+00
};
double[] ey = new double[10];
double[] p = { 1.0, 0.0, 1.0 }; /* Initial conditions */
double[] pactual = { 4.7, 0.0, 6.2 }; /* Actual values used to make data */
//double[] perror = new double[3]; /* Returned parameter errors */
int i;
int status;
MpResult result = new MpResult(3);
//result.xerror = perror;
ParameterConstraint[] pars = new ParameterConstraint[3] /* Parameter constraints */
{
new ParameterConstraint(),
new ParameterConstraint() { isFixed = 1 }, /* Fix parameter 1 */
new ParameterConstraint()
};
for (i = 0; i < 10; i++)
{
ey[i] = 0.2;
}
CustomUserVariable v = new CustomUserVariable() { X = x, Y = y, Ey = ey };
/* Call fitting function for 10 data points and 3 parameters (1
parameter fixed) */
status = MpFit.Solve(ForwardModels.QuadFunc, 10, 3, p, pars, null, v, ref result);
Console.Write("*** TestQuadFix status = {0}\n", status);
PrintResult(p, pactual, result);
return 0;
}
/* Test harness routine, which contains test gaussian-peak data */
static int TestGaussFit()
{
double[] x =
{
-1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
-2.8394297E-01, 1.3416969E+00, 1.3757038E+00,
-1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
8.2065094E-01
};
double[] y =
{
-4.4494256E-02, 8.7324673E-01, 7.4443483E-01,
4.7631559E+00, 1.7187297E-01, 1.1639182E-01,
1.5646480E+00, 5.2322268E+00, 4.2543168E+00,
6.2792623E-01
};
double[] ey = new double[10];
double[] p = { 0.0, 1.0, 1.0, 1.0 }; /* Initial conditions */
double[] pactual = { 0.0, 4.70, 0.0, 0.5 }; /* Actual values used to make data*/
//double[] perror = new double[4]; /* Returned parameter errors */
ParameterConstraint[] pars = new ParameterConstraint[4] /* Parameter constraints */
{
new ParameterConstraint(),
new ParameterConstraint(),
new ParameterConstraint(),
new ParameterConstraint()
};
int i;
int status;
MpResult result = new MpResult(4);
//result.xerror = perror;
/* No constraints */
for (i = 0; i < 10; i++) ey[i] = 0.5;
CustomUserVariable v = new CustomUserVariable() { X = x, Y = y, Ey = ey };
/* Call fitting function for 10 data points and 4 parameters (no
parameters fixed) */
status = MpFit.Solve(ForwardModels.GaussFunc, 10, 4, p, pars, null, v, ref result);
Console.Write("*** TestGaussFit status = {0}\n", status);
PrintResult(p, pactual, result);
return 0;
}
/* Test harness routine, which contains test gaussian-peak data
Example of fixing two parameter
Commented example of how to put boundary constraints
*/
static int TestGaussFix()
{
double[] x =
{
-1.7237128E+00, 1.8712276E+00, -9.6608055E-01,
-2.8394297E-01, 1.3416969E+00, 1.3757038E+00,
-1.3703436E+00, 4.2581975E-02, -1.4970151E-01,
8.2065094E-01
};
double[] y =
{
-4.4494256E-02, 8.7324673E-01, 7.4443483E-01,
4.7631559E+00, 1.7187297E-01, 1.1639182E-01,
1.5646480E+00, 5.2322268E+00, 4.2543168E+00,
6.2792623E-01
};
double[] ey = new double[10];
double[] p = { 0.0, 1.0, 0.0, 0.1 }; /* Initial conditions */
double[] pactual = { 0.0, 4.70, 0.0, 0.5 }; /* Actual values used to make data*/
//double[] perror = new double[4]; /* Returned parameter errors */
int i;
int status;
MpResult result = new MpResult(4);
//result.xerror = perror;
ParameterConstraint[] pars = new ParameterConstraint[4] /* Parameter constraints */
{
new ParameterConstraint() { isFixed = 1 }, /* Fix parameters 0 and 2 */
new ParameterConstraint(),
new ParameterConstraint() { isFixed = 1 },
new ParameterConstraint()
};
/* How to put limits on a parameter. In this case, parameter 3 is
limited to be between -0.3 and +0.2.
pars[3].limited[0] = 0;
pars[3].limited[1] = 1;
pars[3].limits[0] = -0.3;
pars[3].limits[1] = +0.2;
*/
for (i = 0; i < 10; i++)
{
ey[i] = 0.5;
}
CustomUserVariable v = new CustomUserVariable() { X = x, Y = y, Ey = ey };
/* Call fitting function for 10 data points and 4 parameters (2
parameters fixed) */
status = MpFit.Solve(ForwardModels.GaussFunc, 10, 4, p, pars, null, v, ref result);
Console.Write("*** TestGaussFix status = {0}\n", status);
PrintResult(p, pactual, result);
return 0;
}
/* Simple routine to print the fit results */
static void PrintResult(double[] x, double[] xact, MpResult result)
{
int i;
if (x == null) return;
Console.Write(" CHI-SQUARE = {0} ({1} DOF)\n",
result.BestNorm, result.ResidualCount - result.FreeParameterCount);
Console.Write(" NPAR = {0}\n", result.ParameterCount);
Console.Write(" NFREE = {0}\n", result.FreeParameterCount);
Console.Write(" NPEGGED = {0}\n", result.PeggedParameterCount);
Console.Write(" NITER = {0}\n", result.Iterations);
Console.Write(" NFEV = {0}\n", result.Evaluations);
Console.Write("\n");
if (xact != null)
{
for (i = 0; i < result.ParameterCount; i++)
{
Console.Write(" P[{0}] = {1} +/- {2} (ACTUAL {3})\n",
i, x[i], result.FinalparameterUncertainties[i], xact[i]);
}
}
else
{
for (i = 0; i < result.ParameterCount; i++)
{
Console.Write(" P[{0}] = {1} +/- {2}\n",
i, x[i], result.FinalparameterUncertainties[i]);
}
}
}
}
}

3
src/UnitTests/UnitTests.csproj

@ -358,6 +358,9 @@
<Compile Include="EuclidTests\GcdRelatedTest.cs" />
<Compile Include="EuclidTests\GcdRelatedTestBigInteger.cs" />
<Compile Include="EuclidTests\IntegerTheoryTest.cs" />
<Compile Include="OptimizationTests\TestMPFit.cs" />
<Compile Include="OptimizationTests\CustomUserVariable.cs" />
<Compile Include="OptimizationTests\ForwardModels.cs" />
<Compile Include="Random\SystemRandomSourceTests.cs" />
<Compile Include="RootFindingTests\BisectionTest.cs" />
<Compile Include="PermutationTest.cs" />

Loading…
Cancel
Save