void RegionComparer::setRegionSize(int _regionSize) { int i, j; regionSize = _regionSize; numRegions = numwins - regionSize + 1; if(numRegions <= 0) return; float normFactor = 1 / (float)regionSize; float meanpower = 0; float meanpitch = 0; for(i = 0; i < regionSize; i++){ meanpower += powers[i]; meanpitch += pitches[i]; } meanpower *= normFactor; meanpitch *= normFactor; regCentMeans.clear(); regLowPowers.clear(); regFluxMeans.clear(); regPitchies.clear(); regVariances.clear(); regCentMeans.push_back(0); regLowPowers.push_back(0); regFluxMeans.push_back(0); regPitchies.push_back(0); for(i = 0; i < regionSize; i++){ regCentMeans[0] += centroids[i]; regLowPowers[0] += powers[i] > meanpower; regFluxMeans[0] += fluxes[i]; regPitchies[0] += pitches[i] > 0; } regCentMeans[0] *= normFactor; regLowPowers[0] *= normFactor; regFluxMeans[0] *= normFactor; regPitchies[0] *= normFactor; for(i = 1; i < numRegions; i++){ regCentMeans.push_back(regCentMeans[i - 1]); regLowPowers.push_back(0); regFluxMeans.push_back(regFluxMeans[i - 1]); regPitchies.push_back(regPitchies[i - 1]); meanpower += (powers[i + regionSize - 1] - powers[i - 1]) * normFactor; meanpitch += (pitches[i + regionSize - 1] - pitches[i - 1]) * normFactor; for(j = 0; j < regionSize; j++) regLowPowers[i] += powers[i + j] > meanpower; regLowPowers[i] *= normFactor; regCentMeans[i] += (centroids[i + regionSize - 1] - centroids[i - 1]) * normFactor; regFluxMeans[i] += (fluxes[i + regionSize - 1] - fluxes[i - 1]) * normFactor; regPitchies[i] += ((pitches[i + regionSize - 1] > 0) - (pitches[i - 1] > 0)) * normFactor; std::vector< std::vector<float>* > pointFeatures; for(j = 0; j < regionSize; j++){ std::vector<float> *pointFeat = new std::vector<float>; pointFeat->push_back(centroids[i + j]); pointFeat->push_back(powers[i + j]); pointFeat->push_back(fluxes[i + j]); pointFeat->push_back(pitches[i + j]); pointFeatures.push_back(pointFeat); } std::vector<float> means; means.push_back(regCentMeans[i]); means.push_back(meanpower); means.push_back(regFluxMeans[i]); means.push_back(meanpitch); regVariances.push_back(varianceSum(means, pointFeatures)); for(j = 0; j < regionSize; j++) delete pointFeatures[j]; } }
void RegionComparer::getFeatures(Frame &inFrame, std::vector<float> &features, int _winsize) { int i; std::vector<float> localCentroids; std::vector<float> localPowers; std::vector<float> localFluxes; std::vector<float> localPitches; int numlocalwins = frameCentroids(inFrame, _winsize, localCentroids); power(inFrame, _winsize, localPowers); spectralFlux(inFrame, _winsize, localFluxes); framePitches(inFrame, _winsize, localPitches); float normFactor = 1 / (float)numlocalwins; float meanpower = 0; for(i = 0; i < numlocalwins; i++) meanpower += localPowers[i]; meanpower *= normFactor; float meanpitch = 0; features.clear(); for(i = 0; i < 4; i++) features.push_back(0); for(i = 0; i < numlocalwins; i++){ features[0] += localCentroids[i]; features[1] += localPowers[i] > meanpower; features[2] += localFluxes[i]; features[3] += localPitches[i] > 0; meanpitch += localPitches[i]; } meanpitch /= (float)numlocalwins; features[0] *= normFactor; features[1] *= normFactor; features[2] *= normFactor; features[3] *= normFactor; std::vector<float> means; std::vector< std::vector<float>* > pointFeatures; means.push_back(features[0]); means.push_back(meanpower); means.push_back(features[2]); means.push_back(meanpitch); for(i = 0; i < numlocalwins; i++){ std::vector<float> *pointFeat = new std::vector<float>; pointFeat->push_back(localCentroids[i]); pointFeat->push_back(localPowers[i]); pointFeat->push_back(localFluxes[i]); pointFeat->push_back(localPitches[i]); pointFeatures.push_back(pointFeat); } // features.push_back(0); // for(i = 0; i < numlocalwins; i++){ // float diff = (localCentroids[i] - features[0]) / (2 * features[0]); // features[4] += diff * diff; // diff = (localPowers[i] - meanpower) / (2 * meanpower); // features[4] += diff * diff; // diff = (localFluxes[i] - features[2]) / (2 * features[2]); // features[4] += diff * diff; // if(localPitches[i] > 0){ // diff = (localPitches[i] - meanpitch) / (2 * meanpitch); // features[4] += diff * diff; // } // } // features[4] /= (float)(numlocalwins * 4); // features[4] = sqrt(features[4]); features.push_back(varianceSum(means, pointFeatures)); for(i = 0; i < numlocalwins; i++) delete pointFeatures[i]; }
/** * Note that targets is 2*length, groups is length containing * groupCount unique integers from 0 to groupCount -1. groupCounts is * groupCount long and sums to length. */ double TaroneWareMeanPairwise(const std::vector<double> &targets, std::vector<unsigned int> &groups, std::vector<unsigned int> &groupCounts, const unsigned int length, const TaroneWareType twType) { unsigned int i, j, k, pairCount; int pair; double lastTime, weight; bool hasFails = false, hasCens = false; const unsigned int groupCount = groupCounts.size(); // Just guarding pairCount = 1; if (groupCounts.size() > 1) { // Division is safe because this will always be an even number pairCount = (groupCounts.size() * (groupCounts.size() - 1)) / 2; } else { return 0; } // Initialize count variables std::vector<double> fails(groupCount, 0.0); std::vector<double> cens(groupCount, 0.0); std::vector<double> expectedSum(pairCount, 0.0); std::vector<double> observedSum(pairCount, 0.0); std::vector<double> varianceSum(pairCount, 0.0); std::vector<double> atRisk(groupCount, 0.0); std::copy(groupCounts.begin(), groupCounts.begin() + groupCount, atRisk.begin()); double expected, var, totalRisk, totalFail; // Times are already ordered (at least we assume so) // Initialize lastTime to first time lastTime = targets.at(0); for (i = 0; i <= length; i++) { // If a new time is encountered, remove intermediate censored from risk if ((i == length || lastTime != targets.at(2*i)) && hasCens) { // If a new time is observed, then only censored at previous // times have been seen. We need to update riskgroups. for (j = 0; j < groupCount; j++) { atRisk.at(j) -= cens.at(j); cens.at(j) = 0; } hasCens = false; } // When we encounter a new unique time we sum up statistics for previous // or we reach the end if (i == length || (hasFails && targets.at(2*i) != lastTime)) { // All statistics for unique time i-1 done // Do group stuff, always comparing j to k since k to j is equivalent pair = -1; for (j = 0; j < groupCount; j++) { // Will skip this for last group, but rest must be done for (k = j + 1; k < groupCount; k++) { pair++; totalRisk = atRisk.at(j) + atRisk.at(k); totalFail = fails.at(j) + fails.at(k); // If total risk = 0, then none of the sums will have more terms added // If we reach the end and have only censored, then this means stop if (totalRisk > 0 && totalFail > 0) { // Weight depends on choice of statistic. switch (twType) { case TaroneWareType::GEHAN: weight = totalRisk; break; case TaroneWareType::TARONEWARE: weight = sqrt(totalRisk); break; case TaroneWareType::LOGRANK: default: weight = 1.0; break; } // Sum up all failures observed observedSum.at(pair) += weight * fails.at(j); // Expected failure count: relative group size * total failures expected = (atRisk.at(j) / totalRisk) * (totalFail); expectedSum.at(pair) += weight * expected; // Variance will also be zero if expected is zero if (expected > 0 && totalRisk > 1) { // Or we might get a NaN var = totalFail * (totalRisk - totalFail) / (totalRisk - 1) * atRisk.at(j) / totalRisk * (1 - atRisk.at(j) / totalRisk); varianceSum.at(pair) += var * pow(weight, 2); } } } // Last thing to do is to reset counts again // And update risks atRisk.at(j) -= (fails.at(j) + cens.at(j)); fails.at(j) = 0; cens.at(j) = 0; } // hasFails is group independent and so must be updated after all loops hasFails = false; hasCens = false; } // Always update statistics, but only before end if (i < length){ // Same .at(failure) time as last observed failure time, just add // to statistics But since there might be intermediate censored // time, we have to update lastTime also if (targets.at(2*i + 1)) { // Event hasFails = true; fails.at(groups.at(i)) += 1; } else { // Censored cens.at(groups.at(i)) += 1; hasCens = true; } } // Update lastTime here after all group related updates if (i < length) { lastTime = targets.at(2*i); } } // End of loop // Test statistic is now simply the mean double sum = 0; double stat; pair = -1; for (j = 0; j < groupCount; j++) { for (k = j + 1; k < groupCount; k++) { pair++; stat = pow(observedSum.at(pair) - expectedSum.at(pair), 2); stat /= varianceSum.at(pair); sum += stat; } } return sum / ((double) pairCount); }