예제 #1
0
  /** Executes the algorithm
  *
  *  @throw runtime_error Thrown if algorithm cannot execute
  */
  void DiffractionEventCalibrateDetectors::exec()
  {
    // Try to retrieve optional properties
    const int maxIterations = getProperty("MaxIterations");
    const double peakOpt = getProperty("LocationOfPeakToOptimize");

    // Get the input workspace
    EventWorkspace_const_sptr inputW = getProperty("InputWorkspace");

     // retrieve the properties
    const std::string rb_params=getProperty("Params");

    //Get some stuff from the input workspace
    Instrument_const_sptr inst = inputW->getInstrument();

    //Build a list of Rectangular Detectors
    std::vector<boost::shared_ptr<RectangularDetector> > detList;
    // --------- Loading only one bank ----------------------------------
    std::string onebank = getProperty("BankName");
    bool doOneBank = (onebank != ""); 
    for (int i=0; i < inst->nelements(); i++)
    {
      boost::shared_ptr<RectangularDetector> det;
      boost::shared_ptr<ICompAssembly> assem;
      boost::shared_ptr<ICompAssembly> assem2;
  
      det = boost::dynamic_pointer_cast<RectangularDetector>( (*inst)[i] );
      if (det)
      {
        if (det->getName().compare(onebank) == 0) detList.push_back(det); 
        if (!doOneBank) detList.push_back(det); 
      }
      else
      {
        //Also, look in the first sub-level for RectangularDetectors (e.g. PG3).
        // We are not doing a full recursive search since that will be very long for lots of pixels.
        assem = boost::dynamic_pointer_cast<ICompAssembly>( (*inst)[i] );
        if (assem)
        {
          for (int j=0; j < assem->nelements(); j++)
          {
            det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem)[j] );
            if (det)
            {
              if (det->getName().compare(onebank) == 0) detList.push_back(det); 
              if (!doOneBank) detList.push_back(det); 
  
            }
            else
            {
              //Also, look in the second sub-level for RectangularDetectors (e.g. PG3).
              // We are not doing a full recursive search since that will be very long for lots of pixels.
              assem2 = boost::dynamic_pointer_cast<ICompAssembly>( (*assem)[j] );
              if (assem2)
              {
                for (int k=0; k < assem2->nelements(); k++)
                {
                  det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem2)[k] );
                  if (det)
                  {
                    if (det->getName().compare(onebank) == 0) detList.push_back(det); 
                    if (!doOneBank) detList.push_back(det); 
                  }
                }
              }
            }
          }
        }
      }
    }


    // set-up minimizer

    std::string inname = getProperty("InputWorkspace");
    std::string outname = inname+"2"; //getProperty("OutputWorkspace");

    IAlgorithm_sptr algS = createSubAlgorithm("SortEvents");
    algS->setPropertyValue("InputWorkspace",inname);
    algS->setPropertyValue("SortBy", "X Value");
    algS->executeAsSubAlg();
    inputW=algS->getProperty("InputWorkspace");

    //Write DetCal File
    double baseX,baseY,baseZ,upX,upY,upZ;

    std::string filename=getProperty("DetCalFilename");
    std::fstream outfile;
    outfile.open(filename.c_str(), std::ios::out);

    if(detList.size() > 1) 
    {
      outfile << "#\n";
      outfile << "#  Mantid Optimized .DetCal file for SNAP with TWO detector panels\n";
      outfile << "#  Old Panel, nominal size and distance at -90 degrees.\n";
      outfile << "#  New Panel, nominal size and distance at +90 degrees.\n";
      outfile << "#\n";
      outfile << "# Lengths are in centimeters.\n";
      outfile << "# Base and up give directions of unit vectors for a local\n";
      outfile << "# x,y coordinate system on the face of the detector.\n";
      outfile << "#\n";
      std::time_t current_t = DateAndTime::get_current_time().to_time_t() ;
      std::tm * current = gmtime( &current_t );
      outfile << "# "<<asctime (current) <<"\n";
      outfile << "#\n";
      outfile << "6         L1     T0_SHIFT\n";
      IObjComponent_const_sptr source = inst->getSource();
      IObjComponent_const_sptr sample = inst->getSample();
      outfile << "7  "<<source->getDistance(*sample)*100<<"            0\n";
      outfile << "4 DETNUM  NROWS  NCOLS  WIDTH   HEIGHT   DEPTH   DETD   CenterX   CenterY   CenterZ    BaseX    BaseY    BaseZ      UpX      UpY      UpZ\n";
    }

    Progress prog(this,0.0,1.0,detList.size());
    for (int det=0; det < static_cast<int>(detList.size()); det++)
    {
      std::string par[6];
      par[0]=detList[det]->getName();
      par[1]=inname;
      par[2]=outname;
      std::ostringstream strpeakOpt;
      strpeakOpt<<peakOpt;
      par[3]=strpeakOpt.str();
      par[4]=rb_params;

      // --- Create a GroupingWorkspace for this detector name ------
      CPUTimer tim;
      IAlgorithm_sptr alg2 = AlgorithmFactory::Instance().create("CreateGroupingWorkspace", 1);
      alg2->initialize();
      alg2->setPropertyValue("InputWorkspace", getPropertyValue("InputWorkspace"));
      alg2->setPropertyValue("GroupNames", detList[det]->getName());
      std::string groupWSName = "group_" + detList[det]->getName();
      alg2->setPropertyValue("OutputWorkspace", groupWSName);
      alg2->executeAsSubAlg();
      par[5] = groupWSName;
      std::cout << tim << " to CreateGroupingWorkspace" << std::endl;

      const gsl_multimin_fminimizer_type *T =
      gsl_multimin_fminimizer_nmsimplex;
      gsl_multimin_fminimizer *s = NULL;
      gsl_vector *ss, *x;
      gsl_multimin_function minex_func;

      // finally do the fitting

      int nopt = 6;
      int iter = 0;
      int status = 0;
      double size;
 
      /* Starting point */
      x = gsl_vector_alloc (nopt);
      gsl_vector_set (x, 0, 0.0);
      gsl_vector_set (x, 1, 0.0);
      gsl_vector_set (x, 2, 0.0);
      gsl_vector_set (x, 3, 0.0);
      gsl_vector_set (x, 4, 0.0);
      gsl_vector_set (x, 5, 0.0);

      /* Set initial step sizes to 0.1 */
      ss = gsl_vector_alloc (nopt);
      gsl_vector_set_all (ss, 0.1);

      /* Initialize method and iterate */
      minex_func.n = nopt;
      minex_func.f = &Mantid::Algorithms::gsl_costFunction;
      minex_func.params = &par;

      s = gsl_multimin_fminimizer_alloc (T, nopt);
      gsl_multimin_fminimizer_set (s, &minex_func, x, ss);

      do
      {
        iter++;
        status = gsl_multimin_fminimizer_iterate(s);

        if (status)
          break;

        size = gsl_multimin_fminimizer_size (s);
        status = gsl_multimin_test_size (size, 1e-2);

      }
      while (status == GSL_CONTINUE && iter < maxIterations && s->fval != -0.000 );

      // Output summary to log file
      if (s->fval != -0.000) movedetector(gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->x, 2),
         gsl_vector_get (s->x, 3), gsl_vector_get (s->x, 4), gsl_vector_get (s->x, 5), par[0], getProperty("InputWorkspace"));
      else 
      {
        gsl_vector_set (s->x, 0, 0.0);
        gsl_vector_set (s->x, 1, 0.0);
        gsl_vector_set (s->x, 2, 0.0);
        gsl_vector_set (s->x, 3, 0.0);
        gsl_vector_set (s->x, 4, 0.0);
        gsl_vector_set (s->x, 5, 0.0);
      }

      std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status);
      if (s->fval == -0.000) reportOfDiffractionEventCalibrateDetectors = "No events";

      g_log.information() << "Detector = " << det << "\n" <<
        "Method used = " << "Simplex" << "\n" <<
        "Iteration = " << iter << "\n" <<
        "Status = " << reportOfDiffractionEventCalibrateDetectors << "\n" <<
        "Minimize PeakLoc-" << peakOpt << " = " << s->fval << "\n";
      //Move in cm for small shifts
      g_log.information() << "Move (X)   = " << gsl_vector_get (s->x, 0)*0.01 << "  \n";
      g_log.information() << "Move (Y)   = " << gsl_vector_get (s->x, 1)*0.01 << "  \n";
      g_log.information() << "Move (Z)   = " << gsl_vector_get (s->x, 2)*0.01 << "  \n";
      g_log.information() << "Rotate (X) = " << gsl_vector_get (s->x, 3) << "  \n";
      g_log.information() << "Rotate (Y) = " << gsl_vector_get (s->x, 4) << "  \n";
      g_log.information() << "Rotate (Z) = " << gsl_vector_get (s->x, 5) << "  \n";


      Kernel::V3D CalCenter=V3D(gsl_vector_get (s->x, 0)*0.01,
        gsl_vector_get (s->x, 1)*0.01, gsl_vector_get (s->x, 2)*0.01);
      Kernel::V3D Center=detList[det]->getPos()+CalCenter;
      int pixmax = detList[det]->xpixels()-1;
      int pixmid = (detList[det]->ypixels()-1)/2;
      BoundingBox box;
      detList[det]->getAtXY(pixmax, pixmid)->getBoundingBox(box);
      baseX = box.xMax();
      baseY = box.yMax();
      baseZ = box.zMax();
      Kernel::V3D Base=V3D(baseX,baseY,baseZ)+CalCenter;
      pixmid = (detList[det]->xpixels()-1)/2;
      pixmax = detList[det]->ypixels()-1;
      detList[det]->getAtXY(pixmid, pixmax)->getBoundingBox(box);
      upX = box.xMax();
      upY = box.yMax();
      upZ = box.zMax();
      Kernel::V3D Up=V3D(upX,upY,upZ)+CalCenter;
      Base-=Center;
      Up-=Center;
      //Rotate around x
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      double deg2rad=M_PI/180.0;
      double angle = gsl_vector_get (s->x, 3)*deg2rad;
      Base=V3D(baseX,baseY*cos(angle)-baseZ*sin(angle),
        baseY*sin(angle)+baseZ*cos(angle));
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upX,upY*cos(angle)-upZ*sin(angle),
        upY*sin(angle)+upZ*cos(angle));
      //Rotate around y
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      angle = gsl_vector_get (s->x, 4)*deg2rad;
      Base=V3D(baseZ*sin(angle)+baseX*cos(angle),
        baseY,baseZ*cos(angle)-baseX*sin(angle));
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upZ*cos(angle)-upX*sin(angle),upY,
        upZ*sin(angle)+upX*cos(angle));
      //Rotate around z
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      angle = gsl_vector_get (s->x, 5)*deg2rad;
      Base=V3D(baseX*cos(angle)-baseY*sin(angle),
        baseX*sin(angle)+baseY*cos(angle),baseZ);
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upX*cos(angle)-upY*sin(angle),
        upX*sin(angle)+upY*cos(angle),upZ);
      Base.normalize();
      Up.normalize();
      Center*=100.0;
      // << det+1  << "  " 
      outfile << "5  " 
       << detList[det]->getName().substr(4)  << "  " 
       << detList[det]->xpixels() << "  " 
       << detList[det]->ypixels() << "  " 
       << 100.0*detList[det]->xsize() << "  " 
       << 100.0*detList[det]->ysize() << "  " 
       << "0.2000" << "  " 
       << Center.norm() << "  " ;
      Center.write(outfile);
      outfile << "  ";
      Base.write(outfile);
      outfile << "  ";
      Up.write(outfile);
      outfile << "\n";

      // clean up dynamically allocated gsl stuff
      gsl_vector_free(x);
      gsl_vector_free(ss);
      gsl_multimin_fminimizer_free (s);

      // Remove the now-unneeded grouping workspace
      AnalysisDataService::Instance().remove(groupWSName);
      prog.report(detList[det]->getName());
    }

    // Closing
    outfile.close();

    return;
  }
