--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////\r
+//\r
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
+//\r
+// By downloading, copying, installing or using the software you agree to this license.\r
+// If you do not agree to this license, do not download, install,\r
+// copy or use the software.\r
+//\r
+//\r
+// Intel License Agreement\r
+//\r
+// Copyright (C) 2000, Intel Corporation, all rights reserved.\r
+// Third party copyrights are property of their respective owners.\r
+//\r
+// Redistribution and use in source and binary forms, with or without modification,\r
+// are permitted provided that the following conditions are met:\r
+//\r
+// * Redistribution's of source code must retain the above copyright notice,\r
+// this list of conditions and the following disclaimer.\r
+//\r
+// * Redistribution's in binary form must reproduce the above copyright notice,\r
+// this list of conditions and the following disclaimer in the documentation\r
+// and/or other materials provided with the distribution.\r
+//\r
+// * The name of Intel Corporation may not be used to endorse or promote products\r
+// derived from this software without specific prior written permission.\r
+//\r
+// This software is provided by the copyright holders and contributors "as is" and\r
+// any express or implied warranties, including, but not limited to, the implied\r
+// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
+// In no event shall the Intel Corporation or contributors be liable for any direct,\r
+// indirect, incidental, special, exemplary, or consequential damages\r
+// (including, but not limited to, procurement of substitute goods or services;\r
+// loss of use, data, or profits; or business interruption) however caused\r
+// and on any theory of liability, whether in contract, strict liability,\r
+// or tort (including negligence or otherwise) arising in any way out of\r
+// the use of this software, even if advised of the possibility of such damage.\r
+//\r
+//M*/\r
+\r
+#include "_ml.h"\r
+#include <ctype.h>\r
+\r
+#define MISS_VAL FLT_MAX \r
+#define CV_VAR_MISS 0\r
+\r
+CvTrainTestSplit :: CvTrainTestSplit()\r
+{\r
+ train_sample_part_mode = CV_COUNT;\r
+ train_sample_part.count = -1;\r
+ class_part = 0;\r
+ mix = false;\r
+}\r
+\r
+CvTrainTestSplit :: CvTrainTestSplit( int _train_sample_count, bool _mix )\r
+{\r
+ train_sample_part_mode = CV_COUNT;\r
+ train_sample_part.count = _train_sample_count;\r
+ class_part = 0;\r
+ mix = _mix;\r
+}\r
+ \r
+CvTrainTestSplit :: CvTrainTestSplit( float _train_sample_portion, bool _mix )\r
+{\r
+ train_sample_part_mode = CV_PORTION;\r
+ train_sample_part.portion = _train_sample_portion;\r
+ class_part = 0;\r
+ mix = _mix;\r
+}\r
+\r
+////////////////\r
+\r
+CvMLData :: CvMLData()\r
+{\r
+ values = missing = var_types = var_idx_mask = response_out = var_idx_out = var_types_out = 0;\r
+ train_sample_idx = test_sample_idx = 0;\r
+ sample_idx = 0;\r
+ response_idx = -1;\r
+\r
+ train_sample_count = -1;\r
+\r
+ delimiter = ',';\r
+ miss_ch = '?';\r
+ //flt_separator = '.';\r
+\r
+ class_map = new map<string, int>();\r
+ rng = cvRNG( -cvGetTickCount() );\r
+}\r
+\r
+CvMLData :: ~CvMLData()\r
+{\r
+ clear();\r
+ delete class_map;\r
+}\r
+\r
+void CvMLData :: free_train_test_idx()\r
+{\r
+ cvReleaseMat( &train_sample_idx );\r
+ cvReleaseMat( &test_sample_idx );\r
+ sample_idx = 0;\r
+}\r
+\r
+void CvMLData :: clear()\r
+{\r
+ if ( !class_map->empty() )\r
+ class_map->clear();\r
+\r
+ cvReleaseMat( &values );\r
+ cvReleaseMat( &missing );\r
+ cvReleaseMat( &var_types );\r
+ cvReleaseMat( &var_idx_mask );\r
+\r
+ cvReleaseMat( &response_out );\r
+ cvReleaseMat( &var_idx_out );\r
+ cvReleaseMat( &var_types_out );\r
+\r
+ free_train_test_idx();\r
+ \r
+ total_class_count = 0;\r
+\r
+ response_idx = -1;\r
+\r
+ train_sample_count = -1;\r
+}\r
+\r
+int CvMLData :: read_csv(const char* filename)\r
+{\r
+ const int M = 10000;\r
+ const char str_delimiter[3] = { ' ', delimiter, '\0' };\r
+ FILE* file = 0;\r
+ CvMemStorage* storage;\r
+ CvSeq* seq;\r
+ char *buf;\r
+ char *ptr;\r
+ float* el_ptr;\r
+ CvSeqReader reader;\r
+ int cols_count = 0; \r
+ uchar *var_types_ptr = 0;\r
+\r
+ clear();\r
+\r
+ file = fopen( filename, "rt" );\r
+ \r
+ if( !file )\r
+ return -1;\r
+\r
+ // read the first line and determine the number of variables\r
+ buf = new char[M];\r
+ if( !fgets( buf, M, file ))\r
+ {\r
+ fclose(file);\r
+ return 1;\r
+ }\r
+ for( ptr = buf; *ptr != '\0'; ptr++ )\r
+ cols_count += (*ptr == delimiter);\r
+\r
+ if ( cols_count == 0)\r
+ {\r
+ fclose(file);\r
+ return 1;\r
+ }\r
+ cols_count++;\r
+\r
+ // create temporary memory storage to store the whole database\r
+ el_ptr = new float[cols_count];\r
+ storage = cvCreateMemStorage();\r
+ seq = cvCreateSeq( 0, sizeof(*seq), cols_count*sizeof(float), storage );\r
+\r
+ var_types = cvCreateMat( 1, cols_count, CV_8U );\r
+ cvZero( var_types );\r
+ var_types_ptr = var_types->data.ptr;\r
+\r
+ for(;;)\r
+ {\r
+ char *token = NULL;\r
+ int type;\r
+ token = strtok(buf, str_delimiter);\r
+ if (!token) \r
+ {\r
+ fclose(file);\r
+ return 1;\r
+ }\r
+ for (int i = 0; i < cols_count-1; i++)\r
+ {\r
+ \r
+ str_to_flt_elem( token, el_ptr[i], type);\r
+ var_types_ptr[i] |= type;\r
+ token = strtok(NULL, str_delimiter);\r
+ if (!token)\r
+ {\r
+ fclose(file);\r
+ return 1;\r
+ }\r
+ }\r
+ str_to_flt_elem( token, el_ptr[cols_count-1], type);\r
+ var_types_ptr[cols_count-1] |= type;\r
+ cvSeqPush( seq, el_ptr );\r
+ if( !fgets( buf, M, file ) || !strchr( buf, delimiter ) )\r
+ break;\r
+ }\r
+ fclose(file);\r
+\r
+ values = cvCreateMat( seq->total, cols_count, CV_32FC1 );\r
+ missing = cvCreateMat( seq->total, cols_count, CV_8U );\r
+ var_idx_mask = cvCreateMat( 1, values->cols, CV_8UC1 );\r
+ cvSet( var_idx_mask, cvRealScalar(1) );\r
+ train_sample_count = seq->total;\r
+\r
+ cvStartReadSeq( seq, &reader );\r
+ for(int i = 0; i < seq->total; i++ )\r
+ {\r
+ const float* sdata = (float*)reader.ptr;\r
+ float* ddata = values->data.fl + cols_count*i;\r
+ uchar* dm = missing->data.ptr + cols_count*i;\r
+\r
+ for( int j = 0; j < cols_count; j++ )\r
+ {\r
+ ddata[j] = sdata[j];\r
+ dm[j] = ( fabs( MISS_VAL - sdata[j] ) <= FLT_EPSILON );\r
+ }\r
+ CV_NEXT_SEQ_ELEM( seq->elem_size, reader );\r
+ }\r
+\r
+ if ( cvNorm( missing, 0, CV_L1 ) <= FLT_EPSILON )\r
+ cvReleaseMat( &missing );\r
+\r
+ cvReleaseMemStorage( &storage );\r
+ delete []el_ptr;\r
+ delete []buf;\r
+ return 0;\r
+}\r
+\r
+void CvMLData :: str_to_flt_elem( const char* token, float& flt_elem, int& type)\r
+{\r
+ \r
+ char* stopstring = NULL;\r
+ flt_elem = (float)strtod( token, &stopstring );\r
+ assert( stopstring );\r
+ type = CV_VAR_ORDERED;\r
+ if ( *stopstring == miss_ch && strlen(stopstring) == 1 ) // missed value\r
+ {\r
+ flt_elem = MISS_VAL;\r
+ type = CV_VAR_MISS;\r
+ }\r
+ else\r
+ {\r
+ if ( (*stopstring != 0) && (*stopstring != '\n') && (strcmp(stopstring, "\r\n") != 0) ) // class label\r
+ {\r
+ int idx = (*class_map)[token];\r
+ if ( idx == 0)\r
+ {\r
+ total_class_count++;\r
+ idx = total_class_count;\r
+ (*class_map)[token] = idx;\r
+ }\r
+ flt_elem = (float)idx;\r
+ type = CV_VAR_CATEGORICAL;\r
+ }\r
+ }\r
+}\r
+\r
+void CvMLData :: set_delimiter(char ch)\r
+{\r
+ CV_FUNCNAME( "CvMLData :: set_delimited" );\r
+ __BEGIN__;\r
+\r
+ if (ch == miss_ch /*|| ch == flt_separator*/)\r
+ CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different");\r
+ \r
+ delimiter = ch;\r
+\r
+ __END__;\r
+}\r
+\r
+void CvMLData :: set_miss_ch(char ch)\r
+{\r
+ CV_FUNCNAME( "CvMLData :: set_miss_ch" );\r
+ __BEGIN__;\r
+\r
+ if (ch == delimiter/* || ch == flt_separator*/)\r
+ CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different");\r
+ \r
+ miss_ch = ch;\r
+\r
+ __END__;\r
+}\r
+\r
+void CvMLData :: set_response_idx( int idx )\r
+{\r
+ CV_FUNCNAME( "CvMLData :: set_response_idx" );\r
+ __BEGIN__;\r
+\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+\r
+ if ( idx >= values->cols)\r
+ CV_ERROR( CV_StsBadArg, "idx value is not correct" );\r
+\r
+ if ( response_idx >= 0 )\r
+ chahge_var_idx( response_idx, true );\r
+\r
+ if ( idx >= 0 )\r
+ {\r
+ response_idx = idx;\r
+ chahge_var_idx( response_idx, false );\r
+ }\r
+\r
+ __END__; \r
+}\r
+\r
+void CvMLData :: change_var_type( int var_idx, int type )\r
+{\r
+ CV_FUNCNAME( "CvMLData :: change_var_type" );\r
+ __BEGIN__;\r
+ \r
+ int var_count = 0;\r
+\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+ \r
+ var_count = values->cols;\r
+\r
+ if ( var_idx < 0 || var_idx >= var_count)\r
+ CV_ERROR( CV_StsBadArg, "var_idx is not correct" );\r
+\r
+ if ( type != CV_VAR_ORDERED && type != CV_VAR_CATEGORICAL)\r
+ CV_ERROR( CV_StsBadArg, "type is not correct" );\r
+\r
+ assert( var_types ); \r
+ if ( var_types->data.ptr[var_idx] == CV_VAR_CATEGORICAL && type == CV_VAR_ORDERED)\r
+ CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );\r
+ var_types->data.ptr[var_idx] = (uchar)type;\r
+\r
+ __END__;\r
+\r
+ return;\r
+}\r
+\r
+void CvMLData :: set_var_types( const char* str )\r
+{\r
+ CV_FUNCNAME( "CvMLData :: set_var_types" );\r
+ __BEGIN__;\r
+\r
+ const char* ord = 0, *cat = 0;\r
+ int var_count = 0, set_var_type_count = 0;\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+\r
+ var_count = values->cols;\r
+\r
+ assert( var_types );\r
+ \r
+ ord = strstr( str, "ord" );\r
+ cat = strstr( str, "cat" ); \r
+ if ( !ord && !cat )\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ \r
+ if ( !ord && strlen(cat) == 3 ) // str == "cat"\r
+ {\r
+ cvSet( var_types, cvScalarAll(CV_VAR_CATEGORICAL) );\r
+ return;\r
+ }\r
+\r
+ if ( !cat && strlen(ord) == 3 ) // str == "ord"\r
+ {\r
+ cvSet( var_types, cvScalarAll(CV_VAR_ORDERED) );\r
+ return;\r
+ }\r
+\r
+ if ( ord ) // parse ord str\r
+ {\r
+ char* stopstring = NULL; \r
+ if ( ord[3] != '[')\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ \r
+ ord += 4; // pass "ord["\r
+ do\r
+ {\r
+ int b1 = (int)strtod( ord, &stopstring );\r
+ if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') )\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ ord = stopstring + 1;\r
+ if ( (stopstring[0] == ',') || (stopstring[0] == ']'))\r
+ {\r
+ if ( var_types->data.ptr[b1] == CV_VAR_CATEGORICAL)\r
+ CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );\r
+ var_types->data.ptr[b1] = CV_VAR_ORDERED;\r
+ set_var_type_count++;\r
+ }\r
+ else \r
+ {\r
+ if ( stopstring[0] == '-') \r
+ {\r
+ int b2 = (int)strtod( ord, &stopstring);\r
+ if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') )\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" ); \r
+ ord = stopstring + 1;\r
+ for (int i = b1; i <= b2; i++)\r
+ {\r
+ if ( var_types->data.ptr[i] == CV_VAR_CATEGORICAL)\r
+ CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" ); \r
+ var_types->data.ptr[i] = CV_VAR_ORDERED;\r
+ }\r
+ set_var_type_count += b2 - b1 + 1;\r
+ }\r
+ else\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+\r
+ }\r
+ }\r
+ while (*stopstring != ']');\r
+\r
+ if ( stopstring[1] != '\0' && stopstring[1] != ',')\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ } \r
+\r
+ if ( cat ) // parse cat str\r
+ {\r
+ char* stopstring = NULL; \r
+ if ( cat[3] != '[')\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ \r
+ cat += 4; // pass "cat["\r
+ do\r
+ {\r
+ int b1 = (int)strtod( cat, &stopstring );\r
+ if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') )\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ cat = stopstring + 1;\r
+ if ( (stopstring[0] == ',') || (stopstring[0] == ']'))\r
+ {\r
+ var_types->data.ptr[b1] = CV_VAR_CATEGORICAL;\r
+ set_var_type_count++;\r
+ }\r
+ else \r
+ {\r
+ if ( stopstring[0] == '-') \r
+ {\r
+ int b2 = (int)strtod( cat, &stopstring);\r
+ if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') )\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" ); \r
+ cat = stopstring + 1;\r
+ for (int i = b1; i <= b2; i++)\r
+ var_types->data.ptr[i] = CV_VAR_CATEGORICAL;\r
+ set_var_type_count += b2 - b1 + 1;\r
+ }\r
+ else\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+\r
+ }\r
+ }\r
+ while (*stopstring != ']');\r
+\r
+ if ( stopstring[1] != '\0' && stopstring[1] != ',')\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+ } \r
+\r
+ if (set_var_type_count != var_count)\r
+ CV_ERROR( CV_StsBadArg, "types string is not correct" );\r
+\r
+ __END__;\r
+}\r
+\r
+const CvMat* CvMLData :: get_var_types()\r
+{\r
+ CV_FUNCNAME( "CvMLData :: get_var_types" );\r
+ __BEGIN__;\r
+\r
+ uchar *var_types_out_ptr = 0;\r
+ int avcount, vt_size;\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+\r
+ assert( var_idx_mask );\r
+\r
+ avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) );\r
+ vt_size = avcount + (response_idx >= 0);\r
+\r
+ if ( avcount == values->cols || (avcount == values->cols-1 && response_idx == values->cols-1) )\r
+ return var_types;\r
+\r
+ if ( !var_types_out || ( var_types_out && var_types_out->cols != vt_size ) ) \r
+ {\r
+ cvReleaseMat( &var_types_out );\r
+ var_types_out = cvCreateMat( 1, vt_size, CV_8UC1 );\r
+ }\r
+\r
+ var_types_out_ptr = var_types_out->data.ptr;\r
+ for( int i = 0; i < var_types->cols; i++)\r
+ {\r
+ if (i == response_idx || !var_idx_mask->data.ptr[i]) continue;\r
+ *var_types_out_ptr = var_types->data.ptr[i];\r
+ var_types_out_ptr++;\r
+ }\r
+ if ( response_idx >= 0 )\r
+ *var_types_out_ptr = var_types->data.ptr[response_idx];\r
+\r
+ __END__;\r
+\r
+ return var_types_out;\r
+}\r
+\r
+const CvMat* CvMLData :: get_responses()\r
+{\r
+ CV_FUNCNAME( "CvMLData :: get_responses_ptr" );\r
+ __BEGIN__;\r
+\r
+ int var_count = 0;\r
+\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+ var_count = values->cols;\r
+ \r
+ if ( response_idx < 0 || response_idx >= var_count )\r
+ return 0;\r
+ if ( !response_out )\r
+ response_out = cvCreateMatHeader( values->rows, 1, CV_32FC1 );\r
+ else\r
+ cvInitMatHeader( response_out, values->rows, 1, CV_32FC1);\r
+ cvGetCol( values, response_out, response_idx );\r
+\r
+ __END__;\r
+\r
+ return response_out;\r
+}\r
+\r
+void CvMLData :: set_train_test_split( const CvTrainTestSplit * spl)\r
+{\r
+ CV_FUNCNAME( "CvMLData :: set_division" );\r
+ __BEGIN__;\r
+\r
+ int sample_count = 0;\r
+\r
+ if ( spl->class_part )\r
+ CV_ERROR( CV_StsBadArg, "this division type is not supported yet" );\r
+ \r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+\r
+ sample_count = values->rows;\r
+ \r
+ float train_sample_portion;\r
+\r
+ if (spl->train_sample_part_mode == CV_COUNT)\r
+ {\r
+ train_sample_count = spl->train_sample_part.count;\r
+ if (train_sample_count > sample_count)\r
+ CV_ERROR( CV_StsBadArg, "train samples count is not correct" );\r
+ train_sample_count = train_sample_count<=0 ? sample_count : train_sample_count;\r
+ }\r
+ else // dtype.train_sample_part_mode == CV_PORTION\r
+ {\r
+ train_sample_portion = spl->train_sample_part.portion;\r
+ if ( train_sample_portion > 1)\r
+ CV_ERROR( CV_StsBadArg, "train samples count is not correct" );\r
+ train_sample_portion = train_sample_portion <= FLT_EPSILON || \r
+ 1 - train_sample_portion <= FLT_EPSILON ? 1 : train_sample_portion;\r
+ train_sample_count = cvFloor( train_sample_portion * sample_count );\r
+ }\r
+\r
+ if ( train_sample_count == sample_count )\r
+ {\r
+ free_train_test_idx();\r
+ return;\r
+ }\r
+\r
+ if ( train_sample_idx && train_sample_idx->cols != train_sample_count )\r
+ free_train_test_idx();\r
+\r
+ if ( !sample_idx)\r
+ {\r
+ int test_sample_count = sample_count- train_sample_count;\r
+ sample_idx = (int*)cvAlloc( sample_count * sizeof(sample_idx[0]) );\r
+ for (int i = 0; i < sample_count; i++ )\r
+ sample_idx[i] = i;\r
+ train_sample_idx = cvCreateMatHeader( 1, train_sample_count, CV_32SC1 );\r
+ test_sample_idx = cvCreateMatHeader( 1, test_sample_count, CV_32SC1 );\r
+ *train_sample_idx = cvMat( 1, train_sample_count, CV_32SC1, &sample_idx[0] );\r
+ *test_sample_idx = cvMat( 1, test_sample_count, CV_32SC1, &sample_idx[train_sample_count] );\r
+ }\r
+ \r
+ mix = spl->mix;\r
+ if ( mix )\r
+ mix_train_and_test_idx();\r
+ \r
+ __END__;\r
+}\r
+\r
+void CvMLData :: mix_train_and_test_idx()\r
+{\r
+ if ( !values || !sample_idx) return;\r
+\r
+ if ( train_sample_count > 0 && train_sample_count < values->rows )\r
+ {\r
+ int n = values->rows;\r
+ for (int i = 0; i < n; i++)\r
+ {\r
+ int a = cvRandInt( &rng ) % n;\r
+ int b = cvRandInt( &rng ) % n;\r
+ int t;\r
+ CV_SWAP( sample_idx[a], sample_idx[b], t );\r
+ }\r
+ }\r
+}\r
+\r
+const CvMat* CvMLData :: get_var_idx()\r
+{\r
+ CV_FUNCNAME( "CvMLData :: get_var_idx" );\r
+ __BEGIN__;\r
+\r
+ int avcount = 0;\r
+\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+\r
+ assert( var_idx_mask );\r
+ \r
+ avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) );\r
+ int* vidx;\r
+\r
+ if ( avcount == values->cols )\r
+ return 0;\r
+ \r
+ if ( !var_idx_out || ( var_idx_out && var_idx_out->cols != avcount ) ) \r
+ {\r
+ cvReleaseMat( &var_idx_out );\r
+ var_idx_out = cvCreateMat( 1, avcount, CV_32SC1);\r
+ if ( response_idx >=0 )\r
+ var_idx_mask->data.ptr[response_idx] = 0;\r
+ }\r
+\r
+ vidx = var_idx_out->data.i;\r
+ \r
+ for(int i = 0; i < var_idx_mask->cols; i++)\r
+ if ( var_idx_mask->data.ptr[i] )\r
+ { \r
+ *vidx = i;\r
+ vidx++;\r
+ }\r
+\r
+ __END__;\r
+\r
+ return var_idx_out;\r
+}\r
+\r
+void CvMLData :: chahge_var_idx( int vi, bool state )\r
+{\r
+ CV_FUNCNAME( "CvMLData :: get_responses_ptr" );\r
+ __BEGIN__;\r
+\r
+ int var_count = 0;\r
+\r
+ if ( !values )\r
+ CV_ERROR( CV_StsInternal, "data is empty" );\r
+\r
+ var_count = values->cols;\r
+\r
+ if ( vi < 0 || vi >= var_count)\r
+ CV_ERROR( CV_StsBadArg, "variable index is not correct" );\r
+\r
+ assert( var_idx_mask ); \r
+ var_idx_mask->data.ptr[vi] = state;\r
+\r
+ __END__;\r
+}\r
+\r
+/* End of file. */\r