void Foam::CentredFitSnGradData<Polynomial>::calcFit() { const fvMesh& mesh = this->mesh(); // Get the cell/face centres in stencil order. // Centred face stencils no good for triangles or tets. // Need bigger stencils List<List<point>> stencilPoints(mesh.nFaces()); this->stencil().collectData(mesh.C(), stencilPoints); // find the fit coefficients for every face in the mesh const surfaceScalarField& w = mesh.surfaceInterpolation::weights(); const surfaceScalarField& dC = mesh.nonOrthDeltaCoeffs(); for (label facei = 0; facei < mesh.nInternalFaces(); facei++) { calcFit ( coeffs_[facei], stencilPoints[facei], w[facei], dC[facei], facei ); } const surfaceScalarField::Boundary& bw = w.boundaryField(); const surfaceScalarField::Boundary& bdC = dC.boundaryField(); forAll(bw, patchi) { const fvsPatchScalarField& pw = bw[patchi]; const fvsPatchScalarField& pdC = bdC[patchi]; if (pw.coupled()) { label facei = pw.patch().start(); forAll(pw, i) { calcFit ( coeffs_[facei], stencilPoints[facei], pw[i], pdC[i], facei ); facei++; } }
Foam::UpwindFitData<Polynomial>::UpwindFitData ( const fvMesh& mesh, const extendedUpwindCellToFaceStencil& stencil, const bool linearCorrection, const scalar centralWeight ) : FitData < UpwindFitData<Polynomial>, extendedUpwindCellToFaceStencil, Polynomial > ( mesh, stencil, linearCorrection, centralWeight ), owncoeffs_(mesh.nFaces()), neicoeffs_(mesh.nFaces()) { if (debug) { Info<< "Contructing UpwindFitData<Polynomial>" << endl; } calcFit(); if (debug) { Info<< "UpwindFitData<Polynomial>::UpwindFitData() :" << "Finished constructing polynomialFit data" << endl; } }
Foam::CentredFitSnGradData<Polynomial>::CentredFitSnGradData ( const fvMesh& mesh, const extendedCentredCellToFaceStencil& stencil, const scalar linearLimitFactor, const scalar centralWeight ) : FitData < CentredFitSnGradData<Polynomial>, extendedCentredCellToFaceStencil, Polynomial > ( mesh, stencil, true, linearLimitFactor, centralWeight ), coeffs_(mesh.nFaces()) { if (debug) { InfoInFunction << "Constructing CentredFitSnGradData<Polynomial>" << endl; } calcFit(); if (debug) { Info<< " Finished constructing polynomialFit data" << endl; } }
/* * getResidual(residual). * * Returns image - fit. * * residual - Pre-allocated space to store the residual values. * This should be square & the same size as the image. */ void getResidual(double *residual) { int i; calcFit(); for(i=0;i<(image_size_x*image_size_y);i++){ residual[i] = x_data[i] - f_data[i]; //residual[i] = x_data[i] - (f_data[i] + scmos_term[i]); } }
bool Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::movePoints() { calcFit(); return true; }
Foam::quadraticFitSnGradData::quadraticFitSnGradData ( const fvMesh& mesh, const scalar cWeight ) : MeshObject<fvMesh, quadraticFitSnGradData>(mesh), centralWeight_(cWeight), #ifdef SPHERICAL_GEOMETRY dim_(2), #else dim_(mesh.nGeometricD()), #endif minSize_ ( dim_ == 1 ? 3 : dim_ == 2 ? 6 : dim_ == 3 ? 9 : 0 ), stencil_(mesh), fit_(mesh.nInternalFaces()) { if (debug) { Info << "Contructing quadraticFitSnGradData" << endl; } // check input if (centralWeight_ < 1 - SMALL) { FatalErrorIn("quadraticFitSnGradData::quadraticFitSnGradData") << "centralWeight requested = " << centralWeight_ << " should not be less than one" << exit(FatalError); } if (minSize_ == 0) { FatalErrorIn("quadraticFitSnGradData") << " dimension must be 1,2 or 3, not" << dim_ << exit(FatalError); } // store the polynomial size for each face to write out surfaceScalarField snGradPolySize ( IOobject ( "quadraticFitSnGradPolySize", "constant", mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedScalar("quadraticFitSnGradPolySize", dimless, scalar(0)) ); // Get the cell/face centres in stencil order. // Centred face stencils no good for triangles of tets. Need bigger stencils List<List<point> > stencilPoints(stencil_.stencil().size()); stencil_.collectData ( mesh.C(), stencilPoints ); // find the fit coefficients for every face in the mesh for(label faci = 0; faci < mesh.nInternalFaces(); faci++) { snGradPolySize[faci] = calcFit(stencilPoints[faci], faci); } if (debug) { snGradPolySize.write(); Info<< "quadraticFitSnGradData::quadraticFitSnGradData() :" << "Finished constructing polynomialFit data" << endl; } }
// GA function accepts data matrix, legal gene matrix, and number of total genes wanted in final matrix // New stopping criterion: when PD does not increase for maxGenStalled generations int optimizeDecisivnessGA (vector < vector <int> > & data, vector < vector <int> > const& legal, int const& numAdd, bool const& referenceTaxonPresent, int const& numProcs) { // initialize random number generator - already done in main // srand((unsigned)time(0)); // Constants. Some should probably be user specified: tournamentSize, populationSize, mutationProbability, maxgen // int numTaxa = data.size(); // not used // int numLoci = data[0].size(); // not used int numInitialLoci = countLociPresent(data); int tournamentSize = 5; // size of tournament group. const int populationSize = 500; double mutationProbability = 0.9; // probability of mutation, otherwise xover //double stepReplaceProbability = 0.01; int maxgen = 100000; // maximum number of generations; ramp up to 100000 or whatever int numTrees = 100; // ramp up to 1000 double bestSolution = 0.0; vector < vector <int> > bestConfiguration; int genStalled = 0; // number of generations without an increase in best fitness. int maxGenStalled = 5000; // Store fitness double fitness[populationSize]; // cout << "initialize " << endl; // Initialize population vector < vector <int> > population[populationSize]; // int numAdd = maxGenes - numInitialLoci; // number of genes to add int maxGenes = numInitialLoci + numAdd; // cout << "Initial count = " << numInitialLoci << "; adding " << numAdd // << " sampled characters for total of " << maxGenes << " occupied cells of a possible " // << data.size() * data[0].size() << "." << endl; // Function currently errors out when too many genes initially present. // This should be changed to allow genes to be removed. cout << endl << "SETTING UP INITIAL POPULATION" << endl << endl; cout << "Population consists of " << populationSize << " individuals." << endl; if (numAdd < 0) { // subtract genes; not sure when this will be used... cout << numAdd << " populated cells will be removed." << endl; for (int i = 0; i < populationSize; i++) { population[i] = data; for (int j = numAdd; j < 0; j++) { mutate(population[i], legal, 0, 1); } } } else { // add genes cout << numAdd << " additional random taxon-character cells will be populated for each individual..." << endl; for (int i = 0; i < populationSize; i++) { population[i] = data; for (int j = 0; j < numAdd; j++) { // Randomly add numAdd genes in legal positions mutate(population[i], legal, 1, 0); // last 2 arguments are add, remove (boolean) } } } cout << "Done." << endl << endl; //cout << "Best solution from initial population = " << bestSolution << "." << endl; // Calculate initial fitness. For each matrix, crunch through 1000 trees cout << "Calculating initial fitnesses for all individuals..." << endl; for (int i = 0; i < populationSize; i++) { fitness[i] = calcFit(referenceTaxonPresent, numTrees, population[i], numProcs); // cout << "Fitness for individual " << i << " is: " << fitness[i] << "." << endl; if (fitness[i] > bestSolution) { bestSolution = fitness[i]; bestConfiguration = population[i]; // cout << "Best solution from initial population = " << bestSolution << "." << endl; } } cout << "Done." << endl; cout << "Best solution from initial population = " << bestSolution << "." << endl; bool done = 0; // flag to end evolution loop int gen = 0; // counter for number of generations // Check for out of bounds parameter values if (populationSize < 3) { cout << "Population size must be greater than 2" << endl; return(1); } if (tournamentSize < 2) { cout << "Tournament group size must be greater than 1" << endl; return(1); } // Evolution loop cout << endl << "STARTING EVOLUTION" << endl << endl; cout << "Running for a total of " << maxgen << " generations." << endl << endl; // cout << "Progress:" << endl; while (!done) { gen = gen + 1; cout << "Generation " << gen; // Choose tournament group // initialize best and worst with random int random = (int)(rand() % (populationSize)); int best = random; // integer to hold position of best member of tournament group int worst = random; // position of worst member of tournament group double bestFit = fitness[random]; // best fitness double worstFit = fitness[random]; // worst fitness // selection step //for (int i = 1; i < tournamentSize; i++) for (int i = 0; i < tournamentSize; i++) { random = (int)(rand() % populationSize); if (fitness[random] > bestFit) { bestFit = fitness[random]; best = random; } if (fitness[random] < worstFit) { worstFit = fitness[random]; worst = random; } } // make sure best and worst are not the same // if they are the same, choose new best randomly from population while (best == worst) { best = (int)(rand() % (populationSize)); } // Copy best individual to worst individual population[worst] = population[best]; // enter stepwise function. too demanding. // if (gen % 1000 == 0) { // cout << ": Entering stepwise phase." << endl; // stepReplace (population[worst], legal, maxGenes, referenceTaxonPresent, numProcs); // } // else { // Mutate with some probability, otherwise xover double randmu = (double) rand() / RAND_MAX; if (randmu < mutationProbability) { // mutate; change one cell. mutate(population[worst], legal, 1, 1); } else { // xover with random individual in population int randx = (int)(rand() % populationSize); while (randx == worst) { randx = (int)(rand() % populationSize); } xover(population[worst], population[randx], legal, maxGenes); } // } // Calculate fitness of new individual fitness[worst] = calcFit(referenceTaxonPresent, numTrees, population[worst], numProcs); if (fitness[worst] > bestSolution) { bestSolution = fitness[worst]; bestConfiguration = population[worst]; genStalled = 0; } else { genStalled += 1; } // Check to see if max number of generations has been reached cout << ": best solution thus far = " << bestSolution << "." << endl; if (gen == maxgen || genStalled == maxGenStalled) { done = 1; } } // End of evolution loop // double bestFit = 0; // int bestInd = 0; // for (int i = 0; i < populationSize; i++) // { // if (fitness[i] > bestFit) { // bestFit = fitness[i]; // bestInd = i; // } // } // cout << endl << "Best result found: " << bestFit << endl; // copy best evolved matrix to original data matrix // data = population[bestInd]; //printData(data); cout << endl << "Best result found: " << bestSolution << endl; data = bestConfiguration; cout << endl; return(0); }
// This is pretty computationally demanding. Lowering number of trees evaluated. int stepReplace (vector < vector < int > > & data, vector < vector < int > > const& legal, int const& maxGenes, bool const& referenceTaxonPresent, int const& numProcs) { int maxLoops = 100; // maximum number of iterations through while loop. This would be better as a user defined parameter. int numTaxa = data.size(); int numLoci = data[0].size(); int numInitialLoci = countLociPresent(data); int numTrees = 100; // fill matrix randomly int numAdd = maxGenes - numInitialLoci; // number of genes to add if (numAdd < 0) { // subtract genes cout << "Genes will be removed" << endl; for (int j = numAdd; j < 0; j++) { mutate(data, legal, 0, 1); } } else { // add genes for (int j = 0; j < numAdd; j++) { mutate(data, legal, 1, 0); } } bool done = 0; // flag for end of loop int loops = 0; // counter for number of times through while loop // probably better if taxa and loci selected randomly. while (!done) { loops++; int moves = 0; cout << "Step #" << loops << endl; vector <int> temp (numTaxa); for (int i = 0; i < numTaxa; i++) { temp[i] = i; } vector <int> taxaOrder (numTaxa); for (int i = 0; i < numTaxa; i++) { taxaOrder[i] = (int)(rand() % (int)temp.size()); } for (int k = 0; k < numTaxa; k++) { int taxa = taxaOrder[k]; for (int loci = 0; loci < numLoci; loci++) { if (data[taxa][loci] & legal[taxa][loci]) { // if loci present and movable data[taxa][loci] = 0; // remove datum // use -1 to solve uninitializing problems int bestTax = -1; // store best taxa int bestLoci = -1; // store best loci //int bestTax; // store best taxa //int bestLoci; // store best loci //double bestDecisive = calcFit(data); // store best decisiveness double bestDecisive = calcFit(referenceTaxonPresent, numTrees, data, numProcs); // test all possible positions for (int i = 0; i < numTaxa; i++) { for (int j = 0; j < numLoci; j++) { if (legal[i][j] & !data[i][j]) { vector < vector < int > > temp = data; temp[i][j] = 1; //double tempDecisive = calcFit(temp); double tempDecisive = calcFit(referenceTaxonPresent, numTrees, temp, numProcs); if (tempDecisive >= bestDecisive) { bestDecisive = tempDecisive; bestTax = i; bestLoci = j; } } } } if (bestTax != -1 && bestLoci != -1) { data[bestTax][bestLoci] = 1; } data[bestTax][bestLoci] = 1; // add loci to best position if ((bestTax != taxa) || (bestLoci != loci)) { moves++; } } } } // done when no moves made if (moves < 1) done = 1; // check for maximum number of iterations if (loops >= maxLoops) { cout << "Max loops reached" << endl; done = 1; } } return(0); }
/* * initialize(image, params, tol, im_size, n) * * Initializes fitting things for fitting. * * image - pointer to the image data. * scmos_calibration - sCMOS calibration data, variance/gain^2 for each pixel in the image. * params - pointer to the initial values for the parameters for each point. * 1. height * 2. x-center * 3. x-sigma * 4. y-center * 5. y-sigma * 6. background * 7. z-center * 8. status * 9. error * .. repeat .. * im_size_x - size of the image in x. * im_size_y - size of the image in y. * n - number of parameters. * zfit - fitting wx, wy based on z? */ void initialize(double *image, double *scmos_calibration, double *params, double tol, int im_size_x, int im_size_y, int n, int zfit) { int i,j; nfit = n; image_size_x = im_size_x; image_size_y = im_size_y; tolerance = tol; x_data = (double *)malloc(sizeof(double)*image_size_x*image_size_y); f_data = (double *)malloc(sizeof(double)*image_size_x*image_size_y); bg_data = (double *)malloc(sizeof(double)*image_size_x*image_size_y); bg_counts = (int *)malloc(sizeof(int)*image_size_x*image_size_y); scmos_term = (double *)malloc(sizeof(double)*image_size_x*image_size_y); for(i=0;i<(image_size_x*image_size_y);i++){ x_data[i] = image[i]; scmos_term[i] = scmos_calibration[i]; } fit = (fitData *)malloc(sizeof(fitData)*nfit); for(i=0;i<nfit;i++){ fit[i].status = (int)(params[i*NRESULTSPAR+STATUS]); if(fit[i].status==RUNNING){ fit[i].error = 0.0; fit[i].error_old = 0.0; } else { fit[i].error = params[i*NRESULTSPAR+IERROR]; fit[i].error_old = fit[i].error; } fit[i].params[HEIGHT] = params[i*NRESULTSPAR+HEIGHT]; fit[i].params[XCENTER] = params[i*NRESULTSPAR+XCENTER]; fit[i].params[YCENTER] = params[i*NRESULTSPAR+YCENTER]; fit[i].params[BACKGROUND] = params[i*NRESULTSPAR+BACKGROUND]; fit[i].params[ZCENTER] = params[i*NRESULTSPAR+ZCENTER]; if(zfit){ calcWidthsFromZ(&fit[i]); } else{ fit[i].params[XWIDTH] = 1.0/(2.0*params[i*NRESULTSPAR+XWIDTH]*params[i*NRESULTSPAR+XWIDTH]); fit[i].params[YWIDTH] = 1.0/(2.0*params[i*NRESULTSPAR+YWIDTH]*params[i*NRESULTSPAR+YWIDTH]); } // printf("%d %.3f %.3f %.2f %.2f\n", i, fit[i].params[XCENTER], fit[i].params[YCENTER], fit[i].params[HEIGHT], fit[i].params[BACKGROUND]); fit[i].xc = (int)fit[i].params[XCENTER]; fit[i].yc = (int)fit[i].params[YCENTER]; fit[i].wx = calcWidth(fit[i].params[XWIDTH],-10.0); fit[i].wy = calcWidth(fit[i].params[YWIDTH],-10.0); // // FIXME: It would probably better to pass these in. // Currently "tuned" for "standard" STORM images. // fit[i].clamp[HEIGHT] = 1000.0; fit[i].clamp[XCENTER] = 1.0; fit[i].clamp[XWIDTH] = 0.3; fit[i].clamp[YCENTER] = 1.0; fit[i].clamp[YWIDTH] = 0.3; fit[i].clamp[BACKGROUND] = 100.0; fit[i].clamp[ZCENTER] = 0.1; for(j=0;j<NPEAKPAR;j++){ fit[i].sign[j] = 0; } } calcFit(); calcErr(); }