+++ /dev/null
-/*M///////////////////////////////////////////////////////////////////////////////////////
-//
-// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-// By downloading, copying, installing or using the software you agree to this license.
-// If you do not agree to this license, do not download, install,
-// copy or use the software.
-//
-//
-// Intel License Agreement
-//
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistribution's of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// * Redistribution's in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// * The name of Intel Corporation may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
-
-#include "_ml.h"
-
-#if 0
-
-ML_IMPL int
-icvCmpIntegers (const void* a, const void* b) {return *(const int*)a - *(const int*)b;}
-
-/****************************************************************************************\
-* Cross-validation algorithms realizations *
-\****************************************************************************************/
-
-// Return pointer to trainIdx. Function DOES NOT FILL this matrix!
-ML_IMPL
-const CvMat* cvCrossValGetTrainIdxMatrix (const CvStatModel* estimateModel)
-{
- CvMat* result = NULL;
-
- CV_FUNCNAME ("cvCrossValGetTrainIdxMatrix");
- __BEGIN__
-
- if (!CV_IS_CROSSVAL(estimateModel))
- {
- CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
- }
-
- result = ((CvCrossValidationModel*)estimateModel)->sampleIdxTrain;
-
- __END__
-
- return result;
-} // End of cvCrossValGetTrainIdxMatrix
-
-/****************************************************************************************/
-// Return pointer to checkIdx. Function DOES NOT FILL this matrix!
-ML_IMPL
-const CvMat* cvCrossValGetCheckIdxMatrix (const CvStatModel* estimateModel)
-{
- CvMat* result = NULL;
-
- CV_FUNCNAME ("cvCrossValGetCheckIdxMatrix");
- __BEGIN__
-
- if (!CV_IS_CROSSVAL (estimateModel))
- {
- CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
- }
-
- result = ((CvCrossValidationModel*)estimateModel)->sampleIdxEval;
-
- __END__
-
- return result;
-} // End of cvCrossValGetCheckIdxMatrix
-
-/****************************************************************************************/
-// Create new Idx-matrix for next classifiers training and return code of result.
-// Result is 0 if function can't make next step (error input or folds are finished),
-// it is 1 if all was correct, and it is 2 if current fold wasn't' checked.
-ML_IMPL
-int cvCrossValNextStep (CvStatModel* estimateModel)
-{
- int result = 0;
-
- CV_FUNCNAME ("cvCrossValGetNextTrainIdx");
- __BEGIN__
-
- CvCrossValidationModel* crVal = (CvCrossValidationModel*) estimateModel;
- int k, fold;
-
- if (!CV_IS_CROSSVAL (estimateModel))
- {
- CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
- }
-
- fold = ++crVal->current_fold;
-
- if (fold >= crVal->folds_all)
- {
- if (fold == crVal->folds_all)
- EXIT;
- else
- {
- CV_ERROR (CV_StsInternal, "All iterations has end long ago");
- }
- }
-
- k = crVal->folds[fold + 1] - crVal->folds[fold];
- crVal->sampleIdxTrain->data.i = crVal->sampleIdxAll + crVal->folds[fold + 1];
- crVal->sampleIdxTrain->cols = crVal->samples_all - k;
- crVal->sampleIdxEval->data.i = crVal->sampleIdxAll + crVal->folds[fold];
- crVal->sampleIdxEval->cols = k;
-
- if (crVal->is_checked)
- {
- crVal->is_checked = 0;
- result = 1;
- }
- else
- {
- result = 2;
- }
-
- __END__
-
- return result;
-}
-
-/****************************************************************************************/
-// Do checking part of loop of cross-validations metod.
-ML_IMPL
-void cvCrossValCheckClassifier (CvStatModel* estimateModel,
- const CvStatModel* model,
- const CvMat* trainData,
- int sample_t_flag,
- const CvMat* trainClasses)
-{
- CV_FUNCNAME ("cvCrossValCheckClassifier ");
- __BEGIN__
-
- CvCrossValidationModel* crVal = (CvCrossValidationModel*) estimateModel;
- int i, j, k;
- int* data;
- float* responses_fl;
- int step;
- float* responses_result;
- int* responses_i;
- double te, te1;
- double sum_c, sum_p, sum_pp, sum_cp, sum_cc, sq_err;
-
-// Check input data to correct values.
- if (!CV_IS_CROSSVAL (estimateModel))
- {
- CV_ERROR (CV_StsBadArg,"First parameter point to not CvCrossValidationModel");
- }
- if (!CV_IS_STAT_MODEL (model))
- {
- CV_ERROR (CV_StsBadArg, "Second parameter point to not CvStatModel");
- }
- if (!CV_IS_MAT (trainData))
- {
- CV_ERROR (CV_StsBadArg, "Third parameter point to not CvMat");
- }
- if (!CV_IS_MAT (trainClasses))
- {
- CV_ERROR (CV_StsBadArg, "Fifth parameter point to not CvMat");
- }
- if (crVal->is_checked)
- {
- CV_ERROR (CV_StsInternal, "This iterations already was checked");
- }
-
-// Initialize.
- k = crVal->sampleIdxEval->cols;
- data = crVal->sampleIdxEval->data.i;
-
-// Eval tested feature vectors.
- CV_CALL (cvStatModelMultiPredict (model, trainData, sample_t_flag,
- crVal->predict_results, NULL, crVal->sampleIdxEval));
-// Count number if correct results.
- responses_result = crVal->predict_results->data.fl;
- if (crVal->is_regression)
- {
- sum_c = sum_p = sum_pp = sum_cp = sum_cc = sq_err = 0;
- if (CV_MAT_TYPE (trainClasses->type) == CV_32FC1)
- {
- responses_fl = trainClasses->data.fl;
- step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(float);
- for (i = 0; i < k; i++)
- {
- te = responses_result[*data];
- te1 = responses_fl[*data * step];
- sum_c += te1;
- sum_p += te;
- sum_cc += te1 * te1;
- sum_pp += te * te;
- sum_cp += te1 * te;
- te -= te1;
- sq_err += te * te;
-
- data++;
- }
- }
- else
- {
- responses_i = trainClasses->data.i;
- step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(int);
- for (i = 0; i < k; i++)
- {
- te = responses_result[*data];
- te1 = responses_i[*data * step];
- sum_c += te1;
- sum_p += te;
- sum_cc += te1 * te1;
- sum_pp += te * te;
- sum_cp += te1 * te;
- te -= te1;
- sq_err += te * te;
-
- data++;
- }
- }
- // Fixing new internal values of accuracy.
- crVal->sum_correct += sum_c;
- crVal->sum_predict += sum_p;
- crVal->sum_cc += sum_cc;
- crVal->sum_pp += sum_pp;
- crVal->sum_cp += sum_cp;
- crVal->sq_error += sq_err;
- }
- else
- {
- if (CV_MAT_TYPE (trainClasses->type) == CV_32FC1)
- {
- responses_fl = trainClasses->data.fl;
- step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(float);
- for (i = 0, j = 0; i < k; i++)
- {
- if (cvRound (responses_result[*data]) == cvRound (responses_fl[*data * step]))
- j++;
- data++;
- }
- }
- else
- {
- responses_i = trainClasses->data.i;
- step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(int);
- for (i = 0, j = 0; i < k; i++)
- {
- if (cvRound (responses_result[*data]) == responses_i[*data * step])
- j++;
- data++;
- }
- }
- // Fixing new internal values of accuracy.
- crVal->correct_results += j;
- }
-// Fixing that this fold already checked.
- crVal->all_results += k;
- crVal->is_checked = 1;
-
- __END__
-} // End of cvCrossValCheckClassifier
-
-/****************************************************************************************/
-// Return current accuracy.
-ML_IMPL
-float cvCrossValGetResult (const CvStatModel* estimateModel,
- float* correlation)
-{
- float result = 0;
-
- CV_FUNCNAME ("cvCrossValGetResult");
- __BEGIN__
-
- double te, te1;
- CvCrossValidationModel* crVal = (CvCrossValidationModel*)estimateModel;
-
- if (!CV_IS_CROSSVAL (estimateModel))
- {
- CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
- }
-
- if (crVal->all_results)
- {
- if (crVal->is_regression)
- {
- result = ((float)crVal->sq_error) / crVal->all_results;
- if (correlation)
- {
- te = crVal->all_results * crVal->sum_cp -
- crVal->sum_correct * crVal->sum_predict;
- te *= te;
- te1 = (crVal->all_results * crVal->sum_cc -
- crVal->sum_correct * crVal->sum_correct) *
- (crVal->all_results * crVal->sum_pp -
- crVal->sum_predict * crVal->sum_predict);
- *correlation = (float)(te / te1);
-
- }
- }
- else
- {
- result = ((float)crVal->correct_results) / crVal->all_results;
- }
- }
-
- __END__
-
- return result;
-}
-
-/****************************************************************************************/
-// Reset cross-validation EstimateModel to state the same as it was immidiatly after
-// its creating.
-ML_IMPL
-void cvCrossValReset (CvStatModel* estimateModel)
-{
- CV_FUNCNAME ("cvCrossValReset");
- __BEGIN__
-
- CvCrossValidationModel* crVal = (CvCrossValidationModel*)estimateModel;
-
- if (!CV_IS_CROSSVAL (estimateModel))
- {
- CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
- }
-
- crVal->current_fold = -1;
- crVal->is_checked = 1;
- crVal->all_results = 0;
- crVal->correct_results = 0;
- crVal->sq_error = 0;
- crVal->sum_correct = 0;
- crVal->sum_predict = 0;
- crVal->sum_cc = 0;
- crVal->sum_pp = 0;
- crVal->sum_cp = 0;
-
- __END__
-}
-
-/****************************************************************************************/
-// This function is standart CvStatModel field to release cross-validation EstimateModel.
-ML_IMPL
-void cvReleaseCrossValidationModel (CvStatModel** model)
-{
- CvCrossValidationModel* pModel;
-
- CV_FUNCNAME ("cvReleaseCrossValidationModel");
- __BEGIN__
-
- if (!model)
- {
- CV_ERROR (CV_StsNullPtr, "");
- }
-
- pModel = (CvCrossValidationModel*)*model;
- if (!pModel)
- {
- return;
- }
- if (!CV_IS_CROSSVAL (pModel))
- {
- CV_ERROR (CV_StsBadArg, "");
- }
-
- cvFree (&pModel->sampleIdxAll);
- cvFree (&pModel->folds);
- cvReleaseMat (&pModel->sampleIdxEval);
- cvReleaseMat (&pModel->sampleIdxTrain);
- cvReleaseMat (&pModel->predict_results);
-
- cvFree (model);
-
- __END__
-} // End of cvReleaseCrossValidationModel.
-
-/****************************************************************************************/
-// This function create cross-validation EstimateModel.
-ML_IMPL CvStatModel*
-cvCreateCrossValidationEstimateModel(
- int samples_all,
- const CvStatModelParams* estimateParams,
- const CvMat* sampleIdx)
-{
- CvStatModel* model = NULL;
- CvCrossValidationModel* crVal = NULL;
-
- CV_FUNCNAME ("cvCreateCrossValidationEstimateModel");
- __BEGIN__
-
- int k_fold = 10;
-
- int i, j, k, s_len;
- int samples_selected;
- CvRNG rng;
- CvRNG* prng;
- int* res_s_data;
- int* te_s_data;
- int* folds;
-
- rng = cvRNG(cvGetTickCount());
- cvRandInt (&rng); cvRandInt (&rng); cvRandInt (&rng); cvRandInt (&rng);
-// Check input parameters.
- if (estimateParams)
- k_fold = ((CvCrossValidationParams*)estimateParams)->k_fold;
- if (!k_fold)
- {
- CV_ERROR (CV_StsBadArg, "Error in parameters of cross-validation (k_fold == 0)!");
- }
- if (samples_all <= 0)
- {
- CV_ERROR (CV_StsBadArg, "<samples_all> should be positive!");
- }
-
-// Alloc memory and fill standart StatModel's fields.
- CV_CALL (crVal = (CvCrossValidationModel*)cvCreateStatModel (
- CV_STAT_MODEL_MAGIC_VAL | CV_CROSSVAL_MAGIC_VAL,
- sizeof(CvCrossValidationModel),
- cvReleaseCrossValidationModel,
- NULL, NULL));
- crVal->current_fold = -1;
- crVal->folds_all = k_fold;
- if (estimateParams && ((CvCrossValidationParams*)estimateParams)->is_regression)
- crVal->is_regression = 1;
- else
- crVal->is_regression = 0;
- if (estimateParams && ((CvCrossValidationParams*)estimateParams)->rng)
- prng = ((CvCrossValidationParams*)estimateParams)->rng;
- else
- prng = &rng;
-
- // Check and preprocess sample indices.
- if (sampleIdx)
- {
- int s_step;
- int s_type = 0;
-
- if (!CV_IS_MAT (sampleIdx))
- CV_ERROR (CV_StsBadArg, "Invalid sampleIdx array");
-
- if (sampleIdx->rows != 1 && sampleIdx->cols != 1)
- CV_ERROR (CV_StsBadSize, "sampleIdx array must be 1-dimensional");
-
- s_len = sampleIdx->rows + sampleIdx->cols - 1;
- s_step = sampleIdx->rows == 1 ?
- 1 : sampleIdx->step / CV_ELEM_SIZE(sampleIdx->type);
-
- s_type = CV_MAT_TYPE (sampleIdx->type);
-
- switch (s_type)
- {
- case CV_8UC1:
- case CV_8SC1:
- {
- uchar* s_data = sampleIdx->data.ptr;
-
- // sampleIdx is array of 1's and 0's -
- // i.e. it is a mask of the selected samples
- if( s_len != samples_all )
- CV_ERROR (CV_StsUnmatchedSizes,
- "Sample mask should contain as many elements as the total number of samples");
-
- samples_selected = 0;
- for (i = 0; i < s_len; i++)
- samples_selected += s_data[i * s_step] != 0;
-
- if (samples_selected == 0)
- CV_ERROR (CV_StsOutOfRange, "No samples is selected!");
- }
- s_len = samples_selected;
- break;
- case CV_32SC1:
- if (s_len > samples_all)
- CV_ERROR (CV_StsOutOfRange,
- "sampleIdx array may not contain more elements than the total number of samples");
- samples_selected = s_len;
- break;
- default:
- CV_ERROR (CV_StsUnsupportedFormat, "Unsupported sampleIdx array data type "
- "(it should be 8uC1, 8sC1 or 32sC1)");
- }
-
- // Alloc additional memory for internal Idx and fill it.
-/*!!*/ CV_CALL (res_s_data = crVal->sampleIdxAll =
- (int*)cvAlloc (2 * s_len * sizeof(int)));
-
- if (s_type < CV_32SC1)
- {
- uchar* s_data = sampleIdx->data.ptr;
- for (i = 0; i < s_len; i++)
- if (s_data[i * s_step])
- {
- *res_s_data++ = i;
- }
- res_s_data = crVal->sampleIdxAll;
- }
- else
- {
- int* s_data = sampleIdx->data.i;
- int out_of_order = 0;
-
- for (i = 0; i < s_len; i++)
- {
- res_s_data[i] = s_data[i * s_step];
- if (i > 0 && res_s_data[i] < res_s_data[i - 1])
- out_of_order = 1;
- }
-
- if (out_of_order)
- qsort (res_s_data, s_len, sizeof(res_s_data[0]), icvCmpIntegers);
-
- if (res_s_data[0] < 0 ||
- res_s_data[s_len - 1] >= samples_all)
- CV_ERROR (CV_StsBadArg, "There are out-of-range sample indices");
- for (i = 1; i < s_len; i++)
- if (res_s_data[i] <= res_s_data[i - 1])
- CV_ERROR (CV_StsBadArg, "There are duplicated");
- }
- }
- else // if (sampleIdx)
- {
- // Alloc additional memory for internal Idx and fill it.
- s_len = samples_all;
- CV_CALL (res_s_data = crVal->sampleIdxAll = (int*)cvAlloc (2 * s_len * sizeof(int)));
- for (i = 0; i < s_len; i++)
- {
- *res_s_data++ = i;
- }
- res_s_data = crVal->sampleIdxAll;
- } // if (sampleIdx) ... else
-
-// Resort internal Idx.
- te_s_data = res_s_data + s_len;
- for (i = s_len; i > 1; i--)
- {
- j = cvRandInt (prng) % i;
- k = *(--te_s_data);
- *te_s_data = res_s_data[j];
- res_s_data[j] = k;
- }
-
-// Duplicate resorted internal Idx.
-// It will be used to simplify operation of getting trainIdx.
- te_s_data = res_s_data + s_len;
- for (i = 0; i < s_len; i++)
- {
- *te_s_data++ = *res_s_data++;
- }
-
-// Cut sampleIdxAll to parts.
- if (k_fold > 0)
- {
- if (k_fold > s_len)
- {
- CV_ERROR (CV_StsBadArg,
- "Error in parameters of cross-validation ('k_fold' > #samples)!");
- }
- folds = crVal->folds = (int*) cvAlloc ((k_fold + 1) * sizeof (int));
- *folds++ = 0;
- for (i = 1; i < k_fold; i++)
- {
- *folds++ = cvRound (i * s_len * 1. / k_fold);
- }
- *folds = s_len;
- folds = crVal->folds;
-
- crVal->max_fold_size = (s_len - 1) / k_fold + 1;
- }
- else
- {
- k = -k_fold;
- crVal->max_fold_size = k;
- if (k >= s_len)
- {
- CV_ERROR (CV_StsBadArg,
- "Error in parameters of cross-validation (-'k_fold' > #samples)!");
- }
- crVal->folds_all = k = (s_len - 1) / k + 1;
-
- folds = crVal->folds = (int*) cvAlloc ((k + 1) * sizeof (int));
- for (i = 0; i < k; i++)
- {
- *folds++ = -i * k_fold;
- }
- *folds = s_len;
- folds = crVal->folds;
- }
-
-// Prepare other internal fields to working.
- CV_CALL (crVal->predict_results = cvCreateMat (1, samples_all, CV_32FC1));
- CV_CALL (crVal->sampleIdxEval = cvCreateMatHeader (1, 1, CV_32SC1));
- CV_CALL (crVal->sampleIdxTrain = cvCreateMatHeader (1, 1, CV_32SC1));
- crVal->sampleIdxEval->cols = 0;
- crVal->sampleIdxTrain->cols = 0;
- crVal->samples_all = s_len;
- crVal->is_checked = 1;
-
- crVal->getTrainIdxMat = cvCrossValGetTrainIdxMatrix;
- crVal->getCheckIdxMat = cvCrossValGetCheckIdxMatrix;
- crVal->nextStep = cvCrossValNextStep;
- crVal->check = cvCrossValCheckClassifier;
- crVal->getResult = cvCrossValGetResult;
- crVal->reset = cvCrossValReset;
-
- model = (CvStatModel*)crVal;
-
- __END__
-
- if (!model)
- {
- cvReleaseCrossValidationModel ((CvStatModel**)&crVal);
- }
-
- return model;
-} // End of cvCreateCrossValidationEstimateModel
-
-
-/****************************************************************************************\
-* Extended interface with backcalls for models *
-\****************************************************************************************/
-ML_IMPL float
-cvCrossValidation (const CvMat* trueData,
- int tflag,
- const CvMat* trueClasses,
- CvStatModel* (*createClassifier) (const CvMat*,
- int,
- const CvMat*,
- const CvClassifierTrainParams*,
- const CvMat*,
- const CvMat*,
- const CvMat*,
- const CvMat*),
- const CvClassifierTrainParams* estimateParams,
- const CvClassifierTrainParams* trainParams,
- const CvMat* compIdx,
- const CvMat* sampleIdx,
- CvStatModel** pCrValModel,
- const CvMat* typeMask,
- const CvMat* missedMeasurementMask)
-{
- CvCrossValidationModel* crVal = NULL;
- float result = 0;
- CvStatModel* pClassifier = NULL;
-
- CV_FUNCNAME ("cvCrossValidation");
- __BEGIN__
-
- const CvMat* trainDataIdx;
- int samples_all;
-
-// checking input data
- if ((createClassifier) == NULL)
- {
- CV_ERROR (CV_StsNullPtr, "Null pointer to functiion which create classifier");
- }
- if (pCrValModel && *pCrValModel && !CV_IS_CROSSVAL(*pCrValModel))
- {
- CV_ERROR (CV_StsBadArg,
- "<pCrValModel> point to not cross-validation model");
- }
-
-// initialization
- if (pCrValModel && *pCrValModel)
- {
- crVal = (CvCrossValidationModel*)*pCrValModel;
- crVal->reset ((CvStatModel*)crVal);
- }
- else
- {
- samples_all = ((tflag) ? trueData->rows : trueData->cols);
- CV_CALL (crVal = (CvCrossValidationModel*)
- cvCreateCrossValidationEstimateModel (samples_all, estimateParams, sampleIdx));
- }
-
- CV_CALL (trainDataIdx = crVal->getTrainIdxMat ((CvStatModel*)crVal));
-
-// operation loop
- for (; crVal->nextStep((CvStatModel*)crVal) != 0; )
- {
- CV_CALL (pClassifier = createClassifier (trueData, tflag, trueClasses,
- trainParams, compIdx, trainDataIdx, typeMask, missedMeasurementMask));
- CV_CALL (crVal->check ((CvStatModel*)crVal, pClassifier,
- trueData, tflag, trueClasses));
-
- pClassifier->release (&pClassifier);
- }
-
-// Get result and fill output field.
- CV_CALL (result = crVal->getResult ((CvStatModel*)crVal, 0));
-
- if (pCrValModel && !*pCrValModel)
- *pCrValModel = (CvStatModel*)crVal;
-
- __END__
-
-// Free all memory that should be freed.
- if (pClassifier)
- pClassifier->release (&pClassifier);
- if (crVal && (!pCrValModel || !*pCrValModel))
- crVal->release ((CvStatModel**)&crVal);
-
- return result;
-} // End of cvCrossValidation
-
-#endif
-
-/* End of file */