• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*M///////////////////////////////////////////////////////////////////////////////////////
2  //
3  //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4  //
5  //  By downloading, copying, installing or using the software you agree to this license.
6  //  If you do not agree to this license, do not download, install,
7  //  copy or use the software.
8  //
9  //
10  //                        Intel License Agreement
11  //
12  // Copyright (C) 2000, Intel Corporation, all rights reserved.
13  // Third party copyrights are property of their respective owners.
14  //
15  // Redistribution and use in source and binary forms, with or without modification,
16  // are permitted provided that the following conditions are met:
17  //
18  //   * Redistribution's of source code must retain the above copyright notice,
19  //     this list of conditions and the following disclaimer.
20  //
21  //   * Redistribution's in binary form must reproduce the above copyright notice,
22  //     this list of conditions and the following disclaimer in the documentation
23  //     and/or other materials provided with the distribution.
24  //
25  //   * The name of Intel Corporation may not be used to endorse or promote products
26  //     derived from this software without specific prior written permission.
27  //
28  // This software is provided by the copyright holders and contributors "as is" and
29  // any express or implied warranties, including, but not limited to, the implied
30  // warranties of merchantability and fitness for a particular purpose are disclaimed.
31  // In no event shall the Intel Corporation or contributors be liable for any direct,
32  // indirect, incidental, special, exemplary, or consequential damages
33  // (including, but not limited to, procurement of substitute goods or services;
34  // loss of use, data, or profits; or business interruption) however caused
35  // and on any theory of liability, whether in contract, strict liability,
36  // or tort (including negligence or otherwise) arising in any way out of
37  // the use of this software, even if advised of the possibility of such damage.
38  //
39  //M*/
40  
41  #include "_ml.h"
42  
43  #if 0
44  
45  ML_IMPL int
46  icvCmpIntegers (const void* a, const void* b) {return *(const int*)a - *(const int*)b;}
47  
48  /****************************************************************************************\
49  *                    Cross-validation algorithms realizations                            *
50  \****************************************************************************************/
51  
52  // Return pointer to trainIdx. Function DOES NOT FILL this matrix!
53  ML_IMPL
54  const CvMat* cvCrossValGetTrainIdxMatrix (const CvStatModel* estimateModel)
55  {
56      CvMat* result = NULL;
57  
58          CV_FUNCNAME ("cvCrossValGetTrainIdxMatrix");
59          __BEGIN__
60  
61      if (!CV_IS_CROSSVAL(estimateModel))
62      {
63          CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
64      }
65  
66      result = ((CvCrossValidationModel*)estimateModel)->sampleIdxTrain;
67  
68          __END__
69  
70      return result;
71  } // End of cvCrossValGetTrainIdxMatrix
72  
73  /****************************************************************************************/
74  // Return pointer to checkIdx. Function DOES NOT FILL this matrix!
75  ML_IMPL
76  const CvMat* cvCrossValGetCheckIdxMatrix (const CvStatModel* estimateModel)
77  {
78      CvMat* result = NULL;
79  
80          CV_FUNCNAME ("cvCrossValGetCheckIdxMatrix");
81          __BEGIN__
82  
83      if (!CV_IS_CROSSVAL (estimateModel))
84      {
85          CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
86      }
87  
88      result = ((CvCrossValidationModel*)estimateModel)->sampleIdxEval;
89  
90          __END__
91  
92      return result;
93  } // End of cvCrossValGetCheckIdxMatrix
94  
95  /****************************************************************************************/
96  // Create new Idx-matrix for next classifiers training and return code of result.
97  //   Result is 0 if function can't make next step (error input or folds are finished),
98  //   it is 1 if all was correct, and it is 2 if current fold wasn't' checked.
99  ML_IMPL
100  int cvCrossValNextStep (CvStatModel* estimateModel)
101  {
102      int result = 0;
103  
104          CV_FUNCNAME ("cvCrossValGetNextTrainIdx");
105          __BEGIN__
106  
107      CvCrossValidationModel* crVal = (CvCrossValidationModel*) estimateModel;
108      int k, fold;
109  
110      if (!CV_IS_CROSSVAL (estimateModel))
111      {
112          CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
113      }
114  
115      fold = ++crVal->current_fold;
116  
117      if (fold >= crVal->folds_all)
118      {
119          if (fold == crVal->folds_all)
120              EXIT;
121          else
122          {
123              CV_ERROR (CV_StsInternal, "All iterations has end long ago");
124          }
125      }
126  
127      k = crVal->folds[fold + 1] - crVal->folds[fold];
128      crVal->sampleIdxTrain->data.i = crVal->sampleIdxAll + crVal->folds[fold + 1];
129      crVal->sampleIdxTrain->cols = crVal->samples_all - k;
130      crVal->sampleIdxEval->data.i = crVal->sampleIdxAll + crVal->folds[fold];
131      crVal->sampleIdxEval->cols = k;
132  
133      if (crVal->is_checked)
134      {
135          crVal->is_checked = 0;
136          result = 1;
137      }
138      else
139      {
140          result = 2;
141      }
142  
143          __END__
144  
145      return result;
146  }
147  
148  /****************************************************************************************/
149  // Do checking part of loop  of cross-validations metod.
150  ML_IMPL
151  void cvCrossValCheckClassifier (CvStatModel*  estimateModel,
152                            const CvStatModel*  model,
153                            const CvMat*        trainData,
154                                  int           sample_t_flag,
155                            const CvMat*        trainClasses)
156  {
157          CV_FUNCNAME ("cvCrossValCheckClassifier ");
158          __BEGIN__
159  
160      CvCrossValidationModel* crVal = (CvCrossValidationModel*) estimateModel;
161      int  i, j, k;
162      int* data;
163      float* responses_fl;
164      int    step;
165      float* responses_result;
166      int* responses_i;
167      double te, te1;
168      double sum_c, sum_p, sum_pp, sum_cp, sum_cc, sq_err;
169  
170  // Check input data to correct values.
171      if (!CV_IS_CROSSVAL (estimateModel))
172      {
173          CV_ERROR (CV_StsBadArg,"First parameter point to not CvCrossValidationModel");
174      }
175      if (!CV_IS_STAT_MODEL (model))
176      {
177          CV_ERROR (CV_StsBadArg, "Second parameter point to not CvStatModel");
178      }
179      if (!CV_IS_MAT (trainData))
180      {
181          CV_ERROR (CV_StsBadArg, "Third parameter point to not CvMat");
182      }
183      if (!CV_IS_MAT (trainClasses))
184      {
185          CV_ERROR (CV_StsBadArg, "Fifth parameter point to not CvMat");
186      }
187      if (crVal->is_checked)
188      {
189          CV_ERROR (CV_StsInternal, "This iterations already was checked");
190      }
191  
192  // Initialize.
193      k = crVal->sampleIdxEval->cols;
194      data = crVal->sampleIdxEval->data.i;
195  
196  // Eval tested feature vectors.
197      CV_CALL (cvStatModelMultiPredict (model, trainData, sample_t_flag,
198                                           crVal->predict_results, NULL, crVal->sampleIdxEval));
199  // Count number if correct results.
200      responses_result = crVal->predict_results->data.fl;
201      if (crVal->is_regression)
202      {
203          sum_c = sum_p = sum_pp = sum_cp = sum_cc = sq_err = 0;
204          if (CV_MAT_TYPE (trainClasses->type) == CV_32FC1)
205          {
206              responses_fl = trainClasses->data.fl;
207              step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(float);
208              for (i = 0; i < k; i++)
209              {
210                  te = responses_result[*data];
211                  te1 = responses_fl[*data * step];
212                  sum_c += te1;
213                  sum_p += te;
214                  sum_cc += te1 * te1;
215                  sum_pp += te * te;
216                  sum_cp += te1 * te;
217                  te -= te1;
218                  sq_err += te  * te;
219  
220                  data++;
221              }
222          }
223          else
224          {
225              responses_i = trainClasses->data.i;
226              step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(int);
227              for (i = 0; i < k; i++)
228              {
229                  te = responses_result[*data];
230                  te1 = responses_i[*data * step];
231                  sum_c += te1;
232                  sum_p += te;
233                  sum_cc += te1 * te1;
234                  sum_pp += te * te;
235                  sum_cp += te1 * te;
236                  te -= te1;
237                  sq_err += te  * te;
238  
239                  data++;
240              }
241          }
242      // Fixing new internal values of accuracy.
243          crVal->sum_correct += sum_c;
244          crVal->sum_predict += sum_p;
245          crVal->sum_cc += sum_cc;
246          crVal->sum_pp += sum_pp;
247          crVal->sum_cp += sum_cp;
248          crVal->sq_error += sq_err;
249      }
250      else
251      {
252          if (CV_MAT_TYPE (trainClasses->type) == CV_32FC1)
253          {
254              responses_fl = trainClasses->data.fl;
255              step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(float);
256              for (i = 0, j = 0; i < k; i++)
257              {
258                  if (cvRound (responses_result[*data]) == cvRound (responses_fl[*data * step]))
259                      j++;
260                  data++;
261              }
262          }
263          else
264          {
265              responses_i = trainClasses->data.i;
266              step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(int);
267              for (i = 0, j = 0; i < k; i++)
268              {
269                  if (cvRound (responses_result[*data]) == responses_i[*data * step])
270                      j++;
271                  data++;
272              }
273          }
274      // Fixing new internal values of accuracy.
275          crVal->correct_results += j;
276      }
277  // Fixing that this fold already checked.
278      crVal->all_results += k;
279      crVal->is_checked = 1;
280  
281          __END__
282  } // End of cvCrossValCheckClassifier
283  
284  /****************************************************************************************/
285  // Return current accuracy.
286  ML_IMPL
287  float cvCrossValGetResult (const CvStatModel* estimateModel,
288                                   float*       correlation)
289  {
290      float result = 0;
291  
292          CV_FUNCNAME ("cvCrossValGetResult");
293          __BEGIN__
294  
295      double te, te1;
296      CvCrossValidationModel* crVal = (CvCrossValidationModel*)estimateModel;
297  
298      if (!CV_IS_CROSSVAL (estimateModel))
299      {
300          CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
301      }
302  
303      if (crVal->all_results)
304      {
305          if (crVal->is_regression)
306          {
307              result = ((float)crVal->sq_error) / crVal->all_results;
308              if (correlation)
309              {
310                  te = crVal->all_results * crVal->sum_cp -
311                                               crVal->sum_correct * crVal->sum_predict;
312                  te *= te;
313                  te1 = (crVal->all_results * crVal->sum_cc -
314                                      crVal->sum_correct * crVal->sum_correct) *
315                             (crVal->all_results * crVal->sum_pp -
316                                      crVal->sum_predict * crVal->sum_predict);
317                  *correlation = (float)(te / te1);
318  
319              }
320          }
321          else
322          {
323              result = ((float)crVal->correct_results) / crVal->all_results;
324          }
325      }
326  
327          __END__
328  
329      return result;
330  }
331  
332  /****************************************************************************************/
333  // Reset cross-validation EstimateModel to state the same as it was immidiatly after
334  //   its creating.
335  ML_IMPL
336  void cvCrossValReset (CvStatModel* estimateModel)
337  {
338          CV_FUNCNAME ("cvCrossValReset");
339          __BEGIN__
340  
341      CvCrossValidationModel* crVal = (CvCrossValidationModel*)estimateModel;
342  
343      if (!CV_IS_CROSSVAL (estimateModel))
344      {
345          CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel");
346      }
347  
348      crVal->current_fold = -1;
349      crVal->is_checked = 1;
350      crVal->all_results = 0;
351      crVal->correct_results = 0;
352      crVal->sq_error = 0;
353      crVal->sum_correct = 0;
354      crVal->sum_predict = 0;
355      crVal->sum_cc = 0;
356      crVal->sum_pp = 0;
357      crVal->sum_cp = 0;
358  
359          __END__
360  }
361  
362  /****************************************************************************************/
363  // This function is standart CvStatModel field to release cross-validation EstimateModel.
364  ML_IMPL
365  void cvReleaseCrossValidationModel (CvStatModel** model)
366  {
367      CvCrossValidationModel* pModel;
368  
369          CV_FUNCNAME ("cvReleaseCrossValidationModel");
370          __BEGIN__
371  
372      if (!model)
373      {
374          CV_ERROR (CV_StsNullPtr, "");
375      }
376  
377      pModel = (CvCrossValidationModel*)*model;
378      if (!pModel)
379      {
380          return;
381      }
382      if (!CV_IS_CROSSVAL (pModel))
383      {
384          CV_ERROR (CV_StsBadArg, "");
385      }
386  
387      cvFree (&pModel->sampleIdxAll);
388      cvFree (&pModel->folds);
389      cvReleaseMat (&pModel->sampleIdxEval);
390      cvReleaseMat (&pModel->sampleIdxTrain);
391      cvReleaseMat (&pModel->predict_results);
392  
393      cvFree (model);
394  
395          __END__
396  } // End of cvReleaseCrossValidationModel.
397  
398  /****************************************************************************************/
399  // This function create cross-validation EstimateModel.
400  ML_IMPL CvStatModel*
401  cvCreateCrossValidationEstimateModel(
402               int                samples_all,
403         const CvStatModelParams* estimateParams,
404         const CvMat*             sampleIdx)
405  {
406      CvStatModel*            model   = NULL;
407      CvCrossValidationModel* crVal   = NULL;
408  
409          CV_FUNCNAME ("cvCreateCrossValidationEstimateModel");
410          __BEGIN__
411  
412      int  k_fold = 10;
413  
414      int  i, j, k, s_len;
415      int  samples_selected;
416      CvRNG rng;
417      CvRNG* prng;
418      int* res_s_data;
419      int* te_s_data;
420      int* folds;
421  
422      rng = cvRNG(cvGetTickCount());
423      cvRandInt (&rng); cvRandInt (&rng); cvRandInt (&rng); cvRandInt (&rng);
424  // Check input parameters.
425      if (estimateParams)
426          k_fold = ((CvCrossValidationParams*)estimateParams)->k_fold;
427      if (!k_fold)
428      {
429          CV_ERROR (CV_StsBadArg, "Error in parameters of cross-validation (k_fold == 0)!");
430      }
431      if (samples_all <= 0)
432      {
433          CV_ERROR (CV_StsBadArg, "<samples_all> should be positive!");
434      }
435  
436  // Alloc memory and fill standart StatModel's fields.
437      CV_CALL (crVal = (CvCrossValidationModel*)cvCreateStatModel (
438                              CV_STAT_MODEL_MAGIC_VAL | CV_CROSSVAL_MAGIC_VAL,
439                              sizeof(CvCrossValidationModel),
440                              cvReleaseCrossValidationModel,
441                              NULL, NULL));
442      crVal->current_fold    = -1;
443      crVal->folds_all       = k_fold;
444      if (estimateParams && ((CvCrossValidationParams*)estimateParams)->is_regression)
445          crVal->is_regression = 1;
446      else
447          crVal->is_regression = 0;
448      if (estimateParams && ((CvCrossValidationParams*)estimateParams)->rng)
449          prng = ((CvCrossValidationParams*)estimateParams)->rng;
450      else
451          prng = &rng;
452  
453      // Check and preprocess sample indices.
454      if (sampleIdx)
455      {
456          int s_step;
457          int s_type = 0;
458  
459          if (!CV_IS_MAT (sampleIdx))
460              CV_ERROR (CV_StsBadArg, "Invalid sampleIdx array");
461  
462          if (sampleIdx->rows != 1 && sampleIdx->cols != 1)
463              CV_ERROR (CV_StsBadSize, "sampleIdx array must be 1-dimensional");
464  
465          s_len = sampleIdx->rows + sampleIdx->cols - 1;
466          s_step = sampleIdx->rows == 1 ?
467                                       1 : sampleIdx->step / CV_ELEM_SIZE(sampleIdx->type);
468  
469          s_type = CV_MAT_TYPE (sampleIdx->type);
470  
471          switch (s_type)
472          {
473          case CV_8UC1:
474          case CV_8SC1:
475              {
476              uchar* s_data = sampleIdx->data.ptr;
477  
478              // sampleIdx is array of 1's and 0's -
479              // i.e. it is a mask of the selected samples
480              if( s_len != samples_all )
481                  CV_ERROR (CV_StsUnmatchedSizes,
482         "Sample mask should contain as many elements as the total number of samples");
483  
484              samples_selected = 0;
485              for (i = 0; i < s_len; i++)
486                  samples_selected += s_data[i * s_step] != 0;
487  
488              if (samples_selected == 0)
489                  CV_ERROR (CV_StsOutOfRange, "No samples is selected!");
490              }
491              s_len = samples_selected;
492              break;
493          case CV_32SC1:
494              if (s_len > samples_all)
495                  CV_ERROR (CV_StsOutOfRange,
496          "sampleIdx array may not contain more elements than the total number of samples");
497              samples_selected = s_len;
498              break;
499          default:
500              CV_ERROR (CV_StsUnsupportedFormat, "Unsupported sampleIdx array data type "
501                                                 "(it should be 8uC1, 8sC1 or 32sC1)");
502          }
503  
504          // Alloc additional memory for internal Idx and fill it.
505  /*!!*/  CV_CALL (res_s_data = crVal->sampleIdxAll =
506                                                   (int*)cvAlloc (2 * s_len * sizeof(int)));
507  
508          if (s_type < CV_32SC1)
509          {
510              uchar* s_data = sampleIdx->data.ptr;
511              for (i = 0; i < s_len; i++)
512                  if (s_data[i * s_step])
513                  {
514                      *res_s_data++ = i;
515                  }
516              res_s_data = crVal->sampleIdxAll;
517          }
518          else
519          {
520              int* s_data = sampleIdx->data.i;
521              int out_of_order = 0;
522  
523              for (i = 0; i < s_len; i++)
524              {
525                  res_s_data[i] = s_data[i * s_step];
526                  if (i > 0 && res_s_data[i] < res_s_data[i - 1])
527                      out_of_order = 1;
528              }
529  
530              if (out_of_order)
531                  qsort (res_s_data, s_len, sizeof(res_s_data[0]), icvCmpIntegers);
532  
533              if (res_s_data[0] < 0 ||
534                  res_s_data[s_len - 1] >= samples_all)
535                      CV_ERROR (CV_StsBadArg, "There are out-of-range sample indices");
536              for (i = 1; i < s_len; i++)
537                  if (res_s_data[i] <= res_s_data[i - 1])
538                      CV_ERROR (CV_StsBadArg, "There are duplicated");
539          }
540      }
541      else // if (sampleIdx)
542      {
543          // Alloc additional memory for internal Idx and fill it.
544          s_len = samples_all;
545          CV_CALL (res_s_data = crVal->sampleIdxAll = (int*)cvAlloc (2 * s_len * sizeof(int)));
546          for (i = 0; i < s_len; i++)
547          {
548              *res_s_data++ = i;
549          }
550          res_s_data = crVal->sampleIdxAll;
551      } // if (sampleIdx) ... else
552  
553  // Resort internal Idx.
554      te_s_data = res_s_data + s_len;
555      for (i = s_len; i > 1; i--)
556      {
557          j = cvRandInt (prng) % i;
558          k = *(--te_s_data);
559          *te_s_data = res_s_data[j];
560          res_s_data[j] = k;
561      }
562  
563  // Duplicate resorted internal Idx.
564  // It will be used to simplify operation of getting trainIdx.
565      te_s_data = res_s_data + s_len;
566      for (i = 0; i < s_len; i++)
567      {
568          *te_s_data++ = *res_s_data++;
569      }
570  
571  // Cut sampleIdxAll to parts.
572      if (k_fold > 0)
573      {
574          if (k_fold > s_len)
575          {
576              CV_ERROR (CV_StsBadArg,
577                          "Error in parameters of cross-validation ('k_fold' > #samples)!");
578          }
579          folds = crVal->folds = (int*) cvAlloc ((k_fold + 1) * sizeof (int));
580          *folds++ = 0;
581          for (i = 1; i < k_fold; i++)
582          {
583              *folds++ = cvRound (i * s_len * 1. / k_fold);
584          }
585          *folds = s_len;
586          folds = crVal->folds;
587  
588          crVal->max_fold_size = (s_len - 1) / k_fold + 1;
589      }
590      else
591      {
592          k = -k_fold;
593          crVal->max_fold_size = k;
594          if (k >= s_len)
595          {
596              CV_ERROR (CV_StsBadArg,
597                        "Error in parameters of cross-validation (-'k_fold' > #samples)!");
598          }
599          crVal->folds_all = k = (s_len - 1) / k + 1;
600  
601          folds = crVal->folds = (int*) cvAlloc ((k + 1) * sizeof (int));
602          for (i = 0; i < k; i++)
603          {
604              *folds++ = -i * k_fold;
605          }
606          *folds = s_len;
607          folds = crVal->folds;
608      }
609  
610  // Prepare other internal fields to working.
611      CV_CALL (crVal->predict_results = cvCreateMat (1, samples_all, CV_32FC1));
612      CV_CALL (crVal->sampleIdxEval = cvCreateMatHeader (1, 1, CV_32SC1));
613      CV_CALL (crVal->sampleIdxTrain = cvCreateMatHeader (1, 1, CV_32SC1));
614      crVal->sampleIdxEval->cols = 0;
615      crVal->sampleIdxTrain->cols = 0;
616      crVal->samples_all = s_len;
617      crVal->is_checked = 1;
618  
619      crVal->getTrainIdxMat = cvCrossValGetTrainIdxMatrix;
620      crVal->getCheckIdxMat = cvCrossValGetCheckIdxMatrix;
621      crVal->nextStep = cvCrossValNextStep;
622      crVal->check = cvCrossValCheckClassifier;
623      crVal->getResult = cvCrossValGetResult;
624      crVal->reset = cvCrossValReset;
625  
626      model = (CvStatModel*)crVal;
627  
628          __END__
629  
630      if (!model)
631      {
632          cvReleaseCrossValidationModel ((CvStatModel**)&crVal);
633      }
634  
635      return model;
636  } // End of cvCreateCrossValidationEstimateModel
637  
638  
639  /****************************************************************************************\
640  *                Extended interface with backcalls for models                            *
641  \****************************************************************************************/
642  ML_IMPL float
643  cvCrossValidation (const CvMat*            trueData,
644                           int               tflag,
645                     const CvMat*            trueClasses,
646                           CvStatModel*     (*createClassifier) (const CvMat*,
647                                                                       int,
648                                                                 const CvMat*,
649                                                                 const CvClassifierTrainParams*,
650                                                                 const CvMat*,
651                                                                 const CvMat*,
652                                                                 const CvMat*,
653                                                                 const CvMat*),
654                     const CvClassifierTrainParams*    estimateParams,
655                     const CvClassifierTrainParams*    trainParams,
656                     const CvMat*            compIdx,
657                     const CvMat*            sampleIdx,
658                           CvStatModel**     pCrValModel,
659                     const CvMat*            typeMask,
660                     const CvMat*            missedMeasurementMask)
661  {
662      CvCrossValidationModel* crVal = NULL;
663      float  result = 0;
664      CvStatModel* pClassifier = NULL;
665  
666          CV_FUNCNAME ("cvCrossValidation");
667          __BEGIN__
668  
669      const CvMat* trainDataIdx;
670      int    samples_all;
671  
672  // checking input data
673      if ((createClassifier) == NULL)
674      {
675          CV_ERROR (CV_StsNullPtr, "Null pointer to functiion which create classifier");
676      }
677      if (pCrValModel && *pCrValModel && !CV_IS_CROSSVAL(*pCrValModel))
678      {
679          CV_ERROR (CV_StsBadArg,
680             "<pCrValModel> point to not cross-validation model");
681      }
682  
683  // initialization
684      if (pCrValModel && *pCrValModel)
685      {
686          crVal = (CvCrossValidationModel*)*pCrValModel;
687          crVal->reset ((CvStatModel*)crVal);
688      }
689      else
690      {
691          samples_all = ((tflag) ? trueData->rows : trueData->cols);
692          CV_CALL (crVal = (CvCrossValidationModel*)
693             cvCreateCrossValidationEstimateModel (samples_all, estimateParams, sampleIdx));
694      }
695  
696      CV_CALL (trainDataIdx = crVal->getTrainIdxMat ((CvStatModel*)crVal));
697  
698  // operation loop
699      for (; crVal->nextStep((CvStatModel*)crVal) != 0; )
700      {
701          CV_CALL (pClassifier = createClassifier (trueData, tflag, trueClasses,
702                      trainParams, compIdx, trainDataIdx, typeMask, missedMeasurementMask));
703          CV_CALL (crVal->check ((CvStatModel*)crVal, pClassifier,
704                                                             trueData, tflag, trueClasses));
705  
706          pClassifier->release (&pClassifier);
707      }
708  
709  // Get result and fill output field.
710      CV_CALL (result = crVal->getResult ((CvStatModel*)crVal, 0));
711  
712      if (pCrValModel && !*pCrValModel)
713          *pCrValModel = (CvStatModel*)crVal;
714  
715          __END__
716  
717  // Free all memory that should be freed.
718      if (pClassifier)
719          pClassifier->release (&pClassifier);
720      if (crVal && (!pCrValModel || !*pCrValModel))
721          crVal->release ((CvStatModel**)&crVal);
722  
723      return result;
724  } // End of cvCrossValidation
725  
726  #endif
727  
728  /* End of file */
729