예제 #2
0
    // see "computation_of_the_gaze.odt"
    void Cornea::createF(const gsl_vector *x, gsl_vector *F) const {

        // number of LEDs
        const int nLEDs = data.size();

        // index for F
        int index_f = 0;

        const double RHO = trackerSettings.RHO;

        /*
         * For each LED pair, there are 3 functions
         */
        for(int i = 0; i < nLEDs-1; ++i) {

            const double gx_guess1 = gsl_vector_get(x, i);

            const DATA_FOR_CORNEA_COMPUTATION &data1 = data[i];

            const double tan_a1    = tan(data1.alpha_aux);
            const double atan_res1 = atan2(gx_guess1 * tan_a1, data1.l_aux - gx_guess1);
            const double cos_res1  = cos((data1.alpha_aux - atan_res1) * 0.5); // 0.5 = 1. / 2. => a / 2 = a*0.5
            const double sin_res1  = sin((data1.alpha_aux - atan_res1) * 0.5);

            const double A1 = data1.R(0, 0) * (gx_guess1 - RHO * sin_res1);
            const double B1 = data1.R(0, 2) * (gx_guess1 * tan_a1 + RHO * cos_res1);

            const double A2 = data1.R(1, 0) * (gx_guess1 - RHO * sin_res1);
            const double B2 = data1.R(1, 2) * (gx_guess1 * tan_a1 + RHO * cos_res1);

            const double A3 = data1.R(2, 0) * (gx_guess1 - RHO * sin_res1);
            const double B3 = data1.R(2, 2) * (gx_guess1 * tan_a1 + RHO * cos_res1);

            for(int j = i + 1; j < nLEDs; ++j) {

                const double gx_guess2 = gsl_vector_get(x, j);

                const DATA_FOR_CORNEA_COMPUTATION &data2 = data[j];

                const double tan_a2    = tan(data2.alpha_aux);
                const double atan_res2 = atan2(gx_guess2 * tan_a2, data2.l_aux - gx_guess2);
                const double cos_res2  = cos((data2.alpha_aux - atan_res2) * 0.5);
                const double sin_res2  = sin((data2.alpha_aux - atan_res2) * 0.5);

                const double C1 = data2.R(0, 0) * (gx_guess2 - RHO * sin_res2);
                const double D1 = data2.R(0, 2) * (gx_guess2 * tan_a2 + RHO * cos_res2);

                const double C2 = data2.R(1, 0) * (gx_guess2 - RHO * sin_res2);
                const double D2 = data2.R(1, 2) * (gx_guess2 * tan_a2 + RHO * cos_res2);

                const double C3 = data2.R(2, 0) * (gx_guess2 - RHO * sin_res2);
                const double D3 = data2.R(2, 2) * (gx_guess2 * tan_a2 + RHO * cos_res2);

                // assign the values
                gsl_vector_set(F, index_f,     A1 + B1 -C1 -D1);
                gsl_vector_set(F, index_f + 1, A2 + B2 -C2 -D2);
                gsl_vector_set(F, index_f + 2, A3 + B3 -C3 -D3);

                index_f += 3;

            }

        }

    }
