/** 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( ¤t_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 = ∥ 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; }
// 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)); }
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; } }
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; }
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; }
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; } }
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); }
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 */
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); }
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; }
/** 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; }
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 }
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, º1coeff, &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; }
void linreg_set_indep_variable_sd (linreg *c, size_t j, double s) { assert (c != NULL); gsl_vector_set (c->indep_std, j, s); }
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; }
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); }
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; }