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 "old_ml_precomp.hpp"
42 #include <ctype.h>
43
44 #define MISS_VAL FLT_MAX
45 #define CV_VAR_MISS 0
46
CvTrainTestSplit()47 CvTrainTestSplit::CvTrainTestSplit()
48 {
49 train_sample_part_mode = CV_COUNT;
50 train_sample_part.count = -1;
51 mix = false;
52 }
53
CvTrainTestSplit(int _train_sample_count,bool _mix)54 CvTrainTestSplit::CvTrainTestSplit( int _train_sample_count, bool _mix )
55 {
56 train_sample_part_mode = CV_COUNT;
57 train_sample_part.count = _train_sample_count;
58 mix = _mix;
59 }
60
CvTrainTestSplit(float _train_sample_portion,bool _mix)61 CvTrainTestSplit::CvTrainTestSplit( float _train_sample_portion, bool _mix )
62 {
63 train_sample_part_mode = CV_PORTION;
64 train_sample_part.portion = _train_sample_portion;
65 mix = _mix;
66 }
67
68 ////////////////
69
CvMLData()70 CvMLData::CvMLData()
71 {
72 values = missing = var_types = var_idx_mask = response_out = var_idx_out = var_types_out = 0;
73 train_sample_idx = test_sample_idx = 0;
74 header_lines_number = 0;
75 sample_idx = 0;
76 response_idx = -1;
77
78 train_sample_count = -1;
79
80 delimiter = ',';
81 miss_ch = '?';
82 //flt_separator = '.';
83
84 rng = &cv::theRNG();
85 }
86
~CvMLData()87 CvMLData::~CvMLData()
88 {
89 clear();
90 }
91
free_train_test_idx()92 void CvMLData::free_train_test_idx()
93 {
94 cvReleaseMat( &train_sample_idx );
95 cvReleaseMat( &test_sample_idx );
96 sample_idx = 0;
97 }
98
clear()99 void CvMLData::clear()
100 {
101 class_map.clear();
102
103 cvReleaseMat( &values );
104 cvReleaseMat( &missing );
105 cvReleaseMat( &var_types );
106 cvReleaseMat( &var_idx_mask );
107
108 cvReleaseMat( &response_out );
109 cvReleaseMat( &var_idx_out );
110 cvReleaseMat( &var_types_out );
111
112 free_train_test_idx();
113
114 total_class_count = 0;
115
116 response_idx = -1;
117
118 train_sample_count = -1;
119 }
120
121
set_header_lines_number(int idx)122 void CvMLData::set_header_lines_number( int idx )
123 {
124 header_lines_number = std::max(0, idx);
125 }
126
get_header_lines_number() const127 int CvMLData::get_header_lines_number() const
128 {
129 return header_lines_number;
130 }
131
fgets_chomp(char * str,int n,FILE * stream)132 static char *fgets_chomp(char *str, int n, FILE *stream)
133 {
134 char *head = fgets(str, n, stream);
135 if( head )
136 {
137 for(char *tail = head + strlen(head) - 1; tail >= head; --tail)
138 {
139 if( *tail != '\r' && *tail != '\n' )
140 break;
141 *tail = '\0';
142 }
143 }
144 return head;
145 }
146
147
read_csv(const char * filename)148 int CvMLData::read_csv(const char* filename)
149 {
150 const int M = 1000000;
151 const char str_delimiter[3] = { ' ', delimiter, '\0' };
152 FILE* file = 0;
153 CvMemStorage* storage;
154 CvSeq* seq;
155 char *ptr;
156 float* el_ptr;
157 CvSeqReader reader;
158 int cols_count = 0;
159 uchar *var_types_ptr = 0;
160
161 clear();
162
163 file = fopen( filename, "rt" );
164
165 if( !file )
166 return -1;
167
168 std::vector<char> _buf(M);
169 char* buf = &_buf[0];
170
171 // skip header lines
172 for( int i = 0; i < header_lines_number; i++ )
173 {
174 if( fgets( buf, M, file ) == 0 )
175 {
176 fclose(file);
177 return -1;
178 }
179 }
180
181 // read the first data line and determine the number of variables
182 if( !fgets_chomp( buf, M, file ))
183 {
184 fclose(file);
185 return -1;
186 }
187
188 ptr = buf;
189 while( *ptr == ' ' )
190 ptr++;
191 for( ; *ptr != '\0'; )
192 {
193 if(*ptr == delimiter || *ptr == ' ')
194 {
195 cols_count++;
196 ptr++;
197 while( *ptr == ' ' ) ptr++;
198 }
199 else
200 ptr++;
201 }
202
203 cols_count++;
204
205 if ( cols_count == 0)
206 {
207 fclose(file);
208 return -1;
209 }
210
211 // create temporary memory storage to store the whole database
212 el_ptr = new float[cols_count];
213 storage = cvCreateMemStorage();
214 seq = cvCreateSeq( 0, sizeof(*seq), cols_count*sizeof(float), storage );
215
216 var_types = cvCreateMat( 1, cols_count, CV_8U );
217 cvZero( var_types );
218 var_types_ptr = var_types->data.ptr;
219
220 for(;;)
221 {
222 char *token = NULL;
223 int type;
224 token = strtok(buf, str_delimiter);
225 if (!token)
226 break;
227 for (int i = 0; i < cols_count-1; i++)
228 {
229 str_to_flt_elem( token, el_ptr[i], type);
230 var_types_ptr[i] |= type;
231 token = strtok(NULL, str_delimiter);
232 if (!token)
233 {
234 fclose(file);
235 delete [] el_ptr;
236 return -1;
237 }
238 }
239 str_to_flt_elem( token, el_ptr[cols_count-1], type);
240 var_types_ptr[cols_count-1] |= type;
241 cvSeqPush( seq, el_ptr );
242 if( !fgets_chomp( buf, M, file ) )
243 break;
244 }
245 fclose(file);
246
247 values = cvCreateMat( seq->total, cols_count, CV_32FC1 );
248 missing = cvCreateMat( seq->total, cols_count, CV_8U );
249 var_idx_mask = cvCreateMat( 1, values->cols, CV_8UC1 );
250 cvSet( var_idx_mask, cvRealScalar(1) );
251 train_sample_count = seq->total;
252
253 cvStartReadSeq( seq, &reader );
254 for(int i = 0; i < seq->total; i++ )
255 {
256 const float* sdata = (float*)reader.ptr;
257 float* ddata = values->data.fl + cols_count*i;
258 uchar* dm = missing->data.ptr + cols_count*i;
259
260 for( int j = 0; j < cols_count; j++ )
261 {
262 ddata[j] = sdata[j];
263 dm[j] = ( fabs( MISS_VAL - sdata[j] ) <= FLT_EPSILON );
264 }
265 CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
266 }
267
268 if ( cvNorm( missing, 0, CV_L1 ) <= FLT_EPSILON )
269 cvReleaseMat( &missing );
270
271 cvReleaseMemStorage( &storage );
272 delete []el_ptr;
273 return 0;
274 }
275
get_values() const276 const CvMat* CvMLData::get_values() const
277 {
278 return values;
279 }
280
get_missing() const281 const CvMat* CvMLData::get_missing() const
282 {
283 CV_FUNCNAME( "CvMLData::get_missing" );
284 __BEGIN__;
285
286 if ( !values )
287 CV_ERROR( CV_StsInternal, "data is empty" );
288
289 __END__;
290
291 return missing;
292 }
293
get_class_labels_map() const294 const std::map<cv::String, int>& CvMLData::get_class_labels_map() const
295 {
296 return class_map;
297 }
298
str_to_flt_elem(const char * token,float & flt_elem,int & type)299 void CvMLData::str_to_flt_elem( const char* token, float& flt_elem, int& type)
300 {
301
302 char* stopstring = NULL;
303 flt_elem = (float)strtod( token, &stopstring );
304 assert( stopstring );
305 type = CV_VAR_ORDERED;
306 if ( *stopstring == miss_ch && strlen(stopstring) == 1 ) // missed value
307 {
308 flt_elem = MISS_VAL;
309 type = CV_VAR_MISS;
310 }
311 else
312 {
313 if ( (*stopstring != 0) && (*stopstring != '\n') && (strcmp(stopstring, "\r\n") != 0) ) // class label
314 {
315 int idx = class_map[token];
316 if ( idx == 0)
317 {
318 total_class_count++;
319 idx = total_class_count;
320 class_map[token] = idx;
321 }
322 flt_elem = (float)idx;
323 type = CV_VAR_CATEGORICAL;
324 }
325 }
326 }
327
set_delimiter(char ch)328 void CvMLData::set_delimiter(char ch)
329 {
330 CV_FUNCNAME( "CvMLData::set_delimited" );
331 __BEGIN__;
332
333 if (ch == miss_ch /*|| ch == flt_separator*/)
334 CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different");
335
336 delimiter = ch;
337
338 __END__;
339 }
340
get_delimiter() const341 char CvMLData::get_delimiter() const
342 {
343 return delimiter;
344 }
345
set_miss_ch(char ch)346 void CvMLData::set_miss_ch(char ch)
347 {
348 CV_FUNCNAME( "CvMLData::set_miss_ch" );
349 __BEGIN__;
350
351 if (ch == delimiter/* || ch == flt_separator*/)
352 CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different");
353
354 miss_ch = ch;
355
356 __END__;
357 }
358
get_miss_ch() const359 char CvMLData::get_miss_ch() const
360 {
361 return miss_ch;
362 }
363
set_response_idx(int idx)364 void CvMLData::set_response_idx( int idx )
365 {
366 CV_FUNCNAME( "CvMLData::set_response_idx" );
367 __BEGIN__;
368
369 if ( !values )
370 CV_ERROR( CV_StsInternal, "data is empty" );
371
372 if ( idx >= values->cols)
373 CV_ERROR( CV_StsBadArg, "idx value is not correct" );
374
375 if ( response_idx >= 0 )
376 chahge_var_idx( response_idx, true );
377 if ( idx >= 0 )
378 chahge_var_idx( idx, false );
379 response_idx = idx;
380
381 __END__;
382 }
383
get_response_idx() const384 int CvMLData::get_response_idx() const
385 {
386 CV_FUNCNAME( "CvMLData::get_response_idx" );
387 __BEGIN__;
388
389 if ( !values )
390 CV_ERROR( CV_StsInternal, "data is empty" );
391 __END__;
392 return response_idx;
393 }
394
change_var_type(int var_idx,int type)395 void CvMLData::change_var_type( int var_idx, int type )
396 {
397 CV_FUNCNAME( "CvMLData::change_var_type" );
398 __BEGIN__;
399
400 int var_count = 0;
401
402 if ( !values )
403 CV_ERROR( CV_StsInternal, "data is empty" );
404
405 var_count = values->cols;
406
407 if ( var_idx < 0 || var_idx >= var_count)
408 CV_ERROR( CV_StsBadArg, "var_idx is not correct" );
409
410 if ( type != CV_VAR_ORDERED && type != CV_VAR_CATEGORICAL)
411 CV_ERROR( CV_StsBadArg, "type is not correct" );
412
413 assert( var_types );
414 if ( var_types->data.ptr[var_idx] == CV_VAR_CATEGORICAL && type == CV_VAR_ORDERED)
415 CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );
416 var_types->data.ptr[var_idx] = (uchar)type;
417
418 __END__;
419
420 return;
421 }
422
set_var_types(const char * str)423 void CvMLData::set_var_types( const char* str )
424 {
425 CV_FUNCNAME( "CvMLData::set_var_types" );
426 __BEGIN__;
427
428 const char* ord = 0, *cat = 0;
429 int var_count = 0, set_var_type_count = 0;
430 if ( !values )
431 CV_ERROR( CV_StsInternal, "data is empty" );
432
433 var_count = values->cols;
434
435 assert( var_types );
436
437 ord = strstr( str, "ord" );
438 cat = strstr( str, "cat" );
439 if ( !ord && !cat )
440 CV_ERROR( CV_StsBadArg, "types string is not correct" );
441
442 if ( !ord && strlen(cat) == 3 ) // str == "cat"
443 {
444 cvSet( var_types, cvScalarAll(CV_VAR_CATEGORICAL) );
445 return;
446 }
447
448 if ( !cat && strlen(ord) == 3 ) // str == "ord"
449 {
450 cvSet( var_types, cvScalarAll(CV_VAR_ORDERED) );
451 return;
452 }
453
454 if ( ord ) // parse ord str
455 {
456 char* stopstring = NULL;
457 if ( ord[3] != '[')
458 CV_ERROR( CV_StsBadArg, "types string is not correct" );
459
460 ord += 4; // pass "ord["
461 do
462 {
463 int b1 = (int)strtod( ord, &stopstring );
464 if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') )
465 CV_ERROR( CV_StsBadArg, "types string is not correct" );
466 ord = stopstring + 1;
467 if ( (stopstring[0] == ',') || (stopstring[0] == ']'))
468 {
469 if ( var_types->data.ptr[b1] == CV_VAR_CATEGORICAL)
470 CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );
471 var_types->data.ptr[b1] = CV_VAR_ORDERED;
472 set_var_type_count++;
473 }
474 else
475 {
476 if ( stopstring[0] == '-')
477 {
478 int b2 = (int)strtod( ord, &stopstring);
479 if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') )
480 CV_ERROR( CV_StsBadArg, "types string is not correct" );
481 ord = stopstring + 1;
482 for (int i = b1; i <= b2; i++)
483 {
484 if ( var_types->data.ptr[i] == CV_VAR_CATEGORICAL)
485 CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );
486 var_types->data.ptr[i] = CV_VAR_ORDERED;
487 }
488 set_var_type_count += b2 - b1 + 1;
489 }
490 else
491 CV_ERROR( CV_StsBadArg, "types string is not correct" );
492
493 }
494 }
495 while (*stopstring != ']');
496
497 if ( stopstring[1] != '\0' && stopstring[1] != ',')
498 CV_ERROR( CV_StsBadArg, "types string is not correct" );
499 }
500
501 if ( cat ) // parse cat str
502 {
503 char* stopstring = NULL;
504 if ( cat[3] != '[')
505 CV_ERROR( CV_StsBadArg, "types string is not correct" );
506
507 cat += 4; // pass "cat["
508 do
509 {
510 int b1 = (int)strtod( cat, &stopstring );
511 if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') )
512 CV_ERROR( CV_StsBadArg, "types string is not correct" );
513 cat = stopstring + 1;
514 if ( (stopstring[0] == ',') || (stopstring[0] == ']'))
515 {
516 var_types->data.ptr[b1] = CV_VAR_CATEGORICAL;
517 set_var_type_count++;
518 }
519 else
520 {
521 if ( stopstring[0] == '-')
522 {
523 int b2 = (int)strtod( cat, &stopstring);
524 if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') )
525 CV_ERROR( CV_StsBadArg, "types string is not correct" );
526 cat = stopstring + 1;
527 for (int i = b1; i <= b2; i++)
528 var_types->data.ptr[i] = CV_VAR_CATEGORICAL;
529 set_var_type_count += b2 - b1 + 1;
530 }
531 else
532 CV_ERROR( CV_StsBadArg, "types string is not correct" );
533
534 }
535 }
536 while (*stopstring != ']');
537
538 if ( stopstring[1] != '\0' && stopstring[1] != ',')
539 CV_ERROR( CV_StsBadArg, "types string is not correct" );
540 }
541
542 if (set_var_type_count != var_count)
543 CV_ERROR( CV_StsBadArg, "types string is not correct" );
544
545 __END__;
546 }
547
get_var_types()548 const CvMat* CvMLData::get_var_types()
549 {
550 CV_FUNCNAME( "CvMLData::get_var_types" );
551 __BEGIN__;
552
553 uchar *var_types_out_ptr = 0;
554 int avcount, vt_size;
555 if ( !values )
556 CV_ERROR( CV_StsInternal, "data is empty" );
557
558 assert( var_idx_mask );
559
560 avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) );
561 vt_size = avcount + (response_idx >= 0);
562
563 if ( avcount == values->cols || (avcount == values->cols-1 && response_idx == values->cols-1) )
564 return var_types;
565
566 if ( !var_types_out || ( var_types_out && var_types_out->cols != vt_size ) )
567 {
568 cvReleaseMat( &var_types_out );
569 var_types_out = cvCreateMat( 1, vt_size, CV_8UC1 );
570 }
571
572 var_types_out_ptr = var_types_out->data.ptr;
573 for( int i = 0; i < var_types->cols; i++)
574 {
575 if (i == response_idx || !var_idx_mask->data.ptr[i]) continue;
576 *var_types_out_ptr = var_types->data.ptr[i];
577 var_types_out_ptr++;
578 }
579 if ( response_idx >= 0 )
580 *var_types_out_ptr = var_types->data.ptr[response_idx];
581
582 __END__;
583
584 return var_types_out;
585 }
586
get_var_type(int var_idx) const587 int CvMLData::get_var_type( int var_idx ) const
588 {
589 return var_types->data.ptr[var_idx];
590 }
591
get_responses()592 const CvMat* CvMLData::get_responses()
593 {
594 CV_FUNCNAME( "CvMLData::get_responses_ptr" );
595 __BEGIN__;
596
597 int var_count = 0;
598
599 if ( !values )
600 CV_ERROR( CV_StsInternal, "data is empty" );
601 var_count = values->cols;
602
603 if ( response_idx < 0 || response_idx >= var_count )
604 return 0;
605 if ( !response_out )
606 response_out = cvCreateMatHeader( values->rows, 1, CV_32FC1 );
607 else
608 cvInitMatHeader( response_out, values->rows, 1, CV_32FC1);
609 cvGetCol( values, response_out, response_idx );
610
611 __END__;
612
613 return response_out;
614 }
615
set_train_test_split(const CvTrainTestSplit * spl)616 void CvMLData::set_train_test_split( const CvTrainTestSplit * spl)
617 {
618 CV_FUNCNAME( "CvMLData::set_division" );
619 __BEGIN__;
620
621 int sample_count = 0;
622
623 if ( !values )
624 CV_ERROR( CV_StsInternal, "data is empty" );
625
626 sample_count = values->rows;
627
628 float train_sample_portion;
629
630 if (spl->train_sample_part_mode == CV_COUNT)
631 {
632 train_sample_count = spl->train_sample_part.count;
633 if (train_sample_count > sample_count)
634 CV_ERROR( CV_StsBadArg, "train samples count is not correct" );
635 train_sample_count = train_sample_count<=0 ? sample_count : train_sample_count;
636 }
637 else // dtype.train_sample_part_mode == CV_PORTION
638 {
639 train_sample_portion = spl->train_sample_part.portion;
640 if ( train_sample_portion > 1)
641 CV_ERROR( CV_StsBadArg, "train samples count is not correct" );
642 train_sample_portion = train_sample_portion <= FLT_EPSILON ||
643 1 - train_sample_portion <= FLT_EPSILON ? 1 : train_sample_portion;
644 train_sample_count = std::max(1, cvFloor( train_sample_portion * sample_count ));
645 }
646
647 if ( train_sample_count == sample_count )
648 {
649 free_train_test_idx();
650 return;
651 }
652
653 if ( train_sample_idx && train_sample_idx->cols != train_sample_count )
654 free_train_test_idx();
655
656 if ( !sample_idx)
657 {
658 int test_sample_count = sample_count- train_sample_count;
659 sample_idx = (int*)cvAlloc( sample_count * sizeof(sample_idx[0]) );
660 for (int i = 0; i < sample_count; i++ )
661 sample_idx[i] = i;
662 train_sample_idx = cvCreateMatHeader( 1, train_sample_count, CV_32SC1 );
663 *train_sample_idx = cvMat( 1, train_sample_count, CV_32SC1, &sample_idx[0] );
664
665 CV_Assert(test_sample_count > 0);
666 test_sample_idx = cvCreateMatHeader( 1, test_sample_count, CV_32SC1 );
667 *test_sample_idx = cvMat( 1, test_sample_count, CV_32SC1, &sample_idx[train_sample_count] );
668 }
669
670 mix = spl->mix;
671 if ( mix )
672 mix_train_and_test_idx();
673
674 __END__;
675 }
676
get_train_sample_idx() const677 const CvMat* CvMLData::get_train_sample_idx() const
678 {
679 CV_FUNCNAME( "CvMLData::get_train_sample_idx" );
680 __BEGIN__;
681
682 if ( !values )
683 CV_ERROR( CV_StsInternal, "data is empty" );
684 __END__;
685
686 return train_sample_idx;
687 }
688
get_test_sample_idx() const689 const CvMat* CvMLData::get_test_sample_idx() const
690 {
691 CV_FUNCNAME( "CvMLData::get_test_sample_idx" );
692 __BEGIN__;
693
694 if ( !values )
695 CV_ERROR( CV_StsInternal, "data is empty" );
696 __END__;
697
698 return test_sample_idx;
699 }
700
mix_train_and_test_idx()701 void CvMLData::mix_train_and_test_idx()
702 {
703 CV_FUNCNAME( "CvMLData::mix_train_and_test_idx" );
704 __BEGIN__;
705
706 if ( !values )
707 CV_ERROR( CV_StsInternal, "data is empty" );
708 __END__;
709
710 if ( !sample_idx)
711 return;
712
713 if ( train_sample_count > 0 && train_sample_count < values->rows )
714 {
715 int n = values->rows;
716 for (int i = 0; i < n; i++)
717 {
718 int a = (*rng)(n);
719 int b = (*rng)(n);
720 int t;
721 CV_SWAP( sample_idx[a], sample_idx[b], t );
722 }
723 }
724 }
725
get_var_idx()726 const CvMat* CvMLData::get_var_idx()
727 {
728 CV_FUNCNAME( "CvMLData::get_var_idx" );
729 __BEGIN__;
730
731 int avcount = 0;
732
733 if ( !values )
734 CV_ERROR( CV_StsInternal, "data is empty" );
735
736 assert( var_idx_mask );
737
738 avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) );
739 int* vidx;
740
741 if ( avcount == values->cols )
742 return 0;
743
744 if ( !var_idx_out || ( var_idx_out && var_idx_out->cols != avcount ) )
745 {
746 cvReleaseMat( &var_idx_out );
747 var_idx_out = cvCreateMat( 1, avcount, CV_32SC1);
748 if ( response_idx >=0 )
749 var_idx_mask->data.ptr[response_idx] = 0;
750 }
751
752 vidx = var_idx_out->data.i;
753
754 for(int i = 0; i < var_idx_mask->cols; i++)
755 if ( var_idx_mask->data.ptr[i] )
756 {
757 *vidx = i;
758 vidx++;
759 }
760
761 __END__;
762
763 return var_idx_out;
764 }
765
chahge_var_idx(int vi,bool state)766 void CvMLData::chahge_var_idx( int vi, bool state )
767 {
768 change_var_idx( vi, state );
769 }
770
change_var_idx(int vi,bool state)771 void CvMLData::change_var_idx( int vi, bool state )
772 {
773 CV_FUNCNAME( "CvMLData::change_var_idx" );
774 __BEGIN__;
775
776 int var_count = 0;
777
778 if ( !values )
779 CV_ERROR( CV_StsInternal, "data is empty" );
780
781 var_count = values->cols;
782
783 if ( vi < 0 || vi >= var_count)
784 CV_ERROR( CV_StsBadArg, "variable index is not correct" );
785
786 assert( var_idx_mask );
787 var_idx_mask->data.ptr[vi] = state;
788
789 __END__;
790 }
791
792 /* End of file. */
793