float Continuous::getMomentCore(int iMoment, const Ensemble& iEnsemble, const Parameters& iParameters) const { // TODO: Not tested const Variable* var = Variable::get(iEnsemble.getVariable()); float total = 0; float minX = var->getMin(); float maxX = var->getMax(); int nX = 1000; float dX = (maxX - minX)/((float) nX); float c = 0; if(iMoment > 1) { // Compute center of moment c = getMoment(1, iEnsemble, iParameters); } for(int i = 0; i < nX; i++) { float x = minX + i*dX; float pdf = getPdf(x, iEnsemble, iParameters); if(!Global::isValid(pdf)) return Global::MV; total += pow(x - c, iMoment) * pdf; } return total * dX; }
float Continuous::getInvCore(float iCdf, const Ensemble& iEnsemble, const Parameters& iParameters) const { float step = 10; // TODO float X = 5; float currCdf = getCdf(X, iEnsemble, iParameters); if(!Global::isValid(currCdf)) return Global::MV; int dir = 0; int counter = 0; const Variable* var = Variable::get(iEnsemble.getVariable()); bool lowerDiscrete = var->isLowerDiscrete(); bool upperDiscrete = var->isUpperDiscrete(); float varMin = var->getMin(); float varMax = var->getMax(); while(fabs(currCdf - iCdf) > mInvTol) { if(currCdf > iCdf) { if(dir == 1) { step /= 2; } X = X - step; dir = -1; } else { if(dir == -1) { step /= 2; } X = X + step; dir = 1; } // Check that we are not stepping outside the variable's domain if(lowerDiscrete && X < varMin) X = varMin; if(upperDiscrete && X > varMax) X = varMax; if(!Global::isValid(X)) return Global::MV; if(counter > 1000) { std::cout << "Continuous.cpp: Could not converge on CDF target: " << iCdf << " " << X << " " << currCdf << std::endl; return X; } currCdf = getCdf(X, iEnsemble, iParameters); if(!Global::isValid(currCdf)) { return Global::MV; } if(lowerDiscrete && X == varMin && currCdf > iCdf) return X; if(upperDiscrete && X == varMax && currCdf < iCdf) return X; counter++; } return X; }
void CorrectorClim::correctCore(const Parameters& iParameters, Ensemble& iEnsemble) const { float climWeight = iParameters[0]; float ensWeight = 1 - climWeight; float clim; if(mComputeClim) { assert(iParameters.size() == 2); clim = iParameters[1]; } else clim = mData.getClim(iEnsemble.getDate(), iEnsemble.getInit(), iEnsemble.getOffset(), iEnsemble.getLocation(), iEnsemble.getVariable()); if(Global::isValid(clim) && Global::isValid(ensWeight) && Global::isValid(climWeight)) { for(int n = 0; n < iEnsemble.size(); n++) { float currValue = iEnsemble[n]; if(Global::isValid(currValue)) { iEnsemble[n] = currValue * ensWeight + clim * climWeight; } } } }
float MeasureLocalGradient::measureCore(const Ensemble& iEnsemble) const { int date = iEnsemble.getDate(); int init = iEnsemble.getInit(); float offset = iEnsemble.getOffset(); Location loc = iEnsemble.getLocation(); // Determine which variable to use std::string var = mVariable; if(mVariable == "") { var = iEnsemble.getVariable(); } std::string dataset = loc.getDataset(); float centerValue = iEnsemble.getMoment(1); // Get nearby locations Input* input = mData.getInput(dataset); std::vector<Location> nearbyLocations; input->getSurroundingLocations(loc, nearbyLocations, 4); // Compute gradient float grad; int counter = 0; for(int i = 0; i < (int) nearbyLocations.size(); i++) { Ensemble ens; mData.getEnsemble(date, init, offset, nearbyLocations[i], dataset, var, ens); float mean = ens.getMoment(1); if(Global::isValid(mean)) { // TODO float dist = 0; float dvdx = 0; float dydy = 0; counter++; } } return iEnsemble.getMoment(2); }
bool Qc::qc(Ensemble& iEnsemble) const { bool anyChanges = false; for(int i = 0; i < iEnsemble.size(); i++) { if(!check(Value(iEnsemble[i], iEnsemble.getDate(), iEnsemble.getInit(), iEnsemble.getOffset(), iEnsemble.getLocation(), iEnsemble.getVariable()))) { anyChanges = true; iEnsemble[i] = Global::MV; } } return anyChanges; }