Update to 2.0.0 tree from current Fremantle build
[opencv] / src / ml / mldata.cpp
diff --git a/src/ml/mldata.cpp b/src/ml/mldata.cpp
new file mode 100644 (file)
index 0000000..3a9fadf
--- /dev/null
@@ -0,0 +1,667 @@
+/*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