void TableStatistics::update(Table *t, const QString& colName)
{
  if (t != d_base) return;
  
  int j;
  if (d_type == row)
    for (unsigned r=0; r < d_targets.size(); r++)
    {
      int cols=d_base->tableCols();
      int i = d_targets[r];
      int m = 0;
      for (j = 0; j < cols; j++)
		if (!d_base->text(i, j).isEmpty() && d_base->columnType(j) == Numeric)
			m++;

	  if (!m)
		{//clear row statistics
		for (j = 1; j<9; j++)
			setText(r, j, QString::null);
		}

      if (m > 0)
      {
	double *dat = new double[m];
	gsl_vector *y = gsl_vector_alloc (m);
	int aux = 0;
	for (j = 0; j<cols; j++)
	{
	  QString text = d_base->text(i,j);
	  if (!text.isEmpty() && d_base->columnType(j) == Numeric)
	  {					
	    double val = text.toDouble();
	    gsl_vector_set (y, aux, val);
	    dat[aux] = val;
	    aux++;
	  }
	}
	double mean = gsl_stats_mean (dat, 1, m);
	double min, max;
	gsl_vector_minmax (y, &min, &max);

	setText(r, 1, QString::number(d_base->tableCols()));
	setText(r, 2, QString::number(mean));
	setText(r, 3, QString::number(gsl_stats_sd(dat, 1, m)));
	setText(r, 4, QString::number(gsl_stats_variance(dat, 1, m)));
	setText(r, 5, QString::number(mean*m));
	setText(r, 6, QString::number(max));
	setText(r, 7, QString::number(min));
	setText(r, 8, QString::number(m));

	gsl_vector_free (y);
	delete[] dat;
      }
    }
  else if (d_type == column)
    for (unsigned c=0; c < d_targets.size(); c++)
      if (colName == QString(d_base->name())+"_"+text(c, 0))
      {
	int i = d_base->colIndex(colName);
	if (d_base->columnType(i) != Numeric) return;

	int rows = d_base->tableRows();
	int start = -1, m = 0;
	for (j=0; j<rows; j++)
	  if (!d_base->text(j,i).isEmpty())
	  {
	    m++;
	    if (start<0) start=j;
	  }

	  if (!m)
		{//clear col statistics
		for (j = 1; j<11; j++)
			setText(c, j, QString::null);
		return;
		}

	if (start<0) return;

	double *dat = new double[m];
	gsl_vector *y = gsl_vector_alloc (m);

	int aux = 0, min_index = start, max_index = start;
	double val = d_base->text(start, i).toDouble();
	gsl_vector_set (y, 0, val);
	dat[0] = val;
	double min = val, max = val;
	for (j = start + 1; j<rows; j++)
	{
	  if (!d_base->text(j, i).isEmpty())
	  {
	    aux++;
	    val = d_base->text(j, i).toDouble();
	    gsl_vector_set (y, aux, val);
	    dat[aux] = val;
	    if (val < min)
	    {
	      min = val;
	      min_index = j;
	    }
	    if (val > max)
	    {
	      max = val;
	      max_index = j;
	    }
	  }
	}
	double mean=gsl_stats_mean (dat, 1, m);

	setText(c, 1, "[1:"+QString::number(rows)+"]");
	setText(c, 2, QString::number(mean));
	setText(c, 3, QString::number(gsl_stats_sd(dat, 1, m)));
	setText(c, 4, QString::number(gsl_stats_variance(dat, 1, m)));
	setText(c, 5, QString::number(mean*m));
	setText(c, 6, QString::number(max_index + 1));
	setText(c, 7, QString::number(max));
	setText(c, 8, QString::number(min_index + 1));
	setText(c, 9, QString::number(min));
	setText(c, 10, QString::number(m));

	gsl_vector_free (y);
	delete[] dat;
      }

for (int i=0; i<worksheet->numCols(); i++)
	emit modifiedData(this, Table::colName(i));
}
예제 #4
0
파일: symmv.c 프로젝트: tommyliu/visionPJ1
int
gsl_eigen_symmv (gsl_matrix * A, gsl_vector * eval, gsl_matrix * evec,
                       gsl_eigen_symmv_workspace * w)
{
  if (A->size1 != A->size2)
    {
      GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR);
    }
  else if (eval->size != A->size1)
    {
      GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN);
    }
  else if (evec->size1 != A->size1 || evec->size2 != A->size1)
    {
      GSL_ERROR ("eigenvector matrix must match matrix size", GSL_EBADLEN);
    }
  else
    {
      double *const d = w->d;
      double *const sd = w->sd;
      const size_t N = A->size1;
      size_t a, b;

      /* handle special case */

      if (N == 1)
        {
          double A00 = gsl_matrix_get (A, 0, 0);
          gsl_vector_set (eval, 0, A00);
          gsl_matrix_set (evec, 0, 0, 1.0);
          return GSL_SUCCESS;
        }

      /* use sd as the temporary workspace for the decomposition when
         computing eigenvectors */

      {
        gsl_vector_view d_vec = gsl_vector_view_array (d, N);
        gsl_vector_view sd_vec = gsl_vector_view_array (sd, N - 1);
        gsl_vector_view tau = gsl_vector_view_array (sd, N - 1);
        gsl_linalg_symmtd_decomp (A, &tau.vector);
        gsl_linalg_symmtd_unpack (A, &tau.vector, evec, &d_vec.vector, &sd_vec.vector);
      }

      /* Make an initial pass through the tridiagonal decomposition
         to remove off-diagonal elements which are effectively zero */
      
      chop_small_elements (N, d, sd);
      
      /* Progressively reduce the matrix until it is diagonal */
      
      b = N - 1;
      
      while (b > 0)
        {
          if (sd[b - 1] == 0.0 || isnan(sd[b - 1]))
            {
              b--;
              continue;
            }
          
          /* Find the largest unreduced block (a,b) starting from b
             and working backwards */
          
          a = b - 1;
          
          while (a > 0)
            {
              if (sd[a - 1] == 0.0)
                {
                  break;
                }
              a--;
            }
          
          {
            size_t i;
            const size_t n_block = b - a + 1;
            double *d_block = d + a;
            double *sd_block = sd + a;
            double * const gc = w->gc;
            double * const gs = w->gs;
            
            /* apply QR reduction with implicit deflation to the
               unreduced block */
            
            qrstep (n_block, d_block, sd_block, gc, gs);
            
            /* Apply  Givens rotation Gij(c,s) to matrix Q,  Q <- Q G */
            
            for (i = 0; i < n_block - 1; i++)
              {
                const double c = gc[i], s = gs[i];
                size_t k;
                
                for (k = 0; k < N; k++)
                  {
                    double qki = gsl_matrix_get (evec, k, a + i);
                    double qkj = gsl_matrix_get (evec, k, a + i + 1);
                    gsl_matrix_set (evec, k, a + i, qki * c - qkj * s);
                    gsl_matrix_set (evec, k, a + i + 1, qki * s + qkj * c);
                  }
              }
            
            /* remove any small off-diagonal elements */
            
            chop_small_elements (N, d, sd);
          }
        }

      {
        gsl_vector_view d_vec = gsl_vector_view_array (d, N);
        gsl_vector_memcpy (eval, &d_vec.vector);
      }
      
      return GSL_SUCCESS;
    }
}
예제 #5
0
void calcZ(t_Cluster* ptCluster, t_Data *ptData){
    double **aadX = ptData->aadX, **aadZ = ptCluster->aadZ;
    int i = 0, k = 0, l = 0;
    int nK = ptCluster->nK, nD = ptCluster->nD, nN = ptData->nN;
    gsl_vector *ptDiff = gsl_vector_alloc(nD);
    gsl_vector *ptRes = gsl_vector_alloc(nD);
    double adDist[nK], dD = (double) nD;
    double** aadM = ptCluster->aadM, *adPi = ptCluster->adPi;

    for(i = 0; i < nN; i++){
        double dMinDist = DBL_MAX;
        double dTotalZ  = 0.0;
        double dNTotalZ = 0.0;

        for(k = 0; k < nK; k++){
            if(adPi[k] > 0.){
                /*set vector to data point*/
                for(l = 0; l < nD; l++){
                    gsl_vector_set(ptDiff,l,aadX[i][l] - aadM[k][l]);
                }

                gsl_blas_dsymv (CblasLower, 1.0, ptCluster->aptSigma[k], ptDiff, 0.0, ptRes);

                gsl_blas_ddot (ptDiff, ptRes, &adDist[k]);

                adDist[k] *= ptCluster->adNu[k];

                adDist[k] -= ptCluster->adLDet[k];

                adDist[k] += dD/ptCluster->adBeta[k];

                if(adDist[k] < dMinDist){
                    dMinDist = adDist[k];
                }
            }
        }

        for(k = 0; k < nK; k++){
            if(adPi[k] > 0.){
                aadZ[i][k] = adPi[k]*exp(-0.5*(adDist[k]-dMinDist));
                dTotalZ += aadZ[i][k];
            }
            else{
                aadZ[i][k] = 0.0;
            }
        }   

        for(k = 0; k < nK; k++){
            double dF = aadZ[i][k] / dTotalZ;
            if(dF < MIN_Z){
                aadZ[i][k] = 0.0;
            }
            dNTotalZ += aadZ[i][k];
        }
        if(dNTotalZ > 0.){
            for(k = 0; k < nK; k++){
                aadZ[i][k] /= dNTotalZ;
            }
        }
    }

    gsl_vector_free(ptRes);
    gsl_vector_free(ptDiff);
    return;
}
예제 #6
0
static int
msbdf_eval_order (gsl_vector * abscor, gsl_vector * tempvec,
                  gsl_vector * svec, const double errcoeff,
                  const size_t dim, const double errlev[],
                  const double ordm1coeff, const double ordp1coeff,
                  const double ordp1coeffprev, const double ordp2coeff,
                  const double hprev[],
                  const double h, const double z[],
                  size_t * ord, size_t * ordwait)
{
  /* Evaluates and executes change in method order (current, current-1
     or current+1). Order which maximizes the step length is selected.
   */

  size_t i;

  /* step size estimates at current order, order-1 and order+1 */
  double ordest = 0.0;
  double ordm1est = 0.0;
  double ordp1est = 0.0;

  const double safety = 1e-6;
  const double bias = 6.0;
  const double bias2 = 10.0;
  const double min_incr = 1.5;

  /* Relative step length estimate for current order */

  ordest = 1.0 / (pow (bias * gsl_blas_dnrm2 (abscor) / sqrt ((double)dim)
                       * errcoeff, 1.0 / (*ord + 1)) + safety);

  /* Relative step length estimate for order ord - 1 */

  if (*ord > 1)
    {
      for (i = 0; i < dim; i++)
        {
          gsl_vector_set (tempvec, i, z[*ord * dim + i] / errlev[i]);
        }

      ordm1est = 1.0 / (pow (bias * gsl_blas_dnrm2 (tempvec) / sqrt ((double)dim)
                             / ordm1coeff, 1.0 / (*ord)) + safety);
    }
  else
    {
      ordm1est = 0.0;
    }

  /* Relative step length estimate for order ord + 1 */

  if (*ord < MSBDF_MAX_ORD)
    {
      const double c = -ordp1coeff / ordp1coeffprev *
        pow ((double)h / hprev[1], double(*ord) + 1);

      for (i = 0; i < dim; i++)
        {
          gsl_vector_set (svec, i, gsl_vector_get (svec, i) * c +
                          gsl_vector_get (abscor, i));
        }

      ordp1est = 1.0 / (pow (bias2 * gsl_blas_dnrm2 (svec) / sqrt ((double)dim)
                             / ordp2coeff, 1.0 / (*ord + 2)) + safety);
    }
  else
    {
      ordp1est = 0.0;
    }

#ifdef DEBUG
  printf
    ("-- eval_order ord=%d, ordest=%.5e, ordm1est=%.5e, ordp1est=%.5e\n",
     (int) *ord, ordest, ordm1est, ordp1est);
#endif

  /* Choose order that maximises step size and increases step
     size markedly compared to current step 
   */

  if (ordm1est > ordest && ordm1est > ordp1est && ordm1est > min_incr)
    {
      *ord -= 1;
#ifdef DEBUG
      printf ("-- eval_order order DECREASED to %d\n", (int) *ord);
#endif
    }

  else if (ordp1est > ordest && ordp1est > ordm1est && ordp1est > min_incr)
    {
      *ord += 1;
#ifdef DEBUG
      printf ("-- eval_order order INCREASED to %d\n", (int) *ord);
#endif
    }

  *ordwait = *ord + 2;

  return GSL_SUCCESS;
}
예제 #7
0
int
gsl_linalg_hermtd_unpack (const gsl_matrix_complex * A, 
                          const gsl_vector_complex * tau,
                          gsl_matrix_complex * U, 
                          gsl_vector * diag, 
                          gsl_vector * sdiag)
{
  if (A->size1 !=  A->size2)
    {
      GSL_ERROR ("matrix A must be sqaure", GSL_ENOTSQR);
    }
  else if (tau->size + 1 != A->size1)
    {
      GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN);
    }
  else if (U->size1 != A->size1 || U->size2 != A->size1)
    {
      GSL_ERROR ("size of U must match size of A", GSL_EBADLEN);
    }
  else if (diag->size != A->size1)
    {
      GSL_ERROR ("size of diagonal must match size of A", GSL_EBADLEN);
    }
  else if (sdiag->size + 1 != A->size1)
    {
      GSL_ERROR ("size of subdiagonal must be (matrix size - 1)", GSL_EBADLEN);
    }
  else
    {
      const size_t N = A->size1;

      size_t i;

      /* Initialize U to the identity */

      gsl_matrix_complex_set_identity (U);

      for (i = N - 1; i-- > 0;)
        {
          gsl_complex ti = gsl_vector_complex_get (tau, i);

          gsl_vector_complex_const_view c = gsl_matrix_complex_const_column (A, i);

          gsl_vector_complex_const_view h = 
            gsl_vector_complex_const_subvector (&c.vector, i + 1, N - (i+1));

          gsl_matrix_complex_view m = 
            gsl_matrix_complex_submatrix (U, i + 1, i + 1, N-(i+1), N-(i+1));

          gsl_linalg_complex_householder_hm (ti, &h.vector, &m.matrix);
        }

      /* Copy diagonal into diag */

      for (i = 0; i < N; i++)
        {
          gsl_complex Aii = gsl_matrix_complex_get (A, i, i);
          gsl_vector_set (diag, i, GSL_REAL(Aii));
        }

      /* Copy subdiagonal into sdiag */

      for (i = 0; i < N - 1; i++)
        {
          gsl_complex Aji = gsl_matrix_complex_get (A, i+1, i);
          gsl_vector_set (sdiag, i, GSL_REAL(Aji));
        }

      return GSL_SUCCESS;
    }
}
예제 #8
0
파일: linreg.c 프로젝트: RobertDash/pspp
void linreg_set_indep_variable_mean (linreg *c, size_t j, double m)
{
  assert (c != NULL);
  gsl_vector_set (c->indep_means, j, m);
}
void SampleNormedRndVecWBias(gsl_vector* opinion, double x, gsl_rng * r)
{
    for (size_t i = 0; i < opinion->size ; i++)
        gsl_vector_set(opinion,i, x + gsl_ran_ugaussian(r) );
    NormalizeGslVector(opinion);
}
예제 #10
0
int main (void)
{
    /* Local variables */
    int i, j, k, l; /* Indices and counters       */
    int s;          /* Sign of the permutation    */
    int nr = 3;     /* Matrix dimensions, rows    */
    int nc = 3;     /* Matrix dimensions, columns */

    /* Declare and allocate matrix and vector variables */
    gsl_matrix *A = gsl_matrix_calloc(nr,nc); /* A */
    gsl_vector *b = gsl_vector_calloc(nr);    /* b */
    gsl_vector *x = gsl_vector_calloc(nc);     /* x */

    gsl_permutation *p = gsl_permutation_alloc(nr); /* Permutation Vector  for LU */

    /* Simple Example */
    /* A 3x3 matrix */
    double a_data[] = { 2.00, 1.00, 1.00,
                       4.00, 0.00, 0.00,
                      -2.00, 7.00, 2.00 } ;
                      
    /* b 3-vector */
    double b_data[] = { 5.00, -2.00, 9.00 };

    /* Initialize coefficient matrix A and vector b */
    /* use gsl_matrix_set  and gsl_vector_set */
    k = 0 ; l = 0 ; /* set counters  to zero */
    for (i=0;i<nr;i++) {
     for (j=0;j<nc;j++) {
        gsl_matrix_set(A,i,j,a_data[k]); 
        k++ ;
     } /* for j */
     
     gsl_vector_set(b,i,b_data[l]); 
     l++ ;
    } /* for i */

    /* Print entries of A use gsl_matrix_get and printf */
    /* do not use gsl_matrix_fprintf */
    printf("Solution of the system Ax=b via PLU factorizations\n");
    printf("Matrix A:\n");
    for (i = 0; i < nr; i++) {
     for (j = 0; j < nc; j++)
       printf ("%7.2g ", gsl_matrix_get(A, i, j));
    putchar('\n');
    } /* for i */

    /* Print entries of vector b */
    printf("Vector b:\n");
    gsl_vector_fprintf(stdout, b,"%7.2g");

    /* Perform (in place) PLU factorization */
    gsl_linalg_LU_decomp(A, p, &s); /* A is overwritten, p is permutation     */

    /* Find solution using the PLU factors found above and b */
    gsl_linalg_LU_solve(A, p, b, x);

    /* Print solution x */
    printf("Solution x:\n");
    gsl_vector_fprintf(stdout, x, "%7.2g");

    /* Clean up - free heap memory */
    gsl_matrix_free(A);
    gsl_vector_free(b);
    gsl_permutation_free(p);
    gsl_vector_free(x);

    return 0;
} /* main */
예제 #11
0
파일: blocking.c 프로젝트: schmidmt/Spins
int
block_4_majority(settings confin,lattice_site * lin , settings confout, \
                 lattice_site * lout)
{
  int i,j;
  int * newloc, * oldloc;
  int oid, nid;
  double newspin;

  if(confin.spindims != 1)
  {
    fprintf(stderr,"Cannot run majority rule on more than 1 spin dimension!\n");
    return(-1);
  }
  if((confin.sidelength & 1) != 0)
  {
    fprintf(stderr,"Cannot run on lattices of odd sidelength!\n");
    return(-1);
  }

  if(confout.sidelength != confin.sidelength/2)
  {
    fprintf(stderr,"confout isn't set correctly.\n");
    return(-1);
  }

  oldloc = malloc(confin.spacedims*sizeof(double));
  newloc = malloc(confout.spacedims*sizeof(double));

  for(i = 0 ; i < confout.sidelength; i++)
  {
    newloc[0] = i;
    for(j = 0 ; j < confout.sidelength; j++)
    {
      newspin = 0;
      newloc[1] = j;
      nid = location_to_num(confout,newloc);
      
      /* Lower Left */
      oldloc[0] = 2*i;
      oldloc[1] = 2*j;
      oid = location_to_num(confin,oldloc);
      newspin += gsl_vector_get(lin[oid].spin,0);

      /* Upper Left */
      oldloc[0] = 2*i;
      oldloc[1] = 2*j+1;
      oid = location_to_num(confin,oldloc);
      newspin += gsl_vector_get(lin[oid].spin,0);

      /* Lower Right */
      oldloc[0] = 2*i+1;
      oldloc[1] = 2*j;
      oid = location_to_num(confin,oldloc);
      newspin += gsl_vector_get(lin[oid].spin,0);

      /* Upper Right */
      oldloc[0] = 2*i+1;
      oldloc[1] = 2*j+1;
      oid = location_to_num(confin,oldloc);
      newspin += gsl_vector_get(lin[oid].spin,0);

      if(newspin > 0)
        gsl_vector_set(lout[nid].spin,0,1);
      else if(newspin < 0)
        gsl_vector_set(lout[nid].spin,0,-1);
      else if( gsl_rng_uniform(confout.rng) > 0.5)
        gsl_vector_set(lout[nid].spin,0,-1);
      else
        gsl_vector_set(lout[nid].spin,0,1);
    }
  }
  
  free(newloc);
  free(oldloc);
  return(0);
}
예제 #12
0
int prepareLambdas(gsl_vector * y, 
		   gsl_matrix * U, 
		   gsl_vector * D2, 
		   gsl_vector * lambdaVeckHKB, 
		   char * skhkbfilename, 
		   char * sklwfilename, 
		   gsl_vector * lambdaVeckLW, 
		   int randomized, 
		   int s)
{
  double kHKB;
  double kLW;
  double crossprod;
  double numerator;
  double denominatorkHKB;
  double denominatorkLW;
  int lengthLambdaVec = lambdaVeckHKB->size;
  gsl_matrix_view Uview; // a matrix view
  int n = y->size;
  int i, j;
  gsl_vector * resid = gsl_vector_alloc(n);
  gsl_matrix * H = gsl_matrix_alloc(n, n);
  for(i = 0; i < lengthLambdaVec; i++)
    {
      gsl_matrix * diag = gsl_matrix_calloc((i+1), (i+1));
      Uview = gsl_matrix_submatrix(U, 0, 0, n, (i + 1));
      // Make the hat matrix
      gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, &Uview.matrix, &Uview.matrix, 0.0, H);
      // make the fitted ys - put in the resid vector
      gsl_blas_dgemv(CblasNoTrans, 1.0, H, y, 0.0, resid);
      // make the denominaotor for kLW
      if(sklwfilename != NULL)
	{
	  gsl_blas_ddot(y, resid, &denominatorkLW);
	}
      // Make the residual vector 
      gsl_vector_scale(resid, -1);
      gsl_vector_add(resid, y);
      // make the crossproduct
      gsl_blas_ddot(resid, resid, &crossprod);
      // times it by i
      numerator = crossprod * ((float) i + 1.0);
      // this gives the numerator
      // Make the denominator for kHKB
      // Make the diagonal matrix
      for(j = 0; j < diag->size1; j++)
	{
	  gsl_matrix_set(diag, j, j, 1.0 / gsl_vector_get(D2, j));
	}
      // 
      // Make the matrix U diag D2
      gsl_matrix * UD2 = gsl_matrix_alloc(n, (i + 1));
      gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, &Uview.matrix, diag, 0.0, UD2);
      // Make the matrix U diag D2 U' - put it into H
      gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, UD2, &Uview.matrix, 0.0, H);
      // Make the matrix U diag D2 U' y - put it into resid
      gsl_blas_dgemv(CblasNoTrans, 1.0, H, y, 0.0, resid);
      // Make the dot product
      gsl_blas_ddot(y, resid, &denominatorkHKB);
      // put in the matrix
      if(skhkbfilename != NULL)
	{
	  gsl_blas_ddot(y, resid, &denominatorkHKB);
	  denominatorkHKB = ((float) n - (float) i - 1.0) * denominatorkHKB;
	  kHKB = numerator / denominatorkHKB;
	  gsl_vector_set(lambdaVeckHKB, i, kHKB);
	}
      if(sklwfilename != NULL)
	{
	  denominatorkLW = ((float) n - (float) i - 1.0) * denominatorkLW;
	  kLW = numerator / denominatorkLW;
	  gsl_vector_set(lambdaVeckLW, i, kLW);
	}
      gsl_matrix_free(UD2);
      gsl_matrix_free(diag);
    }
  if(randomized)
    {
      gsl_rng * rndm = gsl_rng_alloc(gsl_rng_mt19937);
      double weight;
      gsl_rng_set(rndm, s);
      for(i=0; i<lambdaVeckHKB->size; i++)
	{
	  weight = gsl_ran_flat(rndm, 0.2, 1.0);
	  gsl_vector_set(lambdaVeckHKB, i, weight * gsl_vector_get(lambdaVeckHKB, i));
	  weight = gsl_ran_flat(rndm, 0.2, 1.0);
	  gsl_vector_set(lambdaVeckLW, i, weight * gsl_vector_get(lambdaVeckLW, i));
	}
      gsl_rng_free(rndm);
    }
  gsl_vector_free(resid);
  gsl_matrix_free(H);
  return 0;
}
예제 #13
0
/** Executes the algorithm
 *
 *  @throw runtime_error Thrown if algorithm cannot execute
 */
