Ejemplo n.º 1
0
void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) {  
  KST_UNUSED( pdX )
  KST_UNUSED( pdY )
  KST_UNUSED( iLength )
  
  pdParameterEstimates[0] =  1.0;
  pdParameterEstimates[1] =  0.0;
  pdParameterEstimates[2] =  0.0;
}
Ejemplo n.º 2
0
int kstfit_general_levenberg_marquardt(const double *const inArrays[], const int inArrayLens[],
              const double inScalars[], double *outArrays[], int outArrayLens[],
              double outScalars[], const char* inStrings[], char *outStrings[])
{
  KST_UNUSED(outStrings);

  int iReturn = -1;

  if (inArrayLens[X] >= 2 && inArrayLens[Y] >= 2) {
    mu::Parser parser;
    double* pResult[4];
    double* pDelete = 0L;
    double* pInputX;
    double* pInputY;
    double *parameters;
    double tolerance = inScalars[0];
    double xvar;
    char *token;
    char *toSplit;
    char *endPtr;
    int maxIterations = (int)inScalars[1];
    int n = inArrayLens[0];
    int paramsNumber = 2;
    int startsNumber = 0;
    int iLengthData;
    int i;
    int j;

    iLengthData = inArrayLens[X];
    if( inArrayLens[Y] > iLengthData ) {
      iLengthData = inArrayLens[Y];
    }

    if (inArrayLens[X] == iLengthData) {
      pInputX = (double*)inArrays[X];
    } else {
      pDelete = (double*)malloc(iLengthData * sizeof( double ));
      pInputX = pDelete;
      for( i=0; i<iLengthData; i++) {
        pInputX[i] = interpolate( i, iLengthData, inArrays[X], inArrayLens[X] );
      }
    }

    if (inArrayLens[Y] == iLengthData) {
      pInputY = (double*)inArrays[Y];
    } else {
      pDelete = (double*)malloc(iLengthData * sizeof( double ));
      pInputY = pDelete;
      for( i=0; i<iLengthData; i++) {
        pInputY[i] = interpolate( i, iLengthData, inArrays[Y], inArrayLens[Y] );
      }
    }

    //
    // count the number of parameter names
    //
    toSplit = strdup(inStrings[1]);
    token = strtok( toSplit, ",;:" );
    while( token != NULL ) {
      paramsNumber++;
      token = strtok( NULL, ",;:" );
    }
    free(toSplit);

    if( iLengthData > paramsNumber ) {
      if( outArrayLens[0] != iLengthData ) {
        pResult[0] = (double*)realloc( outArrays[0], iLengthData * sizeof( double ) );
      } else {
        pResult[0] = outArrays[0];
      }

      if( outArrayLens[1] != iLengthData ) {
        pResult[1] = (double*)realloc( outArrays[1], iLengthData * sizeof( double ) );
      } else {
        pResult[1] = outArrays[1];
      }

      if( outArrayLens[2] != paramsNumber ) {
        pResult[2] = (double*)realloc( outArrays[2], paramsNumber * sizeof( double ) );
      } else {
        pResult[2] = outArrays[2];
      }

      if( outArrayLens[3] != paramsNumber * paramsNumber ) {
        pResult[3] = (double*)realloc( outArrays[3], paramsNumber * paramsNumber * sizeof( double ) );
      } else {
        pResult[3] = outArrays[3];
      }

      if( pResult[0] != NULL &&
          pResult[1] != NULL &&
          pResult[2] != NULL &&
          pResult[3] != NULL ) {
        outArrays[0] = pResult[0];
        outArrayLens[0] = iLengthData;
        outArrays[1] = pResult[1];
        outArrayLens[1] = iLengthData;
        outArrays[2] = pResult[2];
        outArrayLens[2] = paramsNumber;
        outArrays[3] = pResult[3];
        outArrayLens[3] = paramsNumber * paramsNumber;

        parameters = new double[paramsNumber];
        for (i=0; i<paramsNumber; i++) {
          parameters[i] = 0.0;
        }
        paramsNumber = 0;

        //
        // set the parameter names
        //
        toSplit = strdup(inStrings[1]);
        token = strtok( toSplit, ",;:" );
        while( token != NULL ) {
          char *paramName = strdup(token);
          char *paramPointer = paramName;

          while (paramPointer[0] == ' ') {
            paramPointer++;
          }
          while (paramPointer[strlen(paramPointer)] == ' ') {
            paramPointer[strlen(paramPointer)] = '\0';
          }

          try {
            parser.DefineVar(paramPointer, &parameters[paramsNumber]);
          } catch (mu::Parser::exception_type &e) {
          }

          paramsNumber++;
          token = strtok( NULL, ",;:" );
          free( paramName );
        }
        free(toSplit);

        //
        // set parameter initial guesses
        //
        double pInit[paramsNumber];
        toSplit = strdup(inStrings[2]);
        token = strtok( toSplit, ",;:" );
        while( token != NULL ) {
          pInit[startsNumber] = strtod(token, &endPtr);
          startsNumber++;
          token = strtok( NULL, ",;:" );
        }
        free(toSplit);

        for (i=startsNumber; i<paramsNumber; i++) {
          pInit[i] = 0.0;
        }

        if (strstr(inStrings[0], "pi") != 0L) {
          parser.DefineConst("pi", M_PI);
        }
        if (strstr(inStrings[0], "Pi") != 0L) {
          parser.DefineConst("Pi", M_PI);
        }
        if (strstr(inStrings[0], "PI") != 0L) {
          parser.DefineConst("PI", M_PI);
        }
        parser.DefineVar("x", &xvar);
        parser.SetExpr(inStrings[0]);

        gsl_vector_view x = gsl_vector_view_array(pInit, paramsNumber);

        struct fit d = { n, inArrays[0], inArrays[1], outArrays[0], &xvar, parameters, paramsNumber, &parser };

        const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;

        gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, n, paramsNumber);
        if (s != 0L) {
          gsl_multifit_function_fdf f;
          gsl_matrix *covar = gsl_matrix_alloc(paramsNumber, paramsNumber);
          if (covar != 0L) {
            f.f = &function_f;
            f.df = &function_df;
            f.fdf = &function_fdf;
            f.n = n;
            f.p = paramsNumber;
            f.params = &d;

            gsl_multifit_fdfsolver_set(s, &f, &x.vector);

            int status;
            int iteration = 0;

            do {
              iteration++;
              status = gsl_multifit_fdfsolver_iterate(s);
              if (status) {
                break;
              }
              status = gsl_multifit_test_delta(s->dx, s->x, tolerance, tolerance);
            } while (status == GSL_CONTINUE && iteration < maxIterations);

            gsl_multifit_covar(s->J, 0.0, covar);

            for( i=0; i<n; i++ ) {
              xvar = inArrays[0][i];

              try {
                outArrays[0][i] = parser.Eval();
                outArrays[1][i] = inArrays[1][i] - outArrays[0][i];
              } catch (mu::Parser::exception_type &e) {
                outArrays[0][i] = 0.0;
                outArrays[1][i] = 0.0;
              }
            }

            for (i=0; i<paramsNumber; i++) {
              outArrays[2][i] = parameters[i];
              for (j=0; j<paramsNumber; j++) {
                outArrays[3][(i*paramsNumber)+j] = gsl_matrix_get( covar, i, j );
              }
            }

            //
            // determine the value of chi^2/nu
            //
            outScalars[0] = gsl_blas_dnrm2( s->f );

            iReturn = 0;

            gsl_matrix_free(covar);
          }

          gsl_multifit_fdfsolver_free(s);
        }
      }
    }

    if( pDelete )
    {
      free( pDelete );
    }
  }

  return iReturn;
}