void CStringEx::PutFloatS(float f, int len) { // Code From // Copyright SOCABIM 1999 // Pierre Caussin // Jean-Paul Retru switch (_fpclass(f)) { case _FPCLASS_SNAN: case _FPCLASS_QNAN: Format("%s", m_csNAN); // "NaN" return; case _FPCLASS_NINF: Format("%s", m_csNINF);// "-Inf" return; case _FPCLASS_PINF: Format("%s", m_csPINF);// "+Inf" return; } PutDoubleS((double) f, len); int acc = 8; if(len< acc+1) return; Accuracy(acc); return; }
void OsuScore::computeSpeedValue(const Beatmap& beatmap) { _speedValue = pow(5.0f * std::max(1.0f, beatmap.DifficultyAttribute(_mods, Beatmap::Speed) / 0.0675f) - 4.0f, 3.0f) / 100000.0f; int numTotalHits = TotalHits(); f32 approachRate = beatmap.DifficultyAttribute(_mods, Beatmap::AR); f32 approachRateFactor = 1.0f; if (approachRate > 10.33f) approachRateFactor += 0.3f * (approachRate - 10.33f); _speedValue *= approachRateFactor; // Longer maps are worth more _speedValue *= 0.95f + 0.4f * std::min(1.0f, static_cast<f32>(numTotalHits) / 2000.0f) + (numTotalHits > 2000 ? log10(static_cast<f32>(numTotalHits) / 2000.0f) * 0.5f : 0.0f); // Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available _speedValue *= pow(0.97f, _numMiss); // Combo scaling float maxCombo = beatmap.DifficultyAttribute(_mods, Beatmap::MaxCombo); if (maxCombo > 0) _speedValue *= std::min(static_cast<f32>(pow(_maxCombo, 0.8f) / pow(maxCombo, 0.8f)), 1.0f); // We want to give more reward for lower AR when it comes to speed and HD. This nerfs high AR and buffs lower AR. if ((_mods & EMods::Hidden) > 0) _speedValue *= 1.0f + 0.04f * (12.0f - approachRate); // Scale the speed value with accuracy _slightly_ _speedValue *= 0.02f + Accuracy(); // It is important to also consider accuracy difficulty when doing that _speedValue *= 0.96f + (pow(beatmap.DifficultyAttribute(_mods, Beatmap::OD), 2) / 1600); }
double LetterClassifier::Test(const cv::Mat &test_dataset, const cv::Mat &test_labels) { if (mean.empty()) LoadPCAcoeffs(); cv::Mat src, avg, trans, pred_labels; // cv::repeat(mean, 1, test_dataset.cols, avg); // src = test_dataset - avg; trans = coeffs.t()*test_dataset; cvsvm->predict(trans.t(), pred_labels); pred_labels.convertTo(pred_labels, test_labels.type()); return Accuracy(pred_labels, test_labels); }
void OsuScore::computeAimValue(const Beatmap& beatmap) { f32 rawAim = beatmap.DifficultyAttribute(_mods, Beatmap::Aim); if ((_mods & EMods::TouchDevice) > 0) rawAim = pow(rawAim, 0.8f); _aimValue = pow(5.0f * std::max(1.0f, rawAim / 0.0675f) - 4.0f, 3.0f) / 100000.0f; int numTotalHits = TotalHits(); // Longer maps are worth more f32 LengthBonus = 0.95f + 0.4f * std::min(1.0f, static_cast<f32>(numTotalHits) / 2000.0f) + (numTotalHits > 2000 ? log10(static_cast<f32>(numTotalHits) / 2000.0f) * 0.5f : 0.0f); _aimValue *= LengthBonus; // Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available _aimValue *= pow(0.97f, _numMiss); // Combo scaling float maxCombo = beatmap.DifficultyAttribute(_mods, Beatmap::MaxCombo); if (maxCombo > 0) _aimValue *= std::min(static_cast<f32>(pow(_maxCombo, 0.8f) / pow(maxCombo, 0.8f)), 1.0f); f32 approachRate = beatmap.DifficultyAttribute(_mods, Beatmap::AR); f32 approachRateFactor = 1.0f; if (approachRate > 10.33f) approachRateFactor += 0.3f * (approachRate - 10.33f); else if (approachRate < 8.0f) { approachRateFactor += 0.01f * (8.0f - approachRate); } _aimValue *= approachRateFactor; // We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR. if ((_mods & EMods::Hidden) > 0) _aimValue *= 1.0f + 0.04f * (12.0f - approachRate); if ((_mods & EMods::Flashlight) > 0) // Apply object-based bonus for flashlight. _aimValue *= 1.0f + 0.35f * std::min(1.0f, static_cast<f32>(numTotalHits) / 200.0f) + (numTotalHits > 200 ? 0.3f * std::min(1.0f, static_cast<f32>(numTotalHits - 200) / 300.0f) + (numTotalHits > 500 ? static_cast<f32>(numTotalHits - 500) / 1200.0f : 0.0f) : 0.0f); // Scale the aim value with accuracy _slightly_ _aimValue *= 0.5f + Accuracy() / 2.0f; // It is important to also consider accuracy difficulty when doing that _aimValue *= 0.98f + (pow(beatmap.DifficultyAttribute(_mods, Beatmap::OD), 2) / 2500); }
void CStringEx::PutDoubleS(double value, int nsignificands) { // Code From // Copyright SOCABIM 1999 // Pierre Caussin // Jean-Paul Retru CString fmt; int nk; switch (_fpclass(value)) { case _FPCLASS_SNAN: case _FPCLASS_QNAN: Format("%s", m_csNAN); // "NaN" return; case _FPCLASS_NINF: Format("%s", m_csNINF);// "-Inf" return; case _FPCLASS_PINF: Format("%s", m_csPINF);// "+Inf" return; case _FPCLASS_NN: case _FPCLASS_PN: nk = (int)log10(fabs(value)); if (fabs(value)<1) nk--; if (nk > nsignificands+1 || nk < 2-nsignificands) { fmt.Format("%%.%dfE%d",nsignificands-1,nk); Format(fmt,value/pow(10.,nk)); } else { fmt.Format("%%.%df",nsignificands>nk+1?nsignificands-nk-1:0); Format(fmt,value); } return; default: fmt.Format("%%.%df",nsignificands); Format(fmt,0.); } int acc = 16; Accuracy(acc); return; }
void OsuScore::computeAccValue(const Beatmap& beatmap) { // This percentage only considers HitCircles of any value - in this part of the calculation we focus on hitting the timing hit window f32 betterAccuracyPercentage; s32 numHitObjectsWithAccuracy; if (beatmap.ScoreVersion() == Beatmap::EScoreVersion::ScoreV2) { numHitObjectsWithAccuracy = TotalHits(); betterAccuracyPercentage = Accuracy(); } // Either ScoreV1 or some unknown value. Let's default to previous behavior. else { numHitObjectsWithAccuracy = beatmap.NumHitCircles(); if (numHitObjectsWithAccuracy > 0) betterAccuracyPercentage = static_cast<f32>((_num300 - (TotalHits() - numHitObjectsWithAccuracy)) * 6 + _num100 * 2 + _num50) / (numHitObjectsWithAccuracy * 6); else betterAccuracyPercentage = 0; // It is possible to reach a negative accuracy with this formula. Cap it at zero - zero points if (betterAccuracyPercentage < 0) betterAccuracyPercentage = 0; } // Lots of arbitrary values from testing. // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution _accValue = pow(1.52163f, beatmap.DifficultyAttribute(_mods, Beatmap::OD)) * pow(betterAccuracyPercentage, 24) * 2.83f; // Bonus for many hitcircles - it's harder to keep good accuracy up for longer _accValue *= std::min(1.15f, static_cast<f32>(pow(numHitObjectsWithAccuracy / 1000.0f, 0.3f))); if ((_mods & EMods::Hidden) > 0) _accValue *= 1.08f; if ((_mods & EMods::Flashlight) > 0) _accValue *= 1.02f; }
void CStringEx::PutDouble(double f, int len) { switch (_fpclass(f)) { case _FPCLASS_SNAN: case _FPCLASS_QNAN: Format("%s", m_csNAN); // "NaN" return; case _FPCLASS_NINF: Format("%s", m_csNINF);// "-Inf" return; case _FPCLASS_PINF: Format("%s", m_csPINF);// "+Inf" return; } dtoan(GetBuffer(len),f,len); ReleaseBuffer(len); // have we exceeded our acuracy? int acc = 16; if(len< acc+1) return; Accuracy(acc); }
//================================================================================================================================ //function [Accuracy, Criterion] = Mcl_Accuracy(X, Cat, Ncats, CatWeight) //-------------------------------------------------------------------------------------------------------------------------------- // Finds the accuracy and decision criterion for a 1-criterion univariate classifier. The user supplies data as X and Cat and // the category for which to compute the univariate criterion as idCat. If there are many columns of X, a separate classifier // is computed for each column. Each row of X is a data sample associated with a category label supplied by Cat. The samples // of each categories are permitted to have differential influence on the solution via the CatWeight parameter which is useful // for enforcing priors. //-------------------------------------------------------------------------------------------------------------------------------- // NOMENCLATURE //---------------------------------------------------- // nSamp (int32 vector: nCats) // The number of samples in each category. For each iCat category, nSamp(1+iCat) is equal to sum(Cat==int32(iCat)). // ntSamp (int32 scalar) // The total number of samples (in all categories). Equal to sum(nSamp) or numel(Cat). // nCols // The number of columns of X. //-------------------------------------------------------------------------------------------------------------------------------- // INPUT (values are not altered by mex function) //---------------------------------------------------- // X (double 2D array: ntSamp * nCols) // Each row of X gives a the coordinate of a sample of data. Each row is a separate sample, each column is a spatial dimension. // The univariate classifiers are applied separately to each column of X. // Cat (int32 vector: ntSamp) // The 0-based category ID. The elements of this vector must be integers from the set {0,...,Ncats-1}. // Ncats (int32 scalar) // The number of categories. // CatWeight (optional double vector: nCats) // For category iCat, the weighted accuracy is computed using weights for each category's samples, CatWeight[iCat]; Default = ones(nCats,1); //-------------------------------------------------------------------------------------------------------------------------------- // OUTPUT (values altered by mex function) //---------------------------------------------------- // Accuracy (double 2D array: Ncats * nCols) // The absolute value of Accuracy(iCat,iCol) gives the weighted accuracy for category iCat in X(:,iCol). The sign of accuracy // disambiguates the decision rule used. // Accuracy(iCat,iCol) is negative when the decision rule is: Assign iCat if X(:,iCol)<Criterion(iCat,iCol). // Accuracy(iCat,iCol) is positive when the decision rule is: Assign iCat if X(:,iCol)>Criterion(iCat,iCol). // Criterion (double 2D array: Ncats * nCols) //================================================================================================================================ void Mcl_Accuracy(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // Basic error checking of arguments doesn't take very long and helps insure against major disasters. if( nrhs<3 ) mexErrMsgTxt("Not enough input arguments."); if( nlhs==0 ) mexErrMsgTxt("Not enough output argument."); if( nlhs>2 ) mexErrMsgTxt("Too many output arguments."); //---------------------------------------------------------------------------------------------- // INPUT //---------------------------------------------------------------------------------------------- double *X = null; if( !mxIsDouble(prhs[0]) ) mexErrMsgTxt("X must be type double."); X = (double*)mxGetData(prhs[0]); int ntSamp = (int)mxGetNumberOfElements(prhs[0]); int nCols = 1; if( (int)mxGetNumberOfDimensions(prhs[0])>1 ) { ntSamp = (int)mxGetM(prhs[0]); nCols = (int)mxGetN(prhs[0]); } //---------------------------------------------------------------------------------------------- int *Cat = null; if( !mxIsInt32(prhs[1]) ) mexErrMsgTxt("Cat must be type int32."); if( (int)mxGetNumberOfElements(prhs[1]) < ntSamp ) mexErrMsgTxt("Cat must have ntSamp rows. Usually, ntSamp = size(X,1)."); Cat = (int*)mxGetData(prhs[1]); //---------------------------------------------------------------------------------------------- int Ncats = 1; if( !mxIsInt32(prhs[2]) ) mexErrMsgTxt("Ncats must be type int32."); if( mxGetNumberOfElements(prhs[2])!=1 ) mexErrMsgTxt("Ncats must be a scalar."); Ncats = ((int*)mxGetData(prhs[2]))[0]; //---------------------------------------------------------------------------------------------- double *CatWeight = null; if( nrhs>=4 ) { if( !mxIsDouble(prhs[3]) || (int)mxGetNumberOfElements(prhs[3])<Ncats ) mexErrMsgTxt("CatWeight must be a double vector of length Ncats."); CatWeight = (double*)mxGetData(prhs[3]); } //---------------------------------------------------------------------------------------------- // OUTPUT //---------------------------------------------------------------------------------------------- double* Acc = null; plhs[0] = mxCreateDoubleMatrix(Ncats,nCols,mxREAL); Acc = (double*)mxGetData(plhs[0]); //---------------------------------------------------------------------------------------------- double* Crit = null; if( nlhs>=2 ) { plhs[1] = mxCreateDoubleMatrix(Ncats,nCols,mxREAL); Crit = (double*)mxGetData(plhs[1]); } //---------------------------------------------------------------------------------------------- // STATIC //---------------------------------------------------------------------------------------------- // Register the function that must delete static memory if( nMcl_Accuracy_Idx==0 ) mexAtExit(Mcl_Accuracy_DeleteStaticMemory); // Determine whether static memory must be initialized if( nMcl_Accuracy_Idx<ntSamp ) { delete Mcl_Accuracy_Idx; nMcl_Accuracy_Idx = 2*ntSamp; Mcl_Accuracy_Idx = new int[nMcl_Accuracy_Idx]; } //---------------------------------------------------------------------------------------------- //mexPrintf("Mcl_Accuracy: [ntSamp, nCols, Ncats] = [%i, %i, %i]\n", ntSamp, nCols, Ncats); int idxCrit = 0; int iCol, iSamp, iCat, iOut; double *Xcol; // For each column of data for(iCol=0; iCol<nCols; iCol++) { // Initialize the index for(iSamp=0; iSamp<ntSamp; iSamp++) Mcl_Accuracy_Idx[iSamp] = iSamp; //mexPrintf("Mcl_Accuracy 02: [iCol] = [%i]\n", iCol); // Sort Xcol = X+iCol*ntSamp; QuickSort(Mcl_Accuracy_Idx, Xcol, 0, ntSamp-1); //mexPrintf("Mcl_Accuracy 03: [iCol] = [%i]\n", iCol); // For each category for(iCat=0; iCat<Ncats; iCat++) { // Accuracy iOut = iCat+Ncats*iCol; //mexPrintf("-------------------------------------------------------------------------\n"); //mexPrintf("Mcl_Accuracy 04: [iCol, iCat, iOut] = [%i, %i, %i]\n", iCol, iCat, iOut); //mexPrintf("-----------------\n"); Acc[iOut] = Accuracy(&idxCrit, Mcl_Accuracy_Idx, Xcol, Cat, CatWeight, ntSamp, Ncats, iCat); if( idxCrit<0 || idxCrit > ntSamp ) Acc[iOut] = -Acc[iOut]; //mexPrintf("Mcl_Accuracy 05: [iCol, iCat, iOut, Acc[iOut], idxCrit] = [%i, %i, %i, %f, %i]\n", iCol, iCat, iOut, Acc[iOut], idxCrit); // Get the crit if(Crit!=null) { if(idxCrit<-ntSamp || idxCrit>ntSamp) Crit[iOut] = Xcol[Mcl_Accuracy_Idx[ntSamp-1]]+1.0; else if(idxCrit==0 ) Crit[iOut] = Xcol[Mcl_Accuracy_Idx[0]]-1.0; else if( idxCrit>0 ) Crit[iOut] = 0.5 * (Xcol[Mcl_Accuracy_Idx[ idxCrit]] + Xcol[Mcl_Accuracy_Idx[ idxCrit-1]]); else Crit[iOut] = 0.5 * (Xcol[Mcl_Accuracy_Idx[-idxCrit]] + Xcol[Mcl_Accuracy_Idx[-idxCrit-1]]); } //mexPrintf("Mcl_Accuracy 06: [iCol, iCat, iOut, Acc[iOut], Crit[iOut]] = [%i, %i, %i, %f, %f]\n", iCol, iCat, iOut, Acc[iOut], Crit[iOut]); } } }
PP_NAMESPACE_BEGIN CatchScore::CatchScore( s64 scoreId, EGamemode mode, s64 userId, s32 beatmapId, s32 score, s32 maxCombo, s32 num300, s32 num100, s32 num50, s32 numMiss, s32 numGeki, s32 numKatu, EMods mods, const Beatmap& beatmap ) : Score{scoreId, mode, userId, beatmapId, score, maxCombo, num300, num100, num50, numMiss, numGeki, numKatu, mods} { // Don't count scores made with supposedly unranked mods if ((_mods & EMods::Relax) > 0 || (_mods & EMods::Relax2) > 0 || (_mods & EMods::Autoplay) > 0) { _value = 0; return; } // We are heavily relying on aim in catch the beat _value = pow(5.0f * std::max(1.0f, beatmap.DifficultyAttribute(_mods, Beatmap::Aim) / 0.0049f) - 4.0f, 2.0f) / 100000.0f; // Longer maps are worth more. "Longer" means how many hits there are which can contribute to combo int numTotalHits = totalComboHits(); // Longer maps are worth more f32 lengthBonus = 0.95f + 0.4f * std::min<f32>(1.0f, static_cast<f32>(numTotalHits) / 3000.0f) + (numTotalHits > 3000 ? log10(static_cast<f32>(numTotalHits) / 3000.0f) * 0.5f : 0.0f); // Longer maps are worth more _value *= lengthBonus; // Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available _value *= pow(0.97f, _numMiss); // Combo scaling float beatmapMaxCombo = beatmap.DifficultyAttribute(_mods, Beatmap::MaxCombo); if (beatmapMaxCombo > 0) _value *= std::min<f32>(pow(static_cast<f32>(_maxCombo), 0.8f) / pow(beatmapMaxCombo, 0.8f), 1.0f); f32 approachRate = beatmap.DifficultyAttribute(_mods, Beatmap::AR); f32 approachRateFactor = 1.0f; if (approachRate > 9.0f) approachRateFactor += 0.1f * (approachRate - 9.0f); // 10% for each AR above 9 else if (approachRate < 8.0f) approachRateFactor += 0.025f * (8.0f - approachRate); // 2.5% for each AR below 8 _value *= approachRateFactor; if ((_mods & EMods::Hidden) > 0) // Hiddens gives nothing on max approach rate, and more the lower it is _value *= 1.05f + 0.075f * (10.0f - std::min(10.0f, approachRate)); // 7.5% for each AR below 10 if ((_mods & EMods::Flashlight) > 0) // Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps. _value *= 1.35f * lengthBonus; // Scale the aim value with accuracy _slightly_ _value *= pow(Accuracy(), 5.5f); // Custom multipliers for NoFail and SpunOut. if ((_mods & EMods::NoFail) > 0) _value *= 0.90f; if ((_mods & EMods::SpunOut) > 0) _value *= 0.95f; }