UnlabelledClassificationData UnlabelledClassificationData::getTrainingFoldData(UINT foldIndex) {
    UnlabelledClassificationData trainingData;

    if( !crossValidationSetup ) {
        errorLog << "getTrainingFoldData(UINT foldIndex) - Cross Validation has not been setup! You need to call the spiltDataIntoKFolds(UINT K) function first before calling this function!" << endl;
        return trainingData;
    }

    if( foldIndex >= kFoldValue ) return trainingData;

    trainingData.setNumDimensions( numDimensions );

    //Add the data to the training set, this will consist of all the data that is NOT in the foldIndex
    UINT index = 0;
    for(UINT k=0; k<kFoldValue; k++) {
        if( k != foldIndex ) {
            for(UINT i=0; i<crossValidationIndexs[k].size(); i++) {

                index = crossValidationIndexs[k][i];
                trainingData.addSample( data.getRowVector(index) );
            }
        }
    }

    return trainingData;
}
UnlabelledClassificationData LabelledClassificationData::reformatAsUnlabelledClassificationData() const{

    UnlabelledClassificationData unlabelledData;

    if( totalNumSamples == 0 ){
        return unlabelledData;
    }

    unlabelledData.setNumDimensions( numDimensions );

    for(UINT i=0; i<totalNumSamples; i++){
        unlabelledData.addSample( data[i].getSample() );
    }

    return unlabelledData;
}
bool UnlabelledClassificationData::merge(UnlabelledClassificationData &unlabelledData) {

    if( unlabelledData.getNumDimensions() != numDimensions ) {
        errorLog << "merge(UnlabelledClassificationData &unlabelledData) - The number of dimensions in the unlabelledData (" << unlabelledData.getNumDimensions() << ") does not match the number of dimensions of this dataset (" << numDimensions << ")" << endl;
        return false;
    }

    //The dataset has changed so flag that any previous cross validation setup will now not work
    crossValidationSetup = false;
    crossValidationIndexs.clear();

    //Add the data from the labelledData to this instance
    for(UINT i=0; i<unlabelledData.getNumSamples(); i++) {
        addSample( unlabelledData[i] );
    }

    return true;
}
UnlabelledClassificationData LabelledTimeSeriesClassificationData::reformatAsUnlabelledClassificationData() const {

    UnlabelledClassificationData unlabelledData;

    if( totalNumSamples == 0 ){
        return unlabelledData;
    }

    unlabelledData.setNumDimensions( numDimensions );

    for(UINT i=0; i<totalNumSamples; i++){
        for(UINT x=0; x<data[i].getLength(); x++){
            unlabelledData.addSample( data[i].getData().getRowVector( x ) );
        }
    }

    return unlabelledData;
}
UnlabelledClassificationData UnlabelledClassificationData::getTestFoldData(UINT foldIndex) {
    UnlabelledClassificationData testData;

    if( !crossValidationSetup ) return testData;

    if( foldIndex >= kFoldValue ) return testData;

    //Add the data to the training
    testData.setNumDimensions( numDimensions );

    UINT index = 0;
    for(UINT i=0; i<crossValidationIndexs[ foldIndex ].size(); i++) {

        index = crossValidationIndexs[ foldIndex ][i];
        testData.addSample( data.getRowVector( index ) );
    }

    return testData;
}
bool KMeansQuantizer::train(UnlabelledClassificationData &trainingData){
	MatrixDouble data = trainingData.getDataAsMatrixDouble();
    return train( data );
}