void DTW::scaleData(LabelledTimeSeriesClassificationData &trainingData){ //Scale the data using the min and max values for(UINT i=0; i<trainingData.getNumSamples(); i++){ scaleData( trainingData[i].getData(), trainingData[i].getData() ); } }
primitiveFFTScaleData(void) { sqInt rcvr; rcvr = stackObjectValue(0); if (!(loadFFTFrom(rcvr))) { return null; } scaleData(); return 0; }
OPTparams * OPTinit(char *fname, int nap, double *salpha, int nbp, double *sbeta, int nfp, double *sfilter) { int i; OPTparams *pa = (OPTparams *) malloc(sizeof(OPTparams)); sprintf(pa->fname, "%s", fname); pa->nfft = 512; pa->samplerate = 44100.; pa->cut_freq = 8000.; pa->ntarget = floor(pa->cut_freq / pa->samplerate * pa->nfft); pa->nslices = 4; pa->dt = 1 / (pa->samplerate); double gamma = 24000; double x0 = 0, y0 = 1.; double *target_data = load_wave_file(fname, &pa->target_ns); if (pa->target_ns % pa->nfft != 0) pa->target_ns = pa->target_ns - pa->target_ns % pa->nfft + pa->nfft; realloc(target_data, pa->target_ns); scaleData(1 / getABSmax(target_data, pa->target_ns), target_data, pa->target_ns); pa->vdata = (double *) calloc(pa->target_ns, sizeof(double)); pa->tmax = pa->target_ns / pa->samplerate; pa->spectrum = get_spectrum_data(target_data, pa->target_ns, pa->nfft, pa->ntarget, pa->nslices, &pa->nchunks); pa->n = pa->nchunks * pa->nslices * pa->ntarget; double talpha[nap]; double tbeta[nbp]; for (i = 0; i < nap; i++) talpha[i] = i * pa->tmax / (nap - 1); for (i = 0; i < nbp; i++) tbeta[i] = i * pa->tmax / (nbp - 1); double myfreqs[] = {0.0, 1000.0, 2000.0, 3000.0, 4000.0, 5000.0, 6000.0, 7000.0, 8000.0, pa->samplerate / 2}; pa->ODEpa = ODEinit(nap, salpha, talpha, nbp, sbeta, tbeta, nfp, sfilter, myfreqs, gamma, x0, y0); free(target_data); return pa; }
void OPTresponse(double *p, double *x, int m, int n, void *data) { OPTparams *OPTpa = (OPTparams *) data; ODEparams *ODEpa = OPTpa->ODEpa; double *vdata = OPTpa->vdata; double *alpha = p; double *sp = OPTpa->spectrum; double *beta = p + ODEpa->nap; double *filter = p + ODEpa->nap + ODEpa->nbp; ODEupdate(ODEpa, alpha, beta, filter); ODErun(vdata, OPTpa->tmax, OPTpa->dt, ODEpa); ODEfilter(vdata, OPTpa->target_ns, OPTpa->nfft, ODEpa); scaleData(1 / getABSmax(vdata, OPTpa->target_ns), vdata, OPTpa->target_ns); ODEtarget(x, vdata, OPTpa->target_ns, OPTpa->nfft, OPTpa->ntarget, OPTpa->nslices, &OPTpa->nchunks); }
double OPTchi2(double *p, double *x, int m, int n, void *data) { static int i = 0; OPTparams *OPTpa = (OPTparams *) data; ODEparams *ODEpa = OPTpa->ODEpa; double *vdata = OPTpa->vdata; double *alpha = p; double *sp = OPTpa->spectrum; double *beta = p + ODEpa->nap; double *filter = p + ODEpa->nap + ODEpa->nbp; int k; ODEupdate(ODEpa, alpha, beta, filter); ODErun(vdata, OPTpa->tmax, OPTpa->dt, ODEpa); ODEfilter(vdata, OPTpa->target_ns, OPTpa->nfft, ODEpa); scaleData(1 / getABSmax(vdata, OPTpa->target_ns), vdata, OPTpa->target_ns); ODEtarget(x, vdata, OPTpa->target_ns, OPTpa->nfft, OPTpa->ntarget, OPTpa->nslices, &OPTpa->nchunks); return CHI2(OPTpa->spectrum, x, OPTpa->n); }
bool DTW::predict(MatrixDouble inputTimeSeries){ if( !trained ){ errorLog << "predict(Matrix<double> &inputTimeSeries) - The DTW templates have not been trained!" << endl; return false; } if( classLikelihoods.size() != numTemplates ) classLikelihoods.resize(numTemplates); if( classDistances.size() != numTemplates ) classDistances.resize(numTemplates); predictedClassLabel = 0; maxLikelihood = DEFAULT_NULL_LIKELIHOOD_VALUE; for(UINT k=0; k<classLikelihoods.size(); k++){ classLikelihoods[k] = 0; classDistances[k] = DEFAULT_NULL_LIKELIHOOD_VALUE; } if( numFeatures != inputTimeSeries.getNumCols() ){ errorLog << "predict(Matrix<double> &inputTimeSeries) - The number of features in the model (" << numFeatures << ") do not match that of the input time series (" << inputTimeSeries.getNumCols() << ")" << endl; return false; } //Perform any preprocessing if requried MatrixDouble *timeSeriesPtr = &inputTimeSeries; MatrixDouble processedTimeSeries; MatrixDouble tempMatrix; if(useScaling){ scaleData(*timeSeriesPtr,processedTimeSeries); timeSeriesPtr = &processedTimeSeries; } //Normalize the data if needed if( useZNormalisation ){ znormData(*timeSeriesPtr,processedTimeSeries); timeSeriesPtr = &processedTimeSeries; } //Smooth the data if required if( useSmoothing ){ smoothData(*timeSeriesPtr,smoothingFactor,tempMatrix); timeSeriesPtr = &tempMatrix; } //Offset the timeseries if required if( offsetUsingFirstSample ){ offsetTimeseries( *timeSeriesPtr ); } //Make the prediction by finding the closest template double sum = 0; if( distanceMatrices.size() != numTemplates ) distanceMatrices.resize( numTemplates ); if( warpPaths.size() != numTemplates ) warpPaths.resize( numTemplates ); //Test the timeSeries against all the templates in the timeSeries buffer for(UINT k=0; k<numTemplates; k++){ //Perform DTW classDistances[k] = computeDistance(templatesBuffer[k].timeSeries,*timeSeriesPtr,distanceMatrices[k],warpPaths[k]); classLikelihoods[k] = classDistances[k]; sum += classLikelihoods[k]; } //See which gave the min distance UINT closestTemplateIndex = 0; bestDistance = classDistances[0]; for(UINT k=1; k<numTemplates; k++){ if( classDistances[k] < bestDistance ){ bestDistance = classDistances[k]; closestTemplateIndex = k; } } //Normalize the class likelihoods and check which class has the maximum likelihood UINT maxLikelihoodIndex = 0; maxLikelihood = 0; for(UINT k=0; k<numTemplates; k++){ classLikelihoods[k] = (sum-classLikelihoods[k])/sum; if( classLikelihoods[k] > maxLikelihood ){ maxLikelihood = classLikelihoods[k]; maxLikelihoodIndex = k; } } if( useNullRejection ){ switch( rejectionMode ){ case TEMPLATE_THRESHOLDS: if( bestDistance <= nullRejectionThresholds[ closestTemplateIndex ] ) predictedClassLabel = templatesBuffer[ closestTemplateIndex ].classLabel; else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; break; case CLASS_LIKELIHOODS: if( maxLikelihood >= 0.99 ) predictedClassLabel = templatesBuffer[ maxLikelihoodIndex ].classLabel; else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; break; case THRESHOLDS_AND_LIKELIHOODS: if( bestDistance <= nullRejectionThresholds[ closestTemplateIndex ] && maxLikelihood >= 0.99 ) predictedClassLabel = templatesBuffer[ closestTemplateIndex ].classLabel; else predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; break; default: errorLog << "predict(Matrix<double> &timeSeries) - Unknown RejectionMode!" << endl; return false; break; } }else predictedClassLabel = templatesBuffer[ closestTemplateIndex ].classLabel; return true; }
////////////////////////// TRAINING FUNCTIONS ////////////////////////// bool DTW::train(LabelledTimeSeriesClassificationData labelledTrainingData){ UINT bestIndex = 0; //Cleanup Memory templatesBuffer.clear(); classLabels.clear(); trained = false; continuousInputDataBuffer.clear(); if( trimTrainingData ){ LabelledTimeSeriesClassificationSampleTrimmer timeSeriesTrimmer(trimThreshold,maximumTrimPercentage); LabelledTimeSeriesClassificationData tempData; tempData.setNumDimensions( labelledTrainingData.getNumDimensions() ); for(UINT i=0; i<labelledTrainingData.getNumSamples(); i++){ if( timeSeriesTrimmer.trimTimeSeries( labelledTrainingData[i] ) ){ tempData.addSample(labelledTrainingData[i].getClassLabel(), labelledTrainingData[i].getData()); }else{ trainingLog << "Removing training sample " << i << " from the dataset as it could not be trimmed!" << endl; } } //Overwrite the original training data with the trimmed dataset labelledTrainingData = tempData; } if( labelledTrainingData.getNumSamples() == 0 ){ errorLog << "_train(LabelledTimeSeriesClassificationData &labelledTrainingData) - Can't train model as there are no samples in training data!" << endl; return false; } //Assign numClasses = labelledTrainingData.getNumClasses(); numTemplates = labelledTrainingData.getNumClasses(); numFeatures = labelledTrainingData.getNumDimensions(); templatesBuffer.resize( numClasses ); classLabels.resize( numClasses ); nullRejectionThresholds.resize( numClasses ); averageTemplateLength = 0; //Need to copy the labelled training data incase we need to scale it or znorm it LabelledTimeSeriesClassificationData trainingData( labelledTrainingData ); //Perform any scaling or normalisation rangesBuffer = trainingData.getRanges(); if( useScaling ) scaleData( trainingData ); if( useZNormalisation ) znormData( trainingData ); //For each class, run a one-to-one DTW and find the template the best describes the data for(UINT k=0; k<numTemplates; k++){ //Get the class label for the cth class UINT classLabel = trainingData.getClassTracker()[k].classLabel; LabelledTimeSeriesClassificationData classData = trainingData.getClassData( classLabel ); UINT numExamples = classData.getNumSamples(); bestIndex = 0; //Set the class label of this template templatesBuffer[k].classLabel = classLabel; //Set the kth class label classLabels[k] = classLabel; trainingLog << "Training Template: " << k << " Class: " << classLabel << endl; //Check to make sure we actually have some training examples if(numExamples<1){ errorLog << "_train(LabelledTimeSeriesClassificationData &labelledTrainingData) - Can not train model: Num of Example is < 1! Class: " << classLabel << endl; return false; } if(numExamples==1){//If we have just one training example then we have to use it as the template bestIndex = 0; nullRejectionThresholds[k] = 0.0;//TODO-We need a better way of calculating this! warningLog << "_train(LabelledTimeSeriesClassificationData &labelledTrainingData) - Can't compute reject thresholds for class " << classLabel << " as there is only 1 training example" << endl; }else{ //Search for the best training example for this class if( !train_NDDTW(classData,templatesBuffer[k],bestIndex) ){ errorLog << "_train(LabelledTimeSeriesClassificationData &labelledTrainingData) - Failed to train template for class with label: " << classLabel << endl; return false; } } //Add the template with the best index to the buffer int trainingMethod = 0; if(useSmoothing) trainingMethod = 1; switch (trainingMethod) { case(0)://Standard Training templatesBuffer[k].timeSeries = classData[bestIndex].getData(); break; case(1)://Training using Smoothing //Smooth the data, reducing its size by a factor set by smoothFactor smoothData(classData[ bestIndex ].getData(),smoothingFactor,templatesBuffer[k].timeSeries); break; default: cout<<"Can not train model: Unknown training method \n"; return false; break; } if( offsetUsingFirstSample ){ offsetTimeseries( templatesBuffer[k].timeSeries ); } //Add the average length of the training examples for this template to the overall averageTemplateLength averageTemplateLength += templatesBuffer[k].averageTemplateLength; } //Flag that the models have been trained trained = true; averageTemplateLength = (UINT) averageTemplateLength/double(numTemplates); //Recompute the null rejection thresholds recomputeNullRejectionThresholds(); //Resize the prediction results to make sure it is setup for realtime prediction continuousInputDataBuffer.clear(); continuousInputDataBuffer.resize(averageTemplateLength,vector<double>(numFeatures,0)); classLikelihoods.resize(numTemplates,DEFAULT_NULL_LIKELIHOOD_VALUE); classDistances.resize(numTemplates,0); predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL; maxLikelihood = DEFAULT_NULL_LIKELIHOOD_VALUE; //Training complete return true; }
/* FFTPlugin>>#transformData: */ static sqInt transformData(sqInt forward) { sqInt fftScale; sqInt fftSize2; sqInt fftSize4; sqInt i; sqInt ii; float imagT; float imagU; sqInt ip; sqInt j; int lev; int lev1; sqInt level; float realT; float realU; sqInt theta; permuteData(); if (failed()) { /* permuteData went wrong. Do the permutation again -- this will restore the original order */ permuteData(); return null; } /* begin transformForward: */ fftSize2 = fftSize / 2; fftSize4 = fftSize / 4; for (level = 1; level <= nu; level += 1) { lev = 1L << level; lev1 = lev / 2; fftScale = fftSize / lev; for (j = 1; j <= lev1; j += 1) { /* pi * (j-1) / lev1 mapped onto 0..n/2 */ theta = (j - 1) * fftScale; if (theta < fftSize4) { /* Compute U, the complex multiplier for each level */ realU = sinTable[(sinTableSize - theta) - 1]; imagU = sinTable[theta]; } else { realU = 0.0 - (sinTable[theta - fftSize4]); imagU = sinTable[fftSize2 - theta]; } if (!forward) { imagU = 0.0 - imagU; } i = j; while (i <= fftSize) { ip = (i + lev1) - 1; ii = i - 1; realT = ((realData[ip]) * realU) - ((imagData[ip]) * imagU); imagT = ((realData[ip]) * imagU) + ((imagData[ip]) * realU); realData[ip] = ((realData[ii]) - realT); imagData[ip] = ((imagData[ii]) - imagT); realData[ii] = ((realData[ii]) + realT); imagData[ii] = ((imagData[ii]) + imagT); i += lev; } } } if (!forward) { scaleData(); } return 0; }
/* Draw one of the image arrays in a subarea of the window */ void TumblerWindow::drawSubArea(TumblerStruct *xtum, unsigned short *sdata, int llx, int urx) { float scale, offset; unsigned int i, xysize; unsigned char *data; b3dUInt16 *usdata; float tf, tmax, tmin; int xo, yo; int zoom = xtum->zoom; xysize = xtum->slice->xsize * xtum->slice->ysize; data = xtum->bwslice->data.b; usdata = xtum->bwslice->data.us; scaleData(xtum, sdata); tmax = 255.0f; tmin = 0.0f; scale = xtum->scale; offset = xtum->offset; /* DNM: scale for depth 8 only if not rgba */ if (App->depth == 8 && !App->rgba){ scale *= xtum->vi->rampsize/256.0f; tmax = xtum->vi->rampbase + xtum->vi->rampsize; tmin = xtum->vi->rampbase; for(i = 0; i < xysize; i++){ tf = ((sdata[i] + offset) * scale) + xtum->vi->rampbase; if (tf < tmin) tf = tmin; if (tf > tmax) tf = tmax; data[i] = (unsigned char)tf; } } else if (xtum->vi->ushortStore) { tmax = 65535.; scale *= 256.; for (i = 0; i < xysize; i++) { tf = (sdata[i] + offset) * scale; usdata[i] = (b3dUInt16)B3DMAX(tmin, B3DMIN(tmax, tf)); } } else { for(i = 0; i < xysize; i++){ tf = (sdata[i] + offset) * scale; data[i] = (unsigned char)B3DMAX(tmin, B3DMIN(tmax, tf)); } } if (xtum->highres) zoom = 1; /* DNM 1/20/02: add slice argument to graphics calls; make it -1 to prevent image re-use */ b3dDrawGreyScalePixelsSubArea (xtum->image, ivwMakeLinePointers(xtum->vi, data, xtum->slice->xsize, xtum->slice->ysize, xtum->vi->rawImageStore), xtum->slice->xsize, xtum->slice->ysize, 0, 0, llx, 0, urx, xtum->height, xtum->vi->rampbase, zoom, &xo, &yo, -1); }