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 47 CvTrainTestSplit::CvTrainTestSplit() 48 { 49 train_sample_part_mode = CV_COUNT; 50 train_sample_part.count = -1; 51 mix = false; 52 } 53 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 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 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 87 CvMLData::~CvMLData() 88 { 89 clear(); 90 } 91 92 void CvMLData::free_train_test_idx() 93 { 94 cvReleaseMat( &train_sample_idx ); 95 cvReleaseMat( &test_sample_idx ); 96 sample_idx = 0; 97 } 98 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 122 void CvMLData::set_header_lines_number( int idx ) 123 { 124 header_lines_number = std::max(0, idx); 125 } 126 127 int CvMLData::get_header_lines_number() const 128 { 129 return header_lines_number; 130 } 131 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 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 276 const CvMat* CvMLData::get_values() const 277 { 278 return values; 279 } 280 281 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 294 const std::map<cv::String, int>& CvMLData::get_class_labels_map() const 295 { 296 return class_map; 297 } 298 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 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 341 char CvMLData::get_delimiter() const 342 { 343 return delimiter; 344 } 345 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 359 char CvMLData::get_miss_ch() const 360 { 361 return miss_ch; 362 } 363 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 384 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 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 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 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 587 int CvMLData::get_var_type( int var_idx ) const 588 { 589 return var_types->data.ptr[var_idx]; 590 } 591 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 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 677 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 689 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 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 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 766 void CvMLData::chahge_var_idx( int vi, bool state ) 767 { 768 change_var_idx( vi, state ); 769 } 770 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