Giter Club home page Giter Club logo

csmpfit's People

Contributors

anders9ustafsson avatar dcuccia avatar fabiannitsche avatar gitter-badger avatar msevestre avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csmpfit's Issues

Failure when first parameter has analytic derivative and next does not.

It seems there may be a bookkeeping issue indexing the parameter derivatives when a parameter with user-supplied analytic derivatives is followed by one with numerical derivatives. This issue was observed after implementing the fix from the previous issue (#3), so there's a chance it could be due to that change. It seems the following change to line 1294 of MPFit.cs fixes the problem:

if (dside != null && dsidei == 3)
{
  ij += m; // bug fix
  continue;
}
//if (dside != null && dsidei == 3) continue; // replaced

The issue can be demonstrated by adding the following test to TestMPFit.cs:

   private static void TestGaussianWithDerivs()
   {
        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 _/
        mp_par[] pars = new mp_par[4] /_ Parameter constraints */
                            {
                                new mp_par() { side = 3, deriv_debug = 0 },
                                new mp_par() { side = 1, deriv_debug = 0 },
                                new mp_par() { side = 3, deriv_debug = 0 },
                                new mp_par() { side = 1, deriv_debug = 0 }
                                //new mp_par() { deriv_debug = 1 },
                                //new mp_par() { deriv_debug = 1 },
                                //new mp_par() { deriv_debug = 1 },
                                //new mp_par() { deriv_debug = 1 }
                            };

    mp_result result = new mp_result(4);
    //result.xerror = perror;

    /* No constraints */

    for (uint 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) */

    var logger = new System.IO.StringWriter();
    int status = MPFit.Solve(GaussianFuncAndDerivs, 10, 4, p, pars, null, v, ref result, logger);

    Console.Write("*** TestGaussFitWithDerivs status = {0}\n", status);
    PrintResult(p, pactual, result);
    Console.WriteLine(logger.ToString());
}

private static int GaussianFuncAndDerivs(double[] p, double[] dy, IList<double>[] dvec, object vars)
{
    CustomUserVariable v = (CustomUserVariable)vars;
    double[] x, y, ey;
    double sig2;

    x = v.X;
    y = v.Y;
    ey = v.Ey;

    sig2 = p[3] * p[3];
    //var dvec1 = new double[dy.Length];
    //var residuals = new double[dy.Length];

    for (int i = 0; i < dy.Length; i++)
    {
        double xc = x[i] - p[2];
        double exp = Math.Exp(-0.5 * xc * xc / sig2);
        //residuals[i] = (y[i] - p[1] * exp - p[0]) / ey[i];
        dy[i] = (y[i] - p[1] * exp - p[0]) / ey[i];

        // NOTE: it would make sense to store the first 2 derivatives in vars since they don't change.
        if (dvec != null)
        {
            if (dvec[0] != null)
            {
                dvec[0][i] = -1.0 / ey[i];
            }
            if (dvec[1] != null)
            {
                //dvec1[i] = -exp / ey[i];
                dvec[1][i] = -exp / ey[i];
            }
            if (dvec[2] != null)
            {
                dvec[2][i] = -p[1] * xc * exp / (ey[i] * sig2);
            }
            if (dvec[3] != null)
            {
                dvec[3][i] = -p[1] * xc * xc * exp / (ey[i] * p[3] * sig2);
            }
        }
    }

    // Array assignment rather than element-wise causes failure.
    //dy = residuals;

    // Array mismatch exception
    //if (dvec != null)
    //{
    //  if (dvec[1] != null)
    //  {
    //      dvec[1] = dvec1;
    //  }
    //}
    return 0;
}

multiple curves fitting

I have two curves described by one model, and I want to fit with them simultaneously. How to fit for multiple curves?

maxiter==0 is not working as expected (e.g. should turn off fitting)

The documentation for maxiter parameter specifies

/* 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. */

However it seems that setting the value to 0 is ignored by the code when the user values are being read

see

if (config.maxiter > 0) conf.maxiter = config.maxiter;

I think it should read
if (config.maxiter >= 0) conf.maxiter = config.maxiter;

instead of
if (config.maxiter > 0) conf.maxiter = config.maxiter;

Array mismatch exception when using analytical derivatives

It would be good if something testing user-supplied analytical derivatives were included in the unit tests. I expected to see them in ForwardModels.GaussFunc().

The following change to line 1219 in MPFit.cs seems to prevent the exception on line 1242 (dvec[ifree[j]] = ....).

dvec = new DelimitedArray<double>[npar];    // Prevents array type mismatch error on dvec[ifree[j]] = new DelimitedArray<double>(fjac, j * m, m) -RDN 6/17/2016
//dvec = new double[npar][];

Adding the following test to TestMPFit.cs illustrates the issue:

private static void TestAnalyticDerivatives()
{
        const double intercept = 7.0;
        const double slope = -3.0;
        var pactual = new double[] { intercept, slope };
        var p = new double[] { 5.9, -1.1 };
        var x = new double[] { -5, -3, -1, 0, 1, 3, 5 };
        var y = new double[x.Length];


    for (uint i = 0; i < x.Length; i++)
    {
        y[i] = intercept + slope * x[i];
    }

    var mpPar = new mp_par[] { new mp_par(), new mp_par() };
    mpPar[0].side = 3;
    mpPar[1].side = 3;

    var result = new mp_result(2);

    var status = MPFit.Solve(LineFunc, x.Length, 2, p, mpPar, null, new LineFitData(x, y), ref result);

    Console.Write("*** TestLineFit status = {0}\n", status);
    PrintResult(p, pactual, result);
}

private class LineFitData
{
    public LineFitData(double[] x, double[] y)
    {
        this.X = x;
        this.Y = y;
    }

    public double[] X { get; }
    public double[] Y { get; }
}

private static int LineFunc(double[] p, double[] dy, IList<double>[] dvec, object vars)
{
    var lineFitData = (LineFitData)vars;
    var x = lineFitData.X;
    var y = lineFitData.Y;

    for (int i = 0; i < x.Length; i++)
    {
        dy[i] = y[i] - (p[0] + p[1] * x[i]);
        if (dvec != null)
        {
            var dvec0 = dvec[0];
            var dvec1 = dvec[1];
            if (dvec0 != null)
            {
                dvec0[i] = -p[0];
            }
            if (dvec1 != null)
            {
                dvec1[i] = -x[i];
            }
        }
    }
    return 0;
}

Element-wise assignment appears to be required in user-supplied function.

In the user-supplied function to be fitted, it seems that both the residuals (dy) and derivatives (dvec) need to be set element-by-element, as opposed to array assignment. dy = array seems to have no effect on output, and dvec[i] = array results in an array-type mismatch exception. Commented out code in the test included in issue #4 demonstrates the problem. Also (possibly unrelated), would it make sense to use the ref keyword in the user function?

Documentation

Could you please provide a documentation for this library(C#)?

Strong Name is not valid from NUGET

I am unable to publish and install a project using ClickOnce due to mpfitlib.dll failing the strong name check, This is with the latest NUGET package v1.1.0

To confirm this, I ran sn.exe -vf mpfitlib.dll which also return that it was invalid.

I then downloaded the latest source from Github and built a release version. The resulting dll passed the strong name verification. This suggests to me that something is wrong with version currently uploaded to NUGET.

Provide .NET Standard library

Recommend we add a .NET Standard library, which allows us to support multiple platforms with a single binary.

https://docs.microsoft.com/en-us/dotnet/standard/library

Per the above, we should provide a NETStandard1.0 library to maximize the runtimes this will work with, including .NET Framework 4.5+, .NET Core 1.0+, Mono 4.6+, Xamarin.iOS 10+, Xamarin.Android 7+, and UWP 10+.

I've created a PR here for review: #10

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.