void Fit1D::exec() {

  // Custom initialization
  prepare();

  // check if derivative defined in derived class
  bool isDerivDefined = true;
  gsl_matrix *M = nullptr;
  try {
    const std::vector<double> inTest(m_parameterNames.size(), 1.0);
    std::vector<double> outTest(m_parameterNames.size());
    const double xValuesTest = 0;
    JacobianImpl J;
    M = gsl_matrix_alloc(m_parameterNames.size(), 1);
    J.setJ(M);
    // note nData set to zero (last argument) hence this should avoid further
    // memory problems
    functionDeriv(&(inTest.front()), &J, &xValuesTest, 0);
  } catch (Exception::NotImplementedError &) {
    isDerivDefined = false;
  }
  gsl_matrix_free(M);

  // Try to retrieve optional properties
  int histNumber = getProperty("WorkspaceIndex");
  const int maxInterations = getProperty("MaxIterations");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  // number of histogram is equal to the number of spectra
  const size_t numberOfSpectra = localworkspace->getNumberHistograms();
  // Check that the index given is valid
  if (histNumber >= static_cast<int>(numberOfSpectra)) {
    g_log.warning("Invalid Workspace index given, using first Workspace");
    histNumber = 0;
  }

  // Retrieve the spectrum into a vector
  const MantidVec &XValues = localworkspace->readX(histNumber);
  const MantidVec &YValues = localworkspace->readY(histNumber);
  const MantidVec &YErrors = localworkspace->readE(histNumber);

  // Read in the fitting range data that we were sent
  double startX = getProperty("StartX");
  double endX = getProperty("EndX");
  // check if the values had been set, otherwise use defaults
  if (isEmpty(startX)) {
    startX = XValues.front();
    modifyStartOfRange(startX); // does nothing by default but derived class may
                                // provide a more intelligent value
  }
  if (isEmpty(endX)) {
    endX = XValues.back();
    modifyEndOfRange(endX); // does nothing by default but derived class may
                            // previde a more intelligent value
  }

  int m_minX;
  int m_maxX;

  // Check the validity of startX
  if (startX < XValues.front()) {
    g_log.warning("StartX out of range! Set to start of frame.");
    startX = XValues.front();
  }
  // Get the corresponding bin boundary that comes before (or coincides with)
  // this value
  for (m_minX = 0; XValues[m_minX + 1] < startX; ++m_minX) {
  }

  // Check the validity of endX and get the bin boundary that come after (or
  // coincides with) it
  if (endX >= XValues.back() || endX < startX) {
    g_log.warning("EndX out of range! Set to end of frame");
    endX = XValues.back();
    m_maxX = static_cast<int>(YValues.size());
  } else {
    for (m_maxX = m_minX; XValues[m_maxX] < endX; ++m_maxX) {
    }
  }

  afterDataRangedDetermined(m_minX, m_maxX);

  // create and populate GSL data container warn user if l_data.n < l_data.p
  // since as a rule of thumb this is required as a minimum to obtained
  // 'accurate'
  // fitting parameter values.

  FitData l_data(this, getProperty("Fix"));

  l_data.n =
      m_maxX -
      m_minX; // m_minX and m_maxX are array index markers. I.e. e.g. 0 & 19.
  if (l_data.n == 0) {
    g_log.error("The data set is empty.");
    throw std::runtime_error("The data set is empty.");
  }
  if (l_data.n < l_data.p) {
    g_log.error(
        "Number of data points less than number of parameters to be fitted.");
    throw std::runtime_error(
        "Number of data points less than number of parameters to be fitted.");
  }
  l_data.X = new double[l_data.n];
  l_data.sigmaData = new double[l_data.n];
  l_data.forSimplexLSwrap = new double[l_data.n];
  l_data.parameters = new double[nParams()];

  // check if histogram data in which case use mid points of histogram bins

  const bool isHistogram = localworkspace->isHistogramData();
  for (unsigned int i = 0; i < l_data.n; ++i) {
    if (isHistogram)
      l_data.X[i] =
          0.5 * (XValues[m_minX + i] +
                 XValues[m_minX + i + 1]); // take mid-point if histogram bin
    else
      l_data.X[i] = XValues[m_minX + i];
  }

  l_data.Y = &YValues[m_minX];

  // check that no error is negative or zero
  for (unsigned int i = 0; i < l_data.n; ++i) {
    if (YErrors[m_minX + i] <= 0.0) {
      l_data.sigmaData[i] = 1.0;
    } else
      l_data.sigmaData[i] = YErrors[m_minX + i];
  }

  // create array of fitted parameter. Take these to those input by the user.
  // However, for doing the
  // underlying fitting it might be more efficient to actually perform the
  // fitting on some of other
  // form of the fitted parameters. For instance, take the Gaussian sigma
  // parameter. In practice it
  // in fact more efficient to perform the fitting not on sigma but 1/sigma^2.
  // The methods
  // modifyInitialFittedParameters() and modifyFinalFittedParameters() are used
  // to allow for this;
  // by default these function do nothing.

  m_fittedParameter.clear();
  for (size_t i = 0; i < nParams(); i++) {
    m_fittedParameter.push_back(getProperty(m_parameterNames[i]));
  }
  modifyInitialFittedParameters(
      m_fittedParameter); // does nothing except if overwritten by derived class
  for (size_t i = 0; i < nParams(); i++) {
    l_data.parameters[i] = m_fittedParameter[i];
  }

  // set-up initial guess for fit parameters

  gsl_vector *initFuncArg;
  initFuncArg = gsl_vector_alloc(l_data.p);

  for (size_t i = 0, j = 0; i < nParams(); i++) {
    if (l_data.active[i])
      gsl_vector_set(initFuncArg, j++, m_fittedParameter[i]);
  }

  // set-up GSL container to be used with GSL simplex algorithm

  gsl_multimin_function gslSimplexContainer;
  gslSimplexContainer.n = l_data.p; // n here refers to number of parameters
  gslSimplexContainer.f = &gsl_costFunction;
  gslSimplexContainer.params = &l_data;

  // set-up GSL least squares container

  gsl_multifit_function_fdf f;
  f.f = &gsl_f;
  f.df = &gsl_df;
  f.fdf = &gsl_fdf;
  f.n = l_data.n;
  f.p = l_data.p;
  f.params = &l_data;

  // set-up remaining GSL machinery for least squared

  const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
  gsl_multifit_fdfsolver *s = nullptr;
  if (isDerivDefined) {
    s = gsl_multifit_fdfsolver_alloc(T, l_data.n, l_data.p);
    gsl_multifit_fdfsolver_set(s, &f, initFuncArg);
  }

  // set-up remaining GSL machinery to use simplex algorithm

  const gsl_multimin_fminimizer_type *simplexType =
      gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *simplexMinimizer = nullptr;
  gsl_vector *simplexStepSize = nullptr;
  if (!isDerivDefined) {
    simplexMinimizer = gsl_multimin_fminimizer_alloc(simplexType, l_data.p);
    simplexStepSize = gsl_vector_alloc(l_data.p);
    gsl_vector_set_all(simplexStepSize,
                       1.0); // is this always a sensible starting step size?
    gsl_multimin_fminimizer_set(simplexMinimizer, &gslSimplexContainer,
                                initFuncArg, simplexStepSize);
  }

  // finally do the fitting

  int iter = 0;
  int status;
  double finalCostFuncVal;
  double dof = static_cast<double>(
      l_data.n - l_data.p); // dof stands for degrees of freedom

  // Standard least-squares used if derivative function defined otherwise
  // simplex
  Progress prog(this, 0.0, 1.0, maxInterations);
  if (isDerivDefined) {

    do {
      iter++;
      status = gsl_multifit_fdfsolver_iterate(s);

      if (status) // break if error
        break;

      status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
      prog.report();
    } while (status == GSL_CONTINUE && iter < maxInterations);

    double chi = gsl_blas_dnrm2(s->f);
    finalCostFuncVal = chi * chi / dof;

    // put final converged fitting values back into m_fittedParameter
    for (size_t i = 0, j = 0; i < nParams(); i++)
      if (l_data.active[i])
        m_fittedParameter[i] = gsl_vector_get(s->x, j++);
  } else {
    do {
      iter++;
      status = gsl_multimin_fminimizer_iterate(simplexMinimizer);

      if (status) // break if error
        break;

      double size = gsl_multimin_fminimizer_size(simplexMinimizer);
      status = gsl_multimin_test_size(size, 1e-2);
      prog.report();
    } while (status == GSL_CONTINUE && iter < maxInterations);

    finalCostFuncVal = simplexMinimizer->fval / dof;

    // put final converged fitting values back into m_fittedParameter
    for (unsigned int i = 0, j = 0; i < m_fittedParameter.size(); i++)
      if (l_data.active[i])
        m_fittedParameter[i] = gsl_vector_get(simplexMinimizer->x, j++);
  }

  modifyFinalFittedParameters(
      m_fittedParameter); // do nothing except if overwritten by derived class

  // Output summary to log file

  std::string reportOfFit = gsl_strerror(status);

  g_log.information() << "Iteration = " << iter << "\n"
                      << "Status = " << reportOfFit << "\n"
                      << "Chi^2/DoF = " << finalCostFuncVal << "\n";
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    g_log.information() << m_parameterNames[i] << " = " << m_fittedParameter[i]
                        << "  \n";

  // also output summary to properties

  setProperty("OutputStatus", reportOfFit);
  setProperty("OutputChi2overDoF", finalCostFuncVal);
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    setProperty(m_parameterNames[i], m_fittedParameter[i]);

  std::string output = getProperty("Output");
  if (!output.empty()) {
    // calculate covariance matrix if derivatives available

    gsl_matrix *covar(nullptr);
    std::vector<double> standardDeviations;
    std::vector<double> sdExtended;
    if (isDerivDefined) {
      covar = gsl_matrix_alloc(l_data.p, l_data.p);
      gsl_multifit_covar(s->J, 0.0, covar);

      int iPNotFixed = 0;
      for (size_t i = 0; i < nParams(); i++) {
        sdExtended.push_back(1.0);
        if (l_data.active[i]) {
          sdExtended[i] = sqrt(gsl_matrix_get(covar, iPNotFixed, iPNotFixed));
          iPNotFixed++;
        }
      }
      modifyFinalFittedParameters(sdExtended);
      for (size_t i = 0; i < nParams(); i++)
        if (l_data.active[i])
          standardDeviations.push_back(sdExtended[i]);

      declareProperty(
          new WorkspaceProperty<API::ITableWorkspace>(
              "OutputNormalisedCovarianceMatrix", "", Direction::Output),
          "The name of the TableWorkspace in which to store the final "
          "covariance matrix");
      setPropertyValue("OutputNormalisedCovarianceMatrix",
                       output + "_NormalisedCovarianceMatrix");

      Mantid::API::ITableWorkspace_sptr m_covariance =
          Mantid::API::WorkspaceFactory::Instance().createTable(
              "TableWorkspace");
      m_covariance->addColumn("str", "Name");
      std::vector<std::string>
          paramThatAreFitted; // used for populating 1st "name" column
      for (size_t i = 0; i < nParams(); i++) {
        if (l_data.active[i]) {
          m_covariance->addColumn("double", m_parameterNames[i]);
          paramThatAreFitted.push_back(m_parameterNames[i]);
        }
      }

      for (size_t i = 0; i < l_data.p; i++) {

        Mantid::API::TableRow row = m_covariance->appendRow();
        row << paramThatAreFitted[i];
        for (size_t j = 0; j < l_data.p; j++) {
          if (j == i)
            row << 1.0;
          else {
            row << 100.0 * gsl_matrix_get(covar, i, j) /
                       sqrt(gsl_matrix_get(covar, i, i) *
                            gsl_matrix_get(covar, j, j));
          }
        }
      }

      setProperty("OutputNormalisedCovarianceMatrix", m_covariance);
    }

    declareProperty(new WorkspaceProperty<API::ITableWorkspace>(
                        "OutputParameters", "", Direction::Output),
                    "The name of the TableWorkspace in which to store the "
                    "final fit parameters");
    declareProperty(
        new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "",
                                               Direction::Output),
        "Name of the output Workspace holding resulting simlated spectrum");

    setPropertyValue("OutputParameters", output + "_Parameters");
    setPropertyValue("OutputWorkspace", output + "_Workspace");

    // Save the final fit parameters in the output table workspace
    Mantid::API::ITableWorkspace_sptr m_result =
        Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
    m_result->addColumn("str", "Name");
    m_result->addColumn("double", "Value");
    if (isDerivDefined)
      m_result->addColumn("double", "Error");
    Mantid::API::TableRow row = m_result->appendRow();
    row << "Chi^2/DoF" << finalCostFuncVal;

    for (size_t i = 0; i < nParams(); i++) {
      Mantid::API::TableRow row = m_result->appendRow();
      row << m_parameterNames[i] << m_fittedParameter[i];
      if (isDerivDefined && l_data.active[i]) {
        // perhaps want to scale standard deviations with sqrt(finalCostFuncVal)
        row << sdExtended[i];
      }
    }
    setProperty("OutputParameters", m_result);

    // Save the fitted and simulated spectra in the output workspace
    MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
    int iSpec = getProperty("WorkspaceIndex");
    const MantidVec &inputX = inputWorkspace->readX(iSpec);
    const MantidVec &inputY = inputWorkspace->readY(iSpec);

    int histN = isHistogram ? 1 : 0;
    Mantid::DataObjects::Workspace2D_sptr ws =
        boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(
            Mantid::API::WorkspaceFactory::Instance().create(
                "Workspace2D", 3, l_data.n + histN, l_data.n));
    ws->setTitle("");
    ws->getAxis(0)->unit() =
        inputWorkspace->getAxis(0)
            ->unit(); //    UnitFactory::Instance().create("TOF");

    for (int i = 0; i < 3; i++)
      ws->dataX(i)
          .assign(inputX.begin() + m_minX, inputX.begin() + m_maxX + histN);

    ws->dataY(0).assign(inputY.begin() + m_minX, inputY.begin() + m_maxX);

    MantidVec &Y = ws->dataY(1);
    MantidVec &E = ws->dataY(2);

    auto lOut =
        new double[l_data.n]; // to capture output from call to function()
    modifyInitialFittedParameters(m_fittedParameter); // does nothing except if
                                                      // overwritten by derived
                                                      // class
    function(&m_fittedParameter[0], lOut, l_data.X, l_data.n);
    modifyInitialFittedParameters(m_fittedParameter); // reverse the effect of
    // modifyInitialFittedParameters - if any

    for (unsigned int i = 0; i < l_data.n; i++) {
      Y[i] = lOut[i];
      E[i] = l_data.Y[i] - Y[i];
    }

    delete[] lOut;

    setProperty("OutputWorkspace",
                boost::dynamic_pointer_cast<MatrixWorkspace>(ws));

    if (isDerivDefined)
      gsl_matrix_free(covar);
  }

  // clean up dynamically allocated gsl stuff

  if (isDerivDefined)
    gsl_multifit_fdfsolver_free(s);
  else {
    gsl_vector_free(simplexStepSize);
    gsl_multimin_fminimizer_free(simplexMinimizer);
  }

  delete[] l_data.X;
  delete[] l_data.sigmaData;
  delete[] l_data.forSimplexLSwrap;
  delete[] l_data.parameters;
  gsl_vector_free(initFuncArg);

  return;
}
예제 #14
0
static void
intersect_polish_root (Curve const &A, double &s,
                       Curve const &B, double &t) {
    std::vector<Point> as, bs;
    as = A.pointAndDerivatives(s, 2);
    bs = B.pointAndDerivatives(t, 2);
    Point F = as[0] - bs[0];
    double best = dot(F, F);

    for(int i = 0; i < 4; i++) {

        /**
           we want to solve
           J*(x1 - x0) = f(x0)

           |dA(s)[0]  -dB(t)[0]|  (X1 - X0) = A(s) - B(t)
           |dA(s)[1]  -dB(t)[1]|
        **/

        // We're using the standard transformation matricies, which is numerically rather poor.  Much better to solve the equation using elimination.

        Matrix jack(as[1][0], as[1][1],
                    -bs[1][0], -bs[1][1],
                    0, 0);
        Point soln = (F)*jack.inverse();
        double ns = s - soln[0];
        double nt = t - soln[1];

        if (ns<0) ns=0;
        else if (ns>1) ns=1;
        if (nt<0) nt=0;
        else if (nt>1) nt=1;

        as = A.pointAndDerivatives(ns, 2);
        bs = B.pointAndDerivatives(nt, 2);
        F = as[0] - bs[0];
        double trial = dot(F, F);
        if (trial > best*0.1) // we have standards, you know
            // At this point we could do a line search
            break;
        best = trial;
        s = ns;
        t = nt;
    }

#ifdef HAVE_GSL
    if(0) { // the GSL version is more accurate, but taints this with GPL
        const size_t n = 2;
        struct rparams p = {A, B};
        gsl_multiroot_function f = {&intersect_polish_f, n, &p};

        double x_init[2] = {s, t};
        gsl_vector *x = gsl_vector_alloc (n);

        gsl_vector_set (x, 0, x_init[0]);
        gsl_vector_set (x, 1, x_init[1]);

        const gsl_multiroot_fsolver_type *T = gsl_multiroot_fsolver_hybrids;
        gsl_multiroot_fsolver *sol = gsl_multiroot_fsolver_alloc (T, 2);
        gsl_multiroot_fsolver_set (sol, &f, x);

        int status = 0;
        size_t iter = 0;
        do
        {
            iter++;
            status = gsl_multiroot_fsolver_iterate (sol);

            if (status)   /* check if solver is stuck */
                break;

            status =
                gsl_multiroot_test_residual (sol->f, 1e-12);
        }
        while (status == GSL_CONTINUE && iter < 1000);

        s = gsl_vector_get (sol->x, 0);
        t = gsl_vector_get (sol->x, 1);

        gsl_multiroot_fsolver_free (sol);
        gsl_vector_free (x);
    }
#endif
}
예제 #15
0
static int
msbdf_apply (void *vstate, size_t dim, double t, double h,
             double y[], double yerr[],
             const double dydt_in[], double dydt_out[],
             const gsl_odeiv2_system * sys)
{
  /* Carries out a step by BDF linear multistep methods. */

  msbdf_state_t *state = (msbdf_state_t *) vstate;

  double *const z = state->z;
  double *const zbackup = state->zbackup;
  double *const ytmp = state->ytmp;
  double *const ytmp2 = state->ytmp2;
  double *const l = state->l;
  double *const hprev = state->hprev;
  double *const hprevbackup = state->hprevbackup;
  size_t *const ordprev = state->ordprev;
  size_t *const ordprevbackup = state->ordprevbackup;
  double *const errlev = state->errlev;
  gsl_vector *const abscor = state->abscor;
  gsl_vector *const relcor = state->relcor;
  gsl_vector *const svec = state->svec;
  gsl_vector *const tempvec = state->tempvec;

  size_t ord = state->ord;      /* order for this step */
  double ordm1coeff = 0.0;
  double ordp1coeff = 0.0;
  double ordp2coeff = 0.0;
  double errcoeff = 0.0;        /* error coefficient */
  double gamma = 0.0;           /* gamma coefficient */

  const size_t max_failcount = 3;
  size_t i;

#ifdef DEBUG
  {
    size_t di;

    printf ("msbdf_apply: t=%.5e, ord=%d, h=%.5e, y:", t, (int) ord, h);

    for (di = 0; di < dim; di++)
      {
        printf ("%.5e ", y[di]);
      }
    printf ("\n");
  }
#endif

  /* Check if t is the same as on previous stepper call (or last
     failed call). This means that calculation of previous step failed
     or the step was rejected, and therefore previous state will be
     restored or the method will be reset.
   */

  if (state->ni > 0 && (t == state->tprev || t == state->failt))
    {
      if (state->ni == 1)
        {
          /* No step has been accepted yet, reset method */

          msbdf_reset (vstate, dim);
#ifdef DEBUG
          printf ("-- first step was REJECTED, msbdf_reset called\n");
#endif
        }
      else
        {
          /* A succesful step has been saved, restore previous state. */

          /* If previous step suggests order increase, but the step was
             rejected, then do not increase order.
           */

          if (ord > ordprev[0])
            {
              state->ord = ordprev[0];
              ord = state->ord;
            }

          /* Restore previous state */

          DBL_MEMCPY (z, zbackup, (MSBDF_MAX_ORD + 1) * dim);
          DBL_MEMCPY (hprev, hprevbackup, MSBDF_MAX_ORD);

          for (i = 0; i < MSBDF_MAX_ORD; i++)
            {
              ordprev[i] = ordprevbackup[i];
            }

          state->ordwait = state->ordwaitbackup;
          state->gammaprev = state->gammaprevbackup;

#ifdef DEBUG
          printf ("-- previous step was REJECTED, state restored\n");
#endif
        }

      /* If step is repeatedly rejected, then reset method */

      state->failcount++;

      if (state->failcount > max_failcount && state->ni > 1)
        {
          msbdf_reset (vstate, dim);
          ord = state->ord;

#ifdef DEBUG
          printf ("-- max_failcount reached, msbdf_reset called\n");
#endif
        }
    }
  else
    {
      /* The previous step was accepted. Backup current state. */

      DBL_MEMCPY (zbackup, z, (MSBDF_MAX_ORD + 1) * dim);
      DBL_MEMCPY (hprevbackup, hprev, MSBDF_MAX_ORD);

      for (i = 0; i < MSBDF_MAX_ORD; i++)
        {
          ordprevbackup[i] = ordprev[i];
        }

      state->ordwaitbackup = state->ordwait;
      state->gammaprevbackup = state->gammaprev;

      state->failcount = 0;

#ifdef DEBUG
      if (state->ni > 0)
        {
          printf ("-- previous step was ACCEPTED, state saved\n");
        }
#endif
    }

#ifdef DEBUG
  printf ("-- ord=%d, ni=%ld, ordwait=%d\n", (int) ord, state->ni,
          (int) state->ordwait);

  size_t di;
  printf ("-- ordprev: ");

  for (di = 0; di < MSBDF_MAX_ORD; di++)
    {
      printf ("%d ", (int) ordprev[di]);
    }

  printf ("\n");
#endif

  /* Get desired error levels via gsl_odeiv2_control object through driver
     object, which is a requirement for this stepper.
   */

  if (state->driver == NULL)
    {
      return GSL_EFAULT;
    }
  else
    {
      size_t i;

      for (i = 0; i < dim; i++)
        {
          if (dydt_in != NULL)
            {
              gsl_odeiv2_control_errlevel (state->driver->c, y[i],
                                           dydt_in[i], h, i, &errlev[i]);
            }
          else
            {
              gsl_odeiv2_control_errlevel (state->driver->c, y[i],
                                           0.0, h, i, &errlev[i]);
            }
        }
    }

#ifdef DEBUG
  {
    size_t di;
    printf ("-- errlev: ");
    for (di = 0; di < dim; di++)
      {
        printf ("%.5e ", errlev[di]);
      }
    printf ("\n");
  }
#endif

  /* On first call initialize Nordsieck matrix */

  if (state->ni == 0)
    {
      size_t i;

      DBL_ZERO_MEMSET (z, (MSBDF_MAX_ORD + 1) * dim);

      if (dydt_in != NULL)
        {
          DBL_MEMCPY (ytmp, dydt_in, dim);
        }
      else
        {
          int s = GSL_ODEIV_FN_EVAL (sys, t, y, ytmp);

          if (s != GSL_SUCCESS)
            {
              return s;
            }
        }

      DBL_MEMCPY (&z[0 * dim], y, dim);
      DBL_MEMCPY (&z[1 * dim], ytmp, dim);

      for (i = 0; i < dim; i++)
        {
          z[1 * dim + i] *= h;
        }
    }

  /* Stability enhancement heuristic for msbdf: If order > 1 and order
     has not been changed, check for decrease in step size, that is
     not accompanied by a decrease in method order. This condition may
     be indication of BDF method stability problems, a change in ODE
     system, or convergence problems in Newton iteration. In all
     cases, the strategy is to decrease method order.
   */

#ifdef DEBUG
  printf ("-- check_no_order_decrease %d, check_step_size_decrease %d\n",
          msbdf_check_no_order_decrease (ordprev),
          msbdf_check_step_size_decrease (hprev));
#endif

  if (ord > 1 &&
      ord - ordprev[0] == 0 &&
      msbdf_check_no_order_decrease (ordprev) &&
      msbdf_check_step_size_decrease (hprev))
    {
      state->ord--;
      state->ordwait = ord + 2;
      ord = state->ord;

#ifdef DEBUG
      printf ("-- stability enhancement decreased order to %d\n", (int) ord);
#endif
    }

  /* Sanity check */

  { 
    const int deltaord = ord - ordprev[0];

  if (deltaord > 1 || deltaord < -1)
    {
      printf ("-- order change %d\n", deltaord);
      GSL_ERROR_NULL ("msbdf_apply too large order change", GSL_ESANITY);
    }

  /* Modify Nordsieck matrix if order or step length has been changed */

  /* If order increased by 1, adjust Nordsieck matrix */

  if (deltaord == 1)
    {
      if (ord > 2)
        {
          size_t i, j;
          double hsum = h;
          double coeff1 = -1.0;
          double coeff2 = 1.0;
          double hrelprev = 1.0;
          double hrelprod = 1.0;
          double hrel = 0.0;

          /* Calculate coefficients used in adjustment to l */

          DBL_ZERO_MEMSET (l, MSBDF_MAX_ORD + 1);

          l[2] = 1.0;

          for (i = 1; i < ord - 1; i++)
            {
              hsum += hprev[i];
              hrel = hsum / h;
              hrelprod *= hrel;
              coeff1 -= 1.0 / (i + 1);
              coeff2 += 1.0 / hrel;

              for (j = i + 2; j > 1; j--)
                {
                  l[j] *= hrelprev;
                  l[j] += l[j - 1];
                }

              hrelprev = hrel;
            }

          /* Scale Nordsieck matrix */

          {
            const double c = (-coeff1 - coeff2) / hrelprod;

            for (i = 0; i < dim; i++)
              {
                z[ord * dim + i] = c * gsl_vector_get (abscor, i);
              }
          }
          for (i = 2; i < ord; i++)
            for (j = 0; j < dim; j++)
              {
                z[i * dim + j] += l[i] * z[ord * dim + j];
              }
        }
      else
        {
          /* zero new vector for order incease from 1 to 2 */

          DBL_ZERO_MEMSET (&z[ord * dim], dim);
        }

#ifdef DEBUG
      printf ("-- order increase detected, Nordsieck modified\n");
#endif
    }

  /* If order decreased by 1, adjust Nordsieck matrix */

  if (deltaord == -1)
    {
      size_t i, j;
      double hsum = 0.0;

      /* Calculate coefficients used in adjustment to l */

      DBL_ZERO_MEMSET (l, MSBDF_MAX_ORD + 1);

      l[2] = 1.0;

      for (i = 1; i < ord; i++)
        {
          hsum += hprev[i - 1];

          for (j = i + 2; j > 1; j--)
            {
              l[j] *= hsum / h;
              l[j] += l[j - 1];
            }
        }

      /* Scale Nordsieck matrix */

      for (i = 2; i < ord + 1; i++)
        for (j = 0; j < dim; j++)
          {
            z[i * dim + j] += -l[i] * z[(ord + 1) * dim + j];
          }

#ifdef DEBUG
      printf ("-- order decrease detected, Nordsieck modified\n");
#endif
    }

  /* Scale Nordsieck vectors if step size has been changed */

  if (state->ni > 0 && h != hprev[0])
    {
      size_t i, j;
      const double hrel = h / hprev[0];
      double coeff = hrel;

      for (i = 1; i < ord + 1; i++)
        {
          for (j = 0; j < dim; j++)
            {
              z[i * dim + j] *= coeff;
            }

          coeff *= hrel;
        }

#ifdef DEBUG
      printf ("-- h != hprev, Nordsieck modified\n");
#endif
    }

  /* Calculate polynomial coefficients (l), error coefficient and
     auxiliary coefficients
   */

  msbdf_calccoeffs (ord, state->ordwait, h, hprev, l, &errcoeff,
                    &ordm1coeff, &ordp1coeff, &ordp2coeff, &gamma);

  /* Carry out the prediction step */

  {
    size_t i, j, k;

    for (i = 1; i < ord + 1; i++)
      for (j = ord; j > i - 1; j--)
        for (k = 0; k < dim; k++)
          {
            z[(j - 1) * dim + k] += z[j * dim + k];
          }

#ifdef DEBUG
    {
      size_t di;
      printf ("-- predicted y: ");
      for (di = 0; di < dim; di++)
        {
          printf ("%.5e ", z[di]);
        }
      printf ("\n");
    }
#endif
  }

  /* Calculate correction step to abscor */
  {
    int s;
    s = msbdf_corrector (vstate, sys, t, h, dim, z, errlev, l, errcoeff,
                         abscor, relcor, ytmp, ytmp2,
                         state->dfdy, state->dfdt, state->M,
                         state->p, state->rhs,
                         &(state->nJ), &(state->nM),
                         state->tprev, state->failt, gamma,
                         state->gammaprev, hprev[0]);

    if (s != GSL_SUCCESS)
      {
        return s;
      }
  }

  {
    /* Add accepted final correction step to Nordsieck matrix */

    size_t i, j;

    for (i = 0; i < ord + 1; i++)
      for (j = 0; j < dim; j++)
        {
          z[i * dim + j] += l[i] * gsl_vector_get (abscor, j);
        }

#ifdef DEBUG
    {
      size_t di;
      printf ("---- l: ");
      for (di = 0; di < ord + 1; di++)
        {
          printf ("%.5e ", l[di]);
        }
      printf ("\n");

      printf ("-- corrected y: ");
      for (di = 0; di < dim; di++)
        {
          printf ("%.5e ", z[di]);
        }
      printf ("\n");
    }
#endif

    /* Derivatives at output */

    if (dydt_out != NULL)
      {
        int s = GSL_ODEIV_FN_EVAL (sys, t + h, z, dydt_out);

        if (s == GSL_EBADFUNC)
          {
            return s;
          }

        if (s != GSL_SUCCESS)
          {
            msbdf_failurehandler (vstate, dim, t);

#ifdef DEBUG
            printf ("-- FAIL at user function evaluation\n");
#endif
            return s;
          }
      }

    /* Calculate error estimate */

    for (i = 0; i < dim; i++)
      {
        yerr[i] = fabs (gsl_vector_get (abscor, i)) * errcoeff;
      }

#ifdef DEBUG
    {
      size_t di;
      printf ("-- yerr: ");
      for (di = 0; di < dim; di++)
        {
          printf ("%.5e ", yerr[di]);
        }
      printf ("\n");
    }
#endif

    /* Save y values */

    for (i = 0; i < dim; i++)
      {
        y[i] = z[0 * dim + i];
      }
  }

  /* Scale abscor with errlev for later use in norm calculations */
  {
    size_t i;

    for (i = 0; i < dim; i++)
      {
        gsl_vector_set (abscor, i, gsl_vector_get (abscor, i) / errlev[i]);
      }
  }

  /* Save items needed for evaluation of order increase on next
     call, if needed
   */

  if (state->ordwait == 1 && ord < MSBDF_MAX_ORD)
    {
      size_t i;

      state->ordp1coeffprev = ordp1coeff;

      for (i = 0; i < dim; i++)
        {
          gsl_vector_set (svec, i, gsl_vector_get (abscor, i));
        }
    }

  /* Consider and execute order change for next step */

  if (state->ordwait == 0)
    {
      msbdf_eval_order (abscor, tempvec, svec, errcoeff, dim, errlev,
                        ordm1coeff, ordp1coeff,
                        state->ordp1coeffprev, ordp2coeff,
                        hprev, h, z, &(state->ord), &(state->ordwait));
    }

  /* Undo scaling of abscor for possible order increase on next step */
  {
    size_t i;
    
    for (i = 0; i < dim; i++)
      {
        gsl_vector_set (abscor, i, gsl_vector_get (abscor, i) * errlev[i]);
      }
  }
  
  /* Save information about current step in state and update counters */
  {
    size_t i;
    
    for (i = MSBDF_MAX_ORD - 1; i > 0; i--)
      {
        hprev[i] = hprev[i - 1];
        ordprev[i] = ordprev[i - 1];
      }
  }
  
  hprev[0] = h;
  ordprev[0] = ord;
  
#ifdef DEBUG
  {
    size_t di;
    printf ("-- hprev: ");
    for (di = 0; di < MSBDF_MAX_ORD; di++)
      {
        printf ("%.5e ", hprev[di]);
      }
    printf ("\n");
  }
#endif
  
  state->tprev = t;
  state->ordwait--;
  state->ni++;
  state->gammaprev = gamma;
  
  state->nJ++;
  state->nM++;
  
#ifdef DEBUG
  printf ("-- nJ=%d, nM=%d\n", (int) state->nJ, (int) state->nM);
#endif
  }

  return GSL_SUCCESS;
}
예제 #16
0
파일: linreg.c 프로젝트: RobertDash/pspp
void linreg_set_indep_variable_sd (linreg *c, size_t j, double s)
{
  assert (c != NULL);
  gsl_vector_set (c->indep_std, j, s);
}
예제 #17
0
static int
msbdf_corrector (void *vstate, const gsl_odeiv2_system * sys,
                 const double t, const double h, const size_t dim,
                 const double z[], const double errlev[],
                 const double l[], const double errcoeff,
                 gsl_vector * abscor, gsl_vector * relcor,
                 double ytmp[], double ytmp2[],
                 gsl_matrix * dfdy, double dfdt[], gsl_matrix * M,
                 gsl_permutation * p, gsl_vector * rhs,
                 size_t * nJ, size_t * nM,
                 const double tprev, const double failt,
                 const double gamma, const double gammaprev,
                 const double hprev0)
{
  /* Calculates the correction step (abscor). Equation
     system M = I - gamma * dfdy = -G is solved by Newton iteration.
   */

  size_t mi, i;
  const size_t max_iter = 3;    /* Maximum number of iterations */
  double convrate = 1.0;        /* convergence rate */
  double stepnorm = 0.0;        /* norm of correction step */
  double stepnormprev = 0.0;    /* previous norm value */

  /* Evaluate at predicted values */

  {
    int s = GSL_ODEIV_FN_EVAL (sys, t + h, z, ytmp);

    if (s == GSL_EBADFUNC)
      {
        return s;
      }

    if (s != GSL_SUCCESS)
      {
        msbdf_failurehandler (vstate, dim, t);

#ifdef DEBUG
        printf ("-- FAIL at user function evaluation\n");
#endif
        return s;
      }
  }

  /* Calculate correction step (abscor) */

  gsl_vector_set_zero (abscor);

  for (mi = 0; mi < max_iter; mi++)
    {
      const double safety = 0.3;
      const double safety2 = 0.1;

      /* Generate or update Jacobian and/or iteration matrix M if needed */

      if (mi == 0)
        {
          int s = msbdf_update (vstate, dim, dfdy, dfdt, t + h, z,
                                sys, M, p, mi,
                                nJ, nM, tprev, failt,
                                gamma, gammaprev,
                                h / hprev0);

          if (s != GSL_SUCCESS)
            {
              return s;
            }
        }

      /* Evaluate the right hand side (-G) */

      for (i = 0; i < dim; i++)
        {
          const double r = -1.0 * gsl_vector_get (abscor, i) -
            z[1 * dim + i] / l[1] + gamma * ytmp[i];

          gsl_vector_set (rhs, i, r);
        }

      /* Solve system of equations */

      {
        int s = gsl_linalg_LU_solve (M, p, rhs, relcor);
        
        if (s != GSL_SUCCESS)
          {
            msbdf_failurehandler (vstate, dim, t);
            
#ifdef DEBUG
            printf ("-- FAIL at LU_solve\n");
#endif
            return GSL_FAILURE;
          }
      }

#ifdef DEBUG
      {
        size_t di;
        printf ("-- dstep: ");
        for (di = 0; di < dim; di++)
          {
            printf ("%.5e ", gsl_vector_get (relcor, di));
          }
        printf ("\n");
      }
#endif

      /* Add iteration results */

      for (i = 0; i < dim; i++)
        {
          const double r =
            gsl_vector_get (abscor, i) + gsl_vector_get (relcor, i);

          gsl_vector_set (abscor, i, r);

          ytmp2[i] = z[i] + r;

          gsl_vector_set (relcor, i, gsl_vector_get (relcor, i) / errlev[i]);
        }

#ifdef DEBUG
      {
        size_t di;
        printf ("-- abscor: ");
        for (di = 0; di < dim; di++)
          {
            printf ("%.5e ", gsl_vector_get (abscor, di));
          }
        printf ("\n");
      }
#endif

      /* Convergence test. Norms used are root-mean-square norms. */

      stepnorm = gsl_blas_dnrm2 (relcor) / sqrt ((double)dim);

      if (mi > 0)
        {
          convrate = GSL_MAX_DBL (safety * convrate, stepnorm / stepnormprev);
        }
      else
        {
          convrate = 1.0;
        }

      {
        const double convtest =
          GSL_MIN_DBL (convrate, 1.0) * stepnorm * errcoeff / safety2;

#ifdef DEBUG
        printf
          ("-- newt iter loop %d, errcoeff=%.5e, stepnorm =%.5e, convrate = %.5e, convtest = %.5e\n",
           (int) mi, errcoeff, stepnorm, convrate, convtest);
#endif
        if (convtest <= 1.0)
          {
            break;
          }
      }

      /* Check for divergence during iteration */

      {
        const double div_const = 2.0;

        if (mi > 1 && stepnorm > div_const * stepnormprev)
          {
            msbdf_failurehandler (vstate, dim, t);

#ifdef DEBUG
            printf ("-- FAIL, diverging Newton iteration\n");
#endif
            return GSL_FAILURE;
          }
      }

      /* Evaluate at new y */

      {
        int s = GSL_ODEIV_FN_EVAL (sys, t + h, ytmp2, ytmp);

        if (s == GSL_EBADFUNC)
          {
            return s;
          }

        if (s != GSL_SUCCESS)
          {
            msbdf_failurehandler (vstate, dim, t);

#ifdef DEBUG
            printf ("-- FAIL at user function evaluation\n");
#endif
            return s;
          }
      }

      stepnormprev = stepnorm;
    }

#ifdef DEBUG
  printf ("-- Newton iteration exit at mi=%d\n", (int) mi);
#endif

  /* Handle convergence failure */

  if (mi == max_iter)
    {
      msbdf_failurehandler (vstate, dim, t);

#ifdef DEBUG
      printf ("-- FAIL, max_iter reached\n");
#endif
      return GSL_FAILURE;
    }

  return GSL_SUCCESS;
}
예제 #18
0
파일: linreg.c 프로젝트: RobertDash/pspp
static void
linreg_fit_qr (const gsl_matrix *cov, linreg *l)
{
  double intcpt_coef = 0.0;
  double intercept_variance = 0.0;
  gsl_matrix *xtx;
  gsl_matrix *q;
  gsl_matrix *r;
  gsl_vector *xty;
  gsl_vector *tau;
  gsl_vector *params;
  double tmp = 0.0;
  size_t i;
  size_t j;

  xtx = gsl_matrix_alloc (cov->size1 - 1, cov->size2 - 1);
  xty = gsl_vector_alloc (cov->size1 - 1);
  tau = gsl_vector_alloc (cov->size1 - 1);
  params = gsl_vector_alloc (cov->size1 - 1);

  for (i = 0; i < xtx->size1; i++)
    {
      gsl_vector_set (xty, i, gsl_matrix_get (cov, cov->size2 - 1, i));
      for (j = 0; j < xtx->size2; j++)
	{
	  gsl_matrix_set (xtx, i, j, gsl_matrix_get (cov, i, j));
	}
    }
  gsl_linalg_QR_decomp (xtx, tau);
  q = gsl_matrix_alloc (xtx->size1, xtx->size2);
  r = gsl_matrix_alloc (xtx->size1, xtx->size2);

  gsl_linalg_QR_unpack (xtx, tau, q, r);
  gsl_linalg_QR_solve (xtx, tau, xty, params);
  for (i = 0; i < params->size; i++)
    {
      l->coeff[i] = gsl_vector_get (params, i);
    }
  l->sst = gsl_matrix_get (cov, cov->size1 - 1, cov->size2 - 1);
  l->ssm = 0.0;
  for (i = 0; i < l->n_indeps; i++)
    {
      l->ssm += gsl_vector_get (xty, i) * l->coeff[i];
    }
  l->sse = l->sst - l->ssm;

  gsl_blas_dtrsm (CblasLeft, CblasLower, CblasNoTrans, CblasNonUnit, linreg_mse (l),
		  r, q);
  /* Copy the lower triangle into the upper triangle. */
  for (i = 0; i < q->size1; i++)
    {
      gsl_matrix_set (l->cov, i + 1, i + 1, gsl_matrix_get (q, i, i));
      for (j = i + 1; j < q->size2; j++)
	{
	  intercept_variance -= 2.0 * gsl_matrix_get (q, i, j) *
	    linreg_get_indep_variable_mean (l, i) *
	    linreg_get_indep_variable_mean (l, j);
	  gsl_matrix_set (q, i, j, gsl_matrix_get (q, j, i));
	}
    }
  l->intercept = linreg_get_depvar_mean (l);
  tmp = 0.0;
  for (i = 0; i < l->n_indeps; i++)
    {
      tmp = linreg_get_indep_variable_mean (l, i);
      l->intercept -= l->coeff[i] * tmp;
      intercept_variance += tmp * tmp * gsl_matrix_get (q, i, i);
    }

  /* Covariances related to the intercept. */
  intercept_variance += linreg_mse (l) / linreg_n_obs (l);
  gsl_matrix_set (l->cov, 0, 0, intercept_variance);  
  for (i = 0; i < q->size1; i++)
    {
      for (j = 0; j < q->size2; j++)
	{
	  intcpt_coef -= gsl_matrix_get (q, i, j) 
	    * linreg_get_indep_variable_mean (l, j);
	}
      gsl_matrix_set (l->cov, 0, i + 1, intcpt_coef);
      gsl_matrix_set (l->cov, i + 1, 0, intcpt_coef);
      intcpt_coef = 0.0;
    }
      
  gsl_matrix_free (q);
  gsl_matrix_free (r);
  gsl_vector_free (xty);
  gsl_vector_free (tau);
  gsl_matrix_free (xtx);
  gsl_vector_free (params);
}
예제 #19
0
double calcVBL(t_Cluster* ptCluster)
{
  int i = 0, k = 0, l = 0, nN = ptCluster->nN;
  int nK = ptCluster->nK, nD = ptCluster->nD;
  double dBishop1 = 0.0, dBishop2 = 0.0, dBishop3 = 0.0, dBishop4 = 0.0, dBishop5 = 0.0; /*Bishop equations 10.71...*/
  gsl_matrix *ptRes  = gsl_matrix_alloc(nD,nD);
  gsl_vector *ptDiff = gsl_vector_alloc(nD);
  gsl_vector *ptR = gsl_vector_alloc(nD);
  double dD = (double) nD;
  double** aadMu = ptCluster->aadMu, **aadM = ptCluster->aadM, **aadZ = ptCluster->aadZ;
  double* adBeta = ptCluster->adBeta, *adNu = ptCluster->adNu, *adLDet = ptCluster->adLDet, *adPi = ptCluster->adPi;
  double adNK[nK];
  double d2Pi = 2.0*M_PI, dBeta0 = ptCluster->ptVBParams->dBeta0, dNu0 = ptCluster->ptVBParams->dNu0, dRet = 0.0;
  double dK = 0.0;

  for(k = 0; k < nK; k++){
    adNK[k] = 0.0;
  }

  /*Equation 10.72*/
  for(i = 0; i < nN; i++){
    for(k = 0; k < nK; k++){
      adNK[k] += aadZ[i][k];
      if(adPi[k] > 0.0){
	dBishop2 += aadZ[i][k]*log(adPi[k]);
      }
    }
  }

  for(k = 0; k < nK; k++){
    if(adNK[k] > 0.0){
      dK++;
    }
  }

  /*Equation 10.71*/
  for(k = 0; k < nK; k++){
    if(adNK[k] > 0.0){
      double dT1 = 0.0, dT2 = 0.0, dF = 0.0;

      gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0,ptCluster->aptCovar[k],ptCluster->aptSigma[k],0.0,ptRes);

      for(l = 0; l < nD; l++){
	dT1 += gsl_matrix_get(ptRes,l,l);
      }
    
      for(l = 0; l < nD; l++){
	gsl_vector_set(ptDiff,l,aadMu[k][l] - aadM[k][l]);
      }

      gsl_blas_dsymv (CblasLower, 1.0, ptCluster->aptSigma[k], ptDiff, 0.0, ptR);
      
      gsl_blas_ddot (ptDiff, ptR, &dT2);

      dF = adLDet[k] - adNu[k]*(dT1 + dT2) - dD*(log(d2Pi) + (1.0/adBeta[k]));

      dBishop1 += 0.5*adNK[k]*dF;
    }
  }

  /*Equation 10.74*/
  for(k = 0; k < nK; k++){
    if(adNK[k] > 0.0){
      double dT1 = 0.0, dT2 = 0.0, dF = 0.0;

      gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0,ptCluster->ptVBParams->ptInvW0,ptCluster->aptSigma[k],0.0,ptRes);

      for(l = 0; l < nD; l++){
	dT1 += gsl_matrix_get(ptRes,l,l);
      }

      for(l = 0; l < nD; l++){
	gsl_vector_set(ptDiff,l,aadM[k][l]);
      }

      gsl_blas_dsymv (CblasLower, 1.0, ptCluster->aptSigma[k], ptDiff, 0.0, ptR);
      
      gsl_blas_ddot (ptDiff, ptR, &dT2);

      dF = dD*log(dBeta0/d2Pi) + adLDet[k] - ((dD*dBeta0)/adBeta[k]) - dBeta0*adNu[k]*dT2 - adNu[k]*dT1;

      dBishop3 += 0.5*(dF + (dNu0 - dD - 1.0)*adLDet[k]);
    }
  }

  dBishop3 += dK*ptCluster->ptVBParams->dLogWishartB;

  /*Equation 10.75*/
  for(i = 0; i < nN; i++){
    for(k = 0; k < nK; k++){
      if(aadZ[i][k] > 0.0){
	dBishop4 += aadZ[i][k]*log(aadZ[i][k]);
      }
    }
  }

  /*Equation 10.77*/
  for(k = 0; k < nK; k++){
    if(adNK[k] > 0.0){
      dBishop5 += 0.5*adLDet[k] + 0.5*dD*log(adBeta[k]/d2Pi) - 0.5*dD - dWishartExpectLogDet(ptCluster->aptSigma[k], adNu[k], nD);
    }  
  }

  gsl_matrix_free(ptRes);
  gsl_vector_free(ptDiff);
  gsl_vector_free(ptR);
  
  dRet = dBishop1 + dBishop2 + dBishop3 - dBishop4 - dBishop5;

  return dRet;
}