16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_ml.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatModel::CvStatModel()
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default_model_name = "my_stat_model";
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatModel::~CvStatModel()
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    clear();
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvStatModel::clear()
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvStatModel::save( const char* filename, const char* name )
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvFileStorage* fs = 0;
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "CvStatModel::save" );
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_WRITE ));
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !fs )
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" );
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    write( fs, name ? name : default_model_name );
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseFileStorage( &fs );
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvStatModel::load( const char* filename, const char* name )
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvFileStorage* fs = 0;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "CvStatModel::load" );
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvFileNode* model_node = 0;
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ ));
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !fs )
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( name )
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        model_node = cvGetFileNodeByName( fs, 0, name );
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvFileNode* root = cvGetRootFileNode( fs );
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( root->data.seq->total > 0 )
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            model_node = (CvFileNode*)cvGetSeqElem( root->data.seq, 0 );
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    read( fs, model_node );
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseFileStorage( &fs );
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvStatModel::write( CvFileStorage*, const char* )
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" );
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvStatModel::read( CvFileStorage*, CvFileNode* )
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" );
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calculates upper triangular matrix S, where A is a symmetrical matrix A=S'*S */
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void cvChol( CvMat* A, CvMat* S )
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dim = A->rows;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float sum;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < dim; i++ )
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < i; j++ )
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_MAT_ELEM(*S, float, i, j) = 0;
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sum = 0;
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( k = 0; k < i; k++ )
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sum += CV_MAT_ELEM(*S, float, k, i) * CV_MAT_ELEM(*S, float, k, i);
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_ELEM(*S, float, i, i) = (float)sqrt(CV_MAT_ELEM(*A, float, i, i) - sum);
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = i + 1; j < dim; j++ )
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sum = 0;
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < i; k++ )
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += CV_MAT_ELEM(*S, float, k, i) * CV_MAT_ELEM(*S, float, k, j);
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_MAT_ELEM(*S, float, i, j) =
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (CV_MAT_ELEM(*A, float, i, j) - sum) / CV_MAT_ELEM(*S, float, i, i);
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Generates <sample> from multivariate normal distribution, where <mean> - is an
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   average row vector, <cov> - symmetric covariation matrix */
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void cvRandMVNormal( CvMat* mean, CvMat* cov, CvMat* sample, CvRNG* rng )
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dim = sample->cols;
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int amount = sample->rows;
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRNG state = rng ? *rng : cvRNG(time(0));
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRandArr(&state, sample, CV_RAND_NORMAL, cvScalarAll(0), cvScalarAll(1) );
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* utmat = cvCreateMat(dim, dim, sample->type);
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* vect = cvCreateMatHeader(1, dim, sample->type);
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvChol(cov, utmat);
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < amount; i++ )
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetRow(sample, vect, i);
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvMatMulAdd(vect, utmat, mean, vect);
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat(&vect);
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat(&utmat);
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Generates <sample> of <amount> points from a discrete variate xi,
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   where Pr{xi = k} == probs[k], 0 < k < len - 1. */
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void cvRandSeries( float probs[], int len, int sample[], int amount )
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* univals = cvCreateMat(1, amount, CV_32FC1);
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float* knots = (float*)cvAlloc( len * sizeof(float) );
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRNG state = cvRNG(-1);
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRandArr(&state, univals, CV_RAND_UNI, cvScalarAll(0), cvScalarAll(1) );
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    knots[0] = probs[0];
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 1; i < len; i++ )
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        knots[i] = knots[i - 1] + probs[i];
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < amount; i++ )
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < len; j++ )
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if ( CV_MAT_ELEM(*univals, float, 0, i) <= knots[j] )
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sample[i] = j;
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree(&knots);
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Generates <sample> from gaussian mixture distribution */
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void cvRandGaussMixture( CvMat* means[],
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 CvMat* covs[],
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 float weights[],
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 int clsnum,
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 CvMat* sample,
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 CvMat* sampClasses )
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dim = sample->cols;
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int amount = sample->rows;
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, clss;
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* sample_clsnum = (int*)cvAlloc( amount * sizeof(int) );
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat** utmats = (CvMat**)cvAlloc( clsnum * sizeof(CvMat*) );
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* vect = cvCreateMatHeader(1, dim, CV_32FC1);
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* classes;
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sampClasses )
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        classes = sampClasses;
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        classes = cvCreateMat(1, amount, CV_32FC1);
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRNG state = cvRNG(-1);
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRandArr(&state, sample, CV_RAND_NORMAL, cvScalarAll(0), cvScalarAll(1));
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRandSeries(weights, clsnum, sample_clsnum, amount);
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < clsnum; i++ )
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        utmats[i] = cvCreateMat(dim, dim, CV_32FC1);
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvChol(covs[i], utmats[i]);
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < amount; i++ )
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_ELEM(*classes, float, 0, i) = (float)sample_clsnum[i];
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetRow(sample, vect, i);
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        clss = sample_clsnum[i];
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvMatMulAdd(vect, utmats[clss], means[clss], vect);
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !sampClasses )
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMat(&classes);
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < clsnum; i++ )
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMat(&utmats[i]);
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree(&utmats);
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree(&sample_clsnum);
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat(&vect);
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMat* icvGenerateRandomClusterCenters ( int seed, const CvMat* data,
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                         int num_of_clusters, CvMat* _centers )
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* centers = _centers;
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("icvGenerateRandomClusterCenters");
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRNG rng;
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat data_comp, centers_comp;
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint minLoc, maxLoc; // Not used, just for function "cvMinMaxLoc"
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double minVal, maxVal;
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dim = data ? data->cols : 0;
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ICV_IS_MAT_OF_TYPE(data, CV_32FC1) )
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_32FC1) )
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR(CV_StsBadArg,"");
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( !_centers )
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_32FC1));
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( ICV_IS_MAT_OF_TYPE(data, CV_64FC1) )
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( _centers && !ICV_IS_MAT_OF_TYPE (_centers, CV_64FC1) )
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR(CV_StsBadArg,"");
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( !_centers )
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL(centers = cvCreateMat (num_of_clusters, dim, CV_64FC1));
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR (CV_StsBadArg,"");
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( num_of_clusters < 1 )
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR (CV_StsBadArg,"");
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rng = cvRNG(seed);
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < dim; i++)
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL(cvGetCol (data, &data_comp, i));
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL(cvMinMaxLoc (&data_comp, &minVal, &maxVal, &minLoc, &maxLoc));
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL(cvGetCol (centers, &centers_comp, i));
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL(cvRandArr (&rng, &centers_comp, CV_RAND_UNI, cvScalarAll(minVal), cvScalarAll(maxVal)));
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (cvGetErrStatus () < 0) || (centers != _centers) )
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMat (&centers);
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return _centers ? _centers : centers;
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // end of icvGenerateRandomClusterCenters
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By S. Dilman - begin -
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_RAND_MAX    4294967296 // == 2^32
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void cvRandRoundUni (CvMat* center,
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             float radius_small,
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             float radius_large,
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             CvMat* desired_matrix,
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             CvRNG* rng_state_ptr)
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float rad, norm, coefficient;
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dim, size, i, j;
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat *cov, sample;
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRNG rng_local;
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("cvRandRoundUni");
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rng_local = *rng_state_ptr;
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT ((radius_small >= 0) &&
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               (radius_large > 0) &&
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               (radius_small <= radius_large));
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT (center && desired_matrix && rng_state_ptr);
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT (center->rows == 1);
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT (center->cols == desired_matrix->cols);
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dim = desired_matrix->cols;
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size = desired_matrix->rows;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cov = cvCreateMat (dim, dim, CV_32FC1);
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSetIdentity (cov);
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRandMVNormal (center, cov, desired_matrix, &rng_local);
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < size; i++)
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rad = (float)(cvRandReal(&rng_local)*(radius_large - radius_small) + radius_small);
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetRow (desired_matrix, &sample, i);
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        norm = (float) cvNorm (&sample, 0, CV_L2);
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        coefficient = rad / norm;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (j = 0; j < dim; j++)
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             CV_MAT_ELEM (sample, float, 0, j) *= coefficient;
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By S. Dilman - end -
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Aij <- Aji for i > j if lower_to_upper != 0
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              for i < j if lower_to_upper = 0 */
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvCompleteSymm( CvMat* matrix, int lower_to_upper )
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("cvCompleteSymm");
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int rows, cols;
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step;
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(matrix))
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR(CV_StsBadArg, "Invalid matrix argument");
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rows = matrix->rows;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cols = matrix->cols;
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step = matrix->step / CV_ELEM_SIZE(matrix->type);
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch(CV_MAT_TYPE(matrix->type))
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_32FC1:
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* dst = matrix->data.fl;
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !lower_to_upper )
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 1; i < rows; i++ )
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const float* src = (const float*)(matrix->data.fl + i);
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst += step;
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < i; j++, src += step )
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = src[0];
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < rows-1; i++, dst += step )
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const float* src = (const float*)(matrix->data.fl + (i+1)*step + i);
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = i+1; j < cols; j++, src += step )
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = src[0];
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_64FC1:
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double* dst = matrix->data.db;
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !lower_to_upper )
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 1; i < rows; i++ )
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const double* src = (const double*)(matrix->data.db + i);
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst += step;
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < i; j++, src += step )
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = src[0];
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < rows-1; i++, dst += step )
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const double* src = (const double*)(matrix->data.db + (i+1)*step + i);
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = i+1; j < cols; j++, src += step )
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = src[0];
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int CV_CDECL
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCmpIntegers( const void* a, const void* b )
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return *(const int*)a - *(const int*)b;
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int CV_CDECL
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCmpIntegersPtr( const void* _a, const void* _b )
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int a = **(const int**)_a;
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int b = **(const int**)_b;
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return (a < b ? -1 : 0)|(a > b);
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int icvCmpSparseVecElems( const void* a, const void* b )
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ((CvSparseVecElem32f*)a)->idx - ((CvSparseVecElem32f*)b)->idx;
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMat*
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_duplicates )
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* idx = 0;
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPreprocessIndexArray" );
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, idx_total, idx_selected = 0, step, type, prev = INT_MIN, is_sorted = 1;
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* srcb = 0;
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* srci = 0;
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* dsti;
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(idx_arr) )
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Invalid index array" );
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( idx_arr->rows != 1 && idx_arr->cols != 1 )
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "the index array must be 1-dimensional" );
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    idx_total = idx_arr->rows + idx_arr->cols - 1;
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcb = idx_arr->data.ptr;
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srci = idx_arr->data.i;
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(idx_arr->type);
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step = CV_IS_MAT_CONT(idx_arr->type) ? 1 : idx_arr->step/CV_ELEM_SIZE(type);
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch( type )
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_8UC1:
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_8SC1:
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // idx_arr is array of 1's and 0's -
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // i.e. it is a mask of the selected components
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( idx_total != data_arr_size )
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes,
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "Component mask should contain as many elements as the total number of input variables" );
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < idx_total; i++ )
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            idx_selected += srcb[i*step] != 0;
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( idx_selected == 0 )
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsOutOfRange, "No components/input_variables is selected!" );
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( idx_selected == idx_total )
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            EXIT;
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_32SC1:
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // idx_arr is array of integer indices of selected components
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( idx_total > data_arr_size )
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsOutOfRange,
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "index array may not contain more elements than the total number of input variables" );
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        idx_selected = idx_total;
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // check if sorted already
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < idx_total; i++ )
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int val = srci[i*step];
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( val >= prev )
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                is_sorted = 0;
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = val;
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported index array data type "
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           "(it should be 8uC1, 8sC1 or 32sC1)" );
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( idx = cvCreateMat( 1, idx_selected, CV_32SC1 ));
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsti = idx->data.i;
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( type < CV_32SC1 )
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < idx_total; i++ )
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( srcb[i*step] )
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *dsti++ = i;
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < idx_total; i++ )
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsti[i] = srci[i*step];
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !is_sorted )
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            qsort( dsti, idx_total, sizeof(dsti[0]), icvCmpIntegers );
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dsti[0] < 0 || dsti[idx_total-1] >= data_arr_size )
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsOutOfRange, "the index array elements are out of range" );
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( check_for_duplicates )
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 1; i < idx_total; i++ )
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( dsti[i] <= dsti[i-1] )
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "There are duplicated index array elements" );
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvGetErrStatus() < 0 )
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMat( &idx );
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return idx;
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMat*
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPreprocessVarType( const CvMat* var_type, const CvMat* var_idx,
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int var_all, int* response_type )
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* out_var_type = 0;
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPreprocessVarType" );
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( response_type )
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *response_type = -1;
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, tm_size, tm_step;
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* map = 0;
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const uchar* src;
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* dst;
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int var_count = var_all;
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(var_type) )
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( var_type ? CV_StsBadArg : CV_StsNullPtr, "Invalid or absent var_type array" );
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( var_type->rows != 1 && var_type->cols != 1 )
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "var_type array must be 1-dimensional" );
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MASK_ARR(var_type))
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "type mask must be 8uC1 or 8sC1 array" );
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tm_size = var_type->rows + var_type->cols - 1;
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tm_step = var_type->step ? var_type->step/CV_ELEM_SIZE(var_type->type) : 1;
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( /*tm_size != var_count &&*/ tm_size != var_count + 1 )
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg,
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "type mask must be of <input var count> + 1 size" );
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( response_type && tm_size > var_count )
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *response_type = var_type->data.ptr[var_count*tm_step] != 0;
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( var_idx )
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(var_idx) || CV_MAT_TYPE(var_idx->type) != CV_32SC1 ||
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            var_idx->rows != 1 && var_idx->cols != 1 || !CV_IS_MAT_CONT(var_idx->type) )
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "var index array should be continuous 1-dimensional integer vector" );
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( var_idx->rows + var_idx->cols - 1 > var_count )
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadSize, "var index array is too large" );
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        map = var_idx->data.i;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        var_count = var_idx->rows + var_idx->cols - 1;
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( out_var_type = cvCreateMat( 1, var_count, CV_8UC1 ));
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src = var_type->data.ptr;
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst = out_var_type->data.ptr;
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < var_count; i++ )
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int idx = map ? map[i] : i;
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( (unsigned)idx < (unsigned)tm_size );
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[i] = (uchar)(src[idx*tm_step] != 0);
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return out_var_type;
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMat*
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPreprocessOrderedResponses( const CvMat* responses, const CvMat* sample_idx, int sample_all )
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* out_responses = 0;
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPreprocessOrderedResponses" );
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, r_type, r_step;
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* map = 0;
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float* dst;
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int sample_count = sample_all;
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(responses) )
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Invalid response array" );
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( responses->rows != 1 && responses->cols != 1 )
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" );
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( responses->rows + responses->cols - 1 != sample_count )
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes,
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Response array must contain as many elements as the total number of samples" );
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r_type = CV_MAT_TYPE(responses->type);
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( r_type != CV_32FC1 && r_type != CV_32SC1 )
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" );
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r_step = responses->step ? responses->step / CV_ELEM_SIZE(responses->type) : 1;
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( r_type == CV_32FC1 && CV_IS_MAT_CONT(responses->type) && !sample_idx )
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        out_responses = (CvMat*)responses;
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_idx )
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 ||
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sample_idx->rows != 1 && sample_idx->cols != 1 || !CV_IS_MAT_CONT(sample_idx->type) )
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" );
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sample_idx->rows + sample_idx->cols - 1 > sample_count )
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadSize, "sample index array is too large" );
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        map = sample_idx->data.i;
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sample_count = sample_idx->rows + sample_idx->cols - 1;
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32FC1 ));
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst = out_responses->data.fl;
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( r_type == CV_32FC1 )
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const float* src = responses->data.fl;
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < sample_count; i++ )
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int idx = map ? map[i] : i;
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( (unsigned)idx < (unsigned)sample_all );
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = src[idx*r_step];
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const int* src = responses->data.i;
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < sample_count; i++ )
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int idx = map ? map[i] : i;
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( (unsigned)idx < (unsigned)sample_all );
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (float)src[idx*r_step];
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return out_responses;
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMat*
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPreprocessCategoricalResponses( const CvMat* responses,
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* sample_idx, int sample_all,
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat** out_response_map, CvMat** class_counts )
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* out_responses = 0;
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int** response_ptr = 0;
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPreprocessCategoricalResponses" );
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_response_map )
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_response_map = 0;
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( class_counts )
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *class_counts = 0;
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, r_type, r_step;
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cls_count = 1, prev_cls, prev_i;
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* map = 0;
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* srci;
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* srcfl;
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* dst;
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* cls_map;
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* cls_counts = 0;
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int sample_count = sample_all;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(responses) )
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Invalid response array" );
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( responses->rows != 1 && responses->cols != 1 )
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "Response array must be 1-dimensional" );
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( responses->rows + responses->cols - 1 != sample_count )
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes,
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Response array must contain as many elements as the total number of samples" );
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r_type = CV_MAT_TYPE(responses->type);
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( r_type != CV_32FC1 && r_type != CV_32SC1 )
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported response type" );
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r_step = responses->step ? responses->step / CV_ELEM_SIZE(responses->type) : 1;
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_idx )
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(sample_idx) || CV_MAT_TYPE(sample_idx->type) != CV_32SC1 ||
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sample_idx->rows != 1 && sample_idx->cols != 1 || !CV_IS_MAT_CONT(sample_idx->type) )
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "sample index array should be continuous 1-dimensional integer vector" );
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sample_idx->rows + sample_idx->cols - 1 > sample_count )
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadSize, "sample index array is too large" );
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        map = sample_idx->data.i;
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sample_count = sample_idx->rows + sample_idx->cols - 1;
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( out_responses = cvCreateMat( 1, sample_count, CV_32SC1 ));
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !out_response_map )
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "out_response_map pointer is NULL" );
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( response_ptr = (int**)cvAlloc( sample_count*sizeof(response_ptr[0])));
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srci = responses->data.i;
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcfl = responses->data.fl;
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst = out_responses->data.i;
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < sample_count; i++ )
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int idx = map ? map[i] : i;
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( (unsigned)idx < (unsigned)sample_all );
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( r_type == CV_32SC1 )
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = srci[idx*r_step];
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float rf = srcfl[idx*r_step];
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ri = cvRound(rf);
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ri != rf )
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                char buf[100];
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sprintf( buf, "response #%d is not integral", idx );
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, buf );
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = ri;
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        response_ptr[i] = dst + i;
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    qsort( response_ptr, sample_count, sizeof(int*), icvCmpIntegersPtr );
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // count the classes
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 1; i < sample_count; i++ )
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cls_count += *response_ptr[i] != *response_ptr[i-1];
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cls_count < 2 )
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "There is only a single class" );
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( *out_response_map = cvCreateMat( 1, cls_count, CV_32SC1 ));
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( class_counts )
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( *class_counts = cvCreateMat( 1, cls_count, CV_32SC1 ));
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cls_counts = (*class_counts)->data.i;
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // compact the class indices and build the map
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    prev_cls = ~*response_ptr[0];
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cls_count = -1;
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cls_map = (*out_response_map)->data.i;
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0, prev_i = -1; i < sample_count; i++ )
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int cur_cls = *response_ptr[i];
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( cur_cls != prev_cls )
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( cls_counts && cls_count >= 0 )
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cls_counts[cls_count] = i - prev_i;
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cls_map[++cls_count] = prev_cls = cur_cls;
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev_i = i;
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *response_ptr[i] = cls_count;
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cls_counts )
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cls_counts[cls_count] = i - prev_i;
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &response_ptr );
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return out_responses;
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst float**
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetTrainSamples( const CvMat* train_data, int tflag,
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const CvMat* var_idx, const CvMat* sample_idx,
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int* _var_count, int* _sample_count,
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   bool always_copy_data )
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float** samples = 0;
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvGetTrainSamples" );
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, var_count, sample_count, s_step, v_step;
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool copy_data;
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* data;
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int *s_idx, *v_idx;
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(train_data) )
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Invalid or NULL training data matrix" );
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    var_count = var_idx ? var_idx->cols + var_idx->rows - 1 :
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows;
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    sample_count = sample_idx ? sample_idx->cols + sample_idx->rows - 1 :
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   tflag == CV_ROW_SAMPLE ? train_data->rows : train_data->cols;
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _var_count )
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_var_count = var_count;
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _sample_count )
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_sample_count = sample_count;
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    copy_data = tflag != CV_ROW_SAMPLE || var_idx || always_copy_data;
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( samples = (float**)cvAlloc(sample_count*sizeof(samples[0]) +
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (copy_data ? 1 : 0)*var_count*sample_count*sizeof(samples[0][0])) );
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    data = train_data->data.fl;
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    s_step = train_data->step / sizeof(samples[0][0]);
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    v_step = 1;
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    s_idx = sample_idx ? sample_idx->data.i : 0;
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    v_idx = var_idx ? var_idx->data.i : 0;
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !copy_data )
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < sample_count; i++ )
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            samples[i] = (float*)(data + (s_idx ? s_idx[i] : i)*s_step);
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples[0] = (float*)(samples + sample_count);
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( tflag != CV_ROW_SAMPLE )
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_SWAP( s_step, v_step, i );
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < sample_count; i++ )
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float* dst = samples[i] = samples[0] + i*var_count;
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const float* src = data + (s_idx ? s_idx[i] : i)*s_step;
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !v_idx )
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < var_count; j++ )
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = src[j*v_step];
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < var_count; j++ )
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = src[v_idx[j]*v_step];
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return (const float**)samples;
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCheckTrainData( const CvMat* train_data, int tflag,
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  const CvMat* missing_mask,
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int* var_all, int* sample_all )
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCheckTrainData" );
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( var_all )
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *var_all = 0;
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_all )
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *sample_all = 0;
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // check parameter types and sizes
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(train_data) || CV_MAT_TYPE(train_data->type) != CV_32FC1 )
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "train data must be floating-point matrix" );
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( missing_mask )
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(missing_mask) || !CV_IS_MASK_ARR(missing_mask) ||
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            !CV_ARE_SIZES_EQ(train_data, missing_mask) )
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg,
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "missing value mask must be 8-bit matrix of the same size as training data" );
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( tflag != CV_ROW_SAMPLE && tflag != CV_COL_SAMPLE )
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg,
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Unknown training data layout (must be CV_ROW_SAMPLE or CV_COL_SAMPLE)" );
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( var_all )
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *var_all = tflag == CV_ROW_SAMPLE ? train_data->cols : train_data->rows;
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_all )
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *sample_all = tflag == CV_ROW_SAMPLE ? train_data->rows : train_data->cols;
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPrepareTrainData( const char* /*funcname*/,
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const CvMat* train_data, int tflag,
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const CvMat* responses, int response_type,
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const CvMat* var_idx,
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const CvMat* sample_idx,
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    bool always_copy_data,
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const float*** out_train_samples,
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int* _sample_count,
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int* _var_count,
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int* _var_all,
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvMat** out_responses,
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvMat** out_response_map,
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvMat** out_var_idx,
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvMat** out_sample_idx )
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ok = 0;
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* _var_idx = 0;
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* _sample_idx = 0;
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* _responses = 0;
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int sample_all = 0, sample_count = 0, var_all = 0, var_count = 0;
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPrepareTrainData" );
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // step 0. clear all the output pointers to ensure we do not try
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // to call free() with uninitialized pointers
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_responses )
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_responses = 0;
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_response_map )
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_response_map = 0;
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_var_idx )
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_var_idx = 0;
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_sample_idx )
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_sample_idx = 0;
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_train_samples )
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_train_samples = 0;
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _sample_count )
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_sample_count = 0;
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _var_count )
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_var_count = 0;
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _var_all )
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_var_all = 0;
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !out_train_samples )
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "output pointer to train samples is NULL" );
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvCheckTrainData( train_data, tflag, 0, &var_all, &sample_all ));
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_idx )
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( _sample_idx = cvPreprocessIndexArray( sample_idx, sample_all ));
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( var_idx )
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( _var_idx = cvPreprocessIndexArray( var_idx, var_all ));
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( responses )
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !out_responses )
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsNullPtr, "output response pointer is NULL" );
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( response_type == CV_VAR_NUMERICAL )
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( _responses = cvPreprocessOrderedResponses( responses,
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                _sample_idx, sample_all ));
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( _responses = cvPreprocessCategoricalResponses( responses,
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                _sample_idx, sample_all, out_response_map, 0 ));
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( *out_train_samples =
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetTrainSamples( train_data, tflag, _var_idx, _sample_idx,
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   &var_count, &sample_count, always_copy_data ));
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ok = 1;
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ok )
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( out_responses )
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *out_responses = _responses, _responses = 0;
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( out_var_idx )
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *out_var_idx = _var_idx, _var_idx = 0;
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( out_sample_idx )
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *out_sample_idx = _sample_idx, _sample_idx = 0;
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( _sample_count )
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *_sample_count = sample_count;
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( _var_count )
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *_var_count = var_count;
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( _var_all )
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *_var_all = var_all;
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( out_response_map )
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvReleaseMat( out_response_map );
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( out_train_samples );
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _responses != responses )
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMat( &_responses );
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &_var_idx );
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &_sample_idx );
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ok;
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvSampleResponsePair
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* sample;
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const uchar* mask;
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int response;
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int index;
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSampleResponsePair;
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_CDECL icvCmpSampleResponsePairs( const void* a, const void* b )
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ra = ((const CvSampleResponsePair*)a)->response;
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int rb = ((const CvSampleResponsePair*)b)->response;
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ia = ((const CvSampleResponsePair*)a)->index;
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ib = ((const CvSampleResponsePair*)b)->index;
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ra < rb ? -1 : ra > rb ? 1 : ia - ib;
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //return (ra > rb ? -1 : 0)|(ra < rb);
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSortSamplesByClasses( const float** samples, const CvMat* classes,
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int* class_ranges, const uchar** mask )
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSampleResponsePair* pairs = 0;
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvSortSamplesByClasses" );
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, k = 0, sample_count;
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !samples || !classes || !class_ranges )
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: some of the args are NULL pointers" );
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( classes->rows != 1 || CV_MAT_TYPE(classes->type) != CV_32SC1 )
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "classes array must be a single row of integers" );
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    sample_count = classes->cols;
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( pairs = (CvSampleResponsePair*)cvAlloc( (sample_count+1)*sizeof(pairs[0])));
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < sample_count; i++ )
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pairs[i].sample = samples[i];
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pairs[i].mask = (mask) ? (mask[i]) : 0;
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pairs[i].response = classes->data.i[i];
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pairs[i].index = i;
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( classes->data.i[i] >= 0 );
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    qsort( pairs, sample_count, sizeof(pairs[0]), icvCmpSampleResponsePairs );
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pairs[sample_count].response = -1;
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    class_ranges[0] = 0;
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < sample_count; i++ )
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples[i] = pairs[i].sample;
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (mask)
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mask[i] = pairs[i].mask;
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        classes->data.i[i] = pairs[i].response;
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( pairs[i].response != pairs[i+1].response )
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            class_ranges[++k] = i+1;
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &pairs );
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPreparePredictData( const CvArr* _sample, int dims_all,
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      const CvMat* comp_idx, int class_count,
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      const CvMat* prob, float** _row_sample,
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int as_sparse )
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float* row_sample = 0;
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* inverse_comp_idx = 0;
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPreparePredictData" );
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* sample = (const CvMat*)_sample;
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float* sample_data;
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int sample_step;
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int is_sparse = CV_IS_SPARSE_MAT(sample);
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int d, sizes[CV_MAX_DIM];
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, dims_selected;
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int vec_size;
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !is_sparse && !CV_IS_MAT(sample) )
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( !sample ? CV_StsNullPtr : CV_StsBadArg, "The sample is not a valid vector" );
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvGetElemType( sample ) != CV_32FC1 )
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "Input sample must have 32fC1 type" );
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( d = cvGetDims( sample, sizes ));
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !(is_sparse && d == 1 || !is_sparse && d == 2 && (sample->rows == 1 || sample->cols == 1)) )
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "Input sample must be 1-dimensional vector" );
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( d == 1 )
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sizes[1] = 1;
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sizes[0] + sizes[1] - 1 != dims_all )
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes,
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "The sample size is different from what has been used for training" );
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !_row_sample )
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "INTERNAL ERROR: The row_sample pointer is NULL" );
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( comp_idx && (!CV_IS_MAT(comp_idx) || comp_idx->rows != 1 ||
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_TYPE(comp_idx->type) != CV_32SC1) )
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "INTERNAL ERROR: invalid comp_idx" );
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dims_selected = comp_idx ? comp_idx->cols : dims_all;
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( prob )
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(prob) )
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "The output matrix of probabilities is invalid" );
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (prob->rows != 1 && prob->cols != 1) ||
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_MAT_TYPE(prob->type) != CV_32FC1 &&
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_MAT_TYPE(prob->type) != CV_64FC1 )
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadSize,
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "The matrix of probabilities must be 1-dimensional vector of 32fC1 type" );
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( prob->rows + prob->cols - 1 != class_count )
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes,
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "The vector of probabilities must contain as many elements as "
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "the number of classes in the training set" );
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vec_size = !as_sparse ? dims_selected*sizeof(row_sample[0]) :
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (dims_selected + 1)*sizeof(CvSparseVecElem32f);
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_IS_MAT(sample) )
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sample_data = sample->data.fl;
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sample_step = sample->step / sizeof(row_sample[0]);
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !comp_idx && sample_step <= 1 && !as_sparse )
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *_row_sample = sample_data;
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( row_sample = (float*)cvAlloc( vec_size ));
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !comp_idx )
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < dims_selected; i++ )
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row_sample[i] = sample_data[sample_step*i];
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int* comp = comp_idx->data.i;
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !sample_step )
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < dims_selected; i++ )
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row_sample[i] = sample_data[comp[i]];
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < dims_selected; i++ )
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row_sample[i] = sample_data[sample_step*comp[i]];
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *_row_sample = row_sample;
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( as_sparse )
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const float* src = (const float*)row_sample;
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSparseVecElem32f* dst = (CvSparseVecElem32f*)row_sample;
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[dims_selected].idx = -1;
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = dims_selected - 1; i >= 0; i-- )
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i].idx = i;
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i].val = src[i];
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSparseNode* node;
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSparseMatIterator mat_iterator;
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const CvSparseMat* sparse = (const CvSparseMat*)sample;
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( is_sparse );
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        node = cvInitSparseMatIterator( sparse, &mat_iterator );
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( row_sample = (float*)cvAlloc( vec_size ));
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( comp_idx )
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( inverse_comp_idx = (int*)cvAlloc( dims_all*sizeof(int) ));
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            memset( inverse_comp_idx, -1, dims_all*sizeof(int) );
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < dims_selected; i++ )
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                inverse_comp_idx[comp_idx->data.i[i]] = i;
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !as_sparse )
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            memset( row_sample, 0, vec_size );
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; node != 0; node = cvGetNextSparseNode(&mat_iterator) )
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int idx = *CV_NODE_IDX( sparse, node );
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( inverse_comp_idx )
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    idx = inverse_comp_idx[idx];
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( idx < 0 )
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        continue;
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                row_sample[idx] = *(float*)CV_NODE_VAL( sparse, node );
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSparseVecElem32f* ptr = (CvSparseVecElem32f*)row_sample;
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; node != 0; node = cvGetNextSparseNode(&mat_iterator) )
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int idx = *CV_NODE_IDX( sparse, node );
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( inverse_comp_idx )
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    idx = inverse_comp_idx[idx];
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( idx < 0 )
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        continue;
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr->idx = idx;
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr->val = *(float*)CV_NODE_VAL( sparse, node );
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr++;
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            qsort( row_sample, ptr - (CvSparseVecElem32f*)row_sample,
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   sizeof(ptr[0]), icvCmpSparseVecElems );
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr->idx = -1;
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_row_sample = row_sample;
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( inverse_comp_idx )
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &inverse_comp_idx );
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvGetErrStatus() < 0 && _row_sample )
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &row_sample );
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_row_sample = 0;
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvConvertDataToSparse( const uchar* src, int src_step, int src_type,
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        uchar* dst, int dst_step, int dst_type,
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvSize size, int* idx )
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "icvConvertDataToSparse" );
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_type = CV_MAT_TYPE(src_type);
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_type = CV_MAT_TYPE(dst_type);
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_MAT_CN(src_type) != 1 || CV_MAT_CN(dst_type) != 1 )
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "The function supports only single-channel arrays" );
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src_step == 0 )
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_step = CV_ELEM_SIZE(src_type);
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_step == 0 )
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst_step = CV_ELEM_SIZE(dst_type);
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // if there is no "idx" and if both arrays are continuous,
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // do the whole processing (copying or conversion) in a single loop
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !idx && CV_ELEM_SIZE(src_type)*size.width == src_step &&
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ELEM_SIZE(dst_type)*size.width == dst_step )
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width *= size.height;
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height = 1;
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src_type == dst_type )
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int full_width = CV_ELEM_SIZE(dst_type)*size.width;
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( full_width == sizeof(int) ) // another common case: copy int's or float's
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < size.height; i++, src += src_step )
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *(int*)(dst + dst_step*(idx ? idx[i] : i)) = *(int*)src;
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < size.height; i++, src += src_step )
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                memcpy( dst + dst_step*(idx ? idx[i] : i), src, full_width );
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( src_type == CV_32SC1 && (dst_type == CV_32FC1 || dst_type == CV_64FC1) )
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < size.height; i++, src += src_step )
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* _dst = dst + dst_step*(idx ? idx[i] : i);
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( dst_type == CV_32FC1 )
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < size.width; j++ )
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((float*)_dst)[j] = (float)((int*)src)[j];
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < size.width; j++ )
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((double*)_dst)[j] = ((int*)src)[j];
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( (src_type == CV_32FC1 || src_type == CV_64FC1) && dst_type == CV_32SC1 )
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < size.height; i++, src += src_step )
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* _dst = dst + dst_step*(idx ? idx[i] : i);
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( src_type == CV_32FC1 )
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < size.width; j++ )
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((int*)_dst)[j] = cvRound(((float*)src)[j]);
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < size.width; j++ )
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((int*)_dst)[j] = cvRound(((double*)src)[j]);
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( src_type == CV_32FC1 && dst_type == CV_64FC1 ||
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             src_type == CV_64FC1 && dst_type == CV_32FC1 )
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < size.height; i++, src += src_step )
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* _dst = dst + dst_step*(idx ? idx[i] : i);
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( src_type == CV_32FC1 )
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < size.width; j++ )
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((double*)_dst)[j] = ((float*)src)[j];
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < size.width; j++ )
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((float*)_dst)[j] = (float)((double*)src)[j];
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input and output vectors" );
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvWritebackLabels( const CvMat* labels, CvMat* dst_labels,
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const CvMat* centers, CvMat* dst_centers,
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const CvMat* probs, CvMat* dst_probs,
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const CvMat* sample_idx, int samples_all,
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const CvMat* comp_idx, int dims_all )
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvWritebackLabels" );
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int samples_selected = samples_all, dims_selected = dims_all;
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_labels && !CV_IS_MAT(dst_labels) )
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Array of output labels is not a valid matrix" );
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_centers )
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !ICV_IS_MAT_OF_TYPE(dst_centers, CV_32FC1) &&
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            !ICV_IS_MAT_OF_TYPE(dst_centers, CV_64FC1) )
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "Array of cluster centers is not a valid matrix" );
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_probs && !CV_IS_MAT(dst_probs) )
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Probability matrix is not valid" );
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_idx )
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( sample_idx->rows == 1 && CV_MAT_TYPE(sample_idx->type) == CV_32SC1 );
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples_selected = sample_idx->cols;
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( comp_idx )
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( comp_idx->rows == 1 && CV_MAT_TYPE(comp_idx->type) == CV_32SC1 );
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dims_selected = comp_idx->cols;
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_labels && (!labels || labels->data.ptr != dst_labels->data.ptr) )
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !labels )
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsNullPtr, "NULL labels" );
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( labels->rows == 1 );
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dst_labels->rows != 1 && dst_labels->cols != 1 )
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadSize, "Array of output labels should be 1d vector" );
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dst_labels->rows + dst_labels->cols - 1 != samples_all )
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes,
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "Size of vector of output labels is not equal to the total number of input samples" );
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( labels->cols == samples_selected );
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvConvertDataToSparse( labels->data.ptr, labels->step, labels->type,
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst_labels->data.ptr, dst_labels->step, dst_labels->type,
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvSize( 1, samples_selected ), sample_idx ? sample_idx->data.i : 0 ));
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_centers && (!centers || centers->data.ptr != dst_centers->data.ptr) )
14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i;
14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !centers )
14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsNullPtr, "NULL centers" );
14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( centers->rows != dst_centers->rows )
14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of rows in matrix of output centers" );
14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dst_centers->cols != dims_all )
14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes,
14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "Number of columns in matrix of output centers is "
14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "not equal to the total number of components in the input samples" );
14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( centers->cols == dims_selected );
14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < centers->rows; i++ )
14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( icvConvertDataToSparse( centers->data.ptr + i*centers->step, 0, centers->type,
14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst_centers->data.ptr + i*dst_centers->step, 0, dst_centers->type,
14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvSize( 1, dims_selected ), comp_idx ? comp_idx->data.i : 0 ));
14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_probs && (!probs || probs->data.ptr != dst_probs->data.ptr) )
14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !probs )
14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsNullPtr, "NULL probs" );
14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( probs->cols != dst_probs->cols )
14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "Invalid number of columns in output probability matrix" );
14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dst_probs->rows != samples_all )
15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes,
15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "Number of rows in output probability matrix is "
15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "not equal to the total number of input samples" );
15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( probs->rows == samples_selected );
15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvConvertDataToSparse( probs->data.ptr, probs->step, probs->type,
15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst_probs->data.ptr, dst_probs->step, dst_probs->type,
15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvSize( probs->cols, samples_selected ),
15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sample_idx ? sample_idx->data.i : 0 ));
15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0
15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvStatModelMultiPredict( const CvStatModel* stat_model,
15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         const CvArr* predict_input,
15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int flags, CvMat* predict_output,
15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvMat* probs, const CvMat* sample_idx )
15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStorage* storage = 0;
15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* sample_idx_buffer = 0;
15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSparseMat** sparse_rows = 0;
15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int samples_selected = 0;
15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvStatModelMultiPredict" );
15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int predict_output_step = 1, sample_idx_step = 1;
15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type;
15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int d, sizes[CV_MAX_DIM];
15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int tflag = flags == CV_COL_SAMPLE;
15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int samples_all, dims_all;
15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int is_sparse = CV_IS_SPARSE_MAT(predict_input);
15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat predict_input_part;
15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvArr* sample = &predict_input_part;
15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat probs_part;
15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* probs1 = probs ? &probs_part : 0;
15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_STAT_MODEL(stat_model) )
15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( !stat_model ? CV_StsNullPtr : CV_StsBadArg, "Invalid statistical model" );
15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !stat_model->predict )
15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNotImplemented, "There is no \"predict\" method" );
15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !predict_input || !predict_output )
15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "NULL input or output matrices" );
15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !is_sparse && !CV_IS_MAT(predict_input) )
15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "predict_input should be a matrix or a sparse matrix" );
15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(predict_output) )
15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "predict_output should be a matrix" );
15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = cvGetElemType( predict_input );
15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( type != CV_32FC1 ||
15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (CV_MAT_TYPE(predict_output->type) != CV_32FC1 &&
15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         CV_MAT_TYPE(predict_output->type) != CV_32SC1 ))
15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         CV_ERROR( CV_StsUnsupportedFormat, "The input or output matrix has unsupported format" );
15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( d = cvGetDims( predict_input, sizes ));
15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( d > 2 )
15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "The input matrix should be 1- or 2-dimensional" );
15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !tflag )
15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples_all = samples_selected = sizes[0];
15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dims_all = sizes[1];
15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples_all = samples_selected = sizes[1];
15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dims_all = sizes[0];
15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sample_idx )
15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(sample_idx) )
15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "Invalid sample_idx matrix" );
15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sample_idx->cols != 1 && sample_idx->rows != 1 )
15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadSize, "sample_idx must be 1-dimensional matrix" );
15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples_selected = sample_idx->rows + sample_idx->cols - 1;
15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 )
15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( samples_selected > samples_all )
15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadSize, "sample_idx is too large vector" );
15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( samples_selected != samples_all )
15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "sample_idx has incorrect size" );
15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sample_idx_step = sample_idx->step ?
15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sample_idx->step / CV_ELEM_SIZE(sample_idx->type) : 1;
16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( predict_output->rows != 1 && predict_output->cols != 1 )
16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "predict_output should be a 1-dimensional matrix" );
16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( predict_output->rows + predict_output->cols - 1 != samples_all )
16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes, "predict_output and predict_input have uncoordinated sizes" );
16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    predict_output_step = predict_output->step ?
16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        predict_output->step / CV_ELEM_SIZE(predict_output->type) : 1;
16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( probs )
16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(probs) )
16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "Invalid matrix of probabilities" );
16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( probs->rows != samples_all )
16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes,
16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "matrix of probabilities must have as many rows as the total number of samples" );
16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_TYPE(probs->type) != CV_32FC1 )
16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "matrix of probabilities must have 32fC1 type" );
16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( is_sparse )
16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSparseNode* node;
16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSparseMatIterator mat_iterator;
16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSparseMat* sparse = (CvSparseMat*)predict_input;
16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sample_idx && CV_MAT_TYPE(sample_idx->type) == CV_32SC1 )
16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( sample_idx_buffer = cvCreateMat( 1, samples_all, CV_8UC1 ));
16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvZero( sample_idx_buffer );
16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < samples_selected; i++ )
16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sample_idx_buffer->data.ptr[sample_idx->data.i[i*sample_idx_step]] = 1;
16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            samples_selected = samples_all;
16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sample_idx = sample_idx_buffer;
16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sample_idx_step = 1;
16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( sparse_rows = (CvSparseMat**)cvAlloc( samples_selected*sizeof(sparse_rows[0])));
16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < samples_selected; i++ )
16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sample_idx && sample_idx->data.ptr[i*sample_idx_step] == 0 )
16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( sparse_rows[i] = cvCreateSparseMat( 1, &dims_all, type ));
16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !storage )
16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                storage = sparse_rows[i]->heap->storage;
16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // hack: to decrease memory footprint, make all the sparse matrices
16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // reside in the same storage
16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int elem_size = sparse_rows[i]->heap->elem_size;
16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvReleaseMemStorage( &sparse_rows[i]->heap->storage );
16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sparse_rows[i]->heap = cvCreateSet( 0, sizeof(CvSet), elem_size, storage );
16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // put each row (or column) of predict_input into separate sparse matrix.
16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        node = cvInitSparseMatIterator( sparse, &mat_iterator );
16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator ))
16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int* idx = CV_NODE_IDX( sparse, node );
16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int idx0 = idx[tflag ^ 1];
16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int idx1 = idx[tflag];
16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sample_idx && sample_idx->data.ptr[idx0*sample_idx_step] == 0 )
16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( sparse_rows[idx0] != 0 );
16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *(float*)cvPtrND( sparse, &idx1, 0, 1, 0 ) = *(float*)CV_NODE_VAL( sparse, node );
16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < samples_selected; i++ )
16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int idx = i;
16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float response;
16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sample_idx )
16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( CV_MAT_TYPE(sample_idx->type) == CV_32SC1 )
16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                idx = sample_idx->data.i[i*sample_idx_step];
16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)idx >= (unsigned)samples_all )
16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsOutOfRange, "Some of sample_idx elements are out of range" );
16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( CV_MAT_TYPE(sample_idx->type) == CV_8UC1 &&
16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     sample_idx->data.ptr[i*sample_idx_step] == 0 )
16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !is_sparse )
16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !tflag )
16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetRow( predict_input, &predict_input_part, idx );
16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetCol( predict_input, &predict_input_part, idx );
17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sample = sparse_rows[idx];
17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( probs )
17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGetRow( probs, probs1, idx );
17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( response = stat_model->predict( stat_model, (CvMat*)sample, probs1 ));
17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_TYPE(predict_output->type) == CV_32FC1 )
17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            predict_output->data.fl[idx*predict_output_step] = response;
17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ASSERT( cvRound(response) == response );
17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            predict_output->data.i[idx*predict_output_step] = cvRound(response);
17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sparse_rows )
17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i;
17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < samples_selected; i++ )
17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sparse_rows[i] )
17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sparse_rows[i]->heap->storage = 0;
17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvReleaseSparseMat( &sparse_rows[i] );
17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &sparse_rows );
17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &sample_idx_buffer );
17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMemStorage( &storage );
17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By P. Yarykin - begin -
17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid cvCombineResponseMaps (CvMat*  _responses,
17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      const CvMat*  old_response_map,
17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvMat*  new_response_map,
17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvMat** out_response_map)
17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int** old_data = NULL;
17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int** new_data = NULL;
17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_FUNCNAME ("cvCombineResponseMaps");
17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __BEGIN__
17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i,j;
17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int old_n, new_n, out_n;
17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int samples, free_response;
17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* first;
17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* responses;
17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* out_data;
17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( out_response_map )
17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *out_response_map = 0;
17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Check input data.
17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ((!ICV_IS_MAT_OF_TYPE (_responses, CV_32SC1)) ||
17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (!ICV_IS_MAT_OF_TYPE (old_response_map, CV_32SC1)) ||
17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (!ICV_IS_MAT_OF_TYPE (new_response_map, CV_32SC1)))
17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR (CV_StsBadArg, "Some of input arguments is not the CvMat")
17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Prepare sorted responses.
17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    first = new_response_map->data.i;
17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    new_n = new_response_map->cols;
17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL (new_data = (int**)cvAlloc (new_n * sizeof (new_data[0])));
17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < new_n; i++)
17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        new_data[i] = first + i;
17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    qsort (new_data, new_n, sizeof(int*), icvCmpIntegersPtr);
17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    first = old_response_map->data.i;
17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    old_n = old_response_map->cols;
17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL (old_data = (int**)cvAlloc (old_n * sizeof (old_data[0])));
17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < old_n; i++)
17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        old_data[i] = first + i;
17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    qsort (old_data, old_n, sizeof(int*), icvCmpIntegersPtr);
17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Count the number of different responses.
17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0, j = 0, out_n = 0; i < old_n && j < new_n; out_n++)
17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (*old_data[i] == *new_data[j])
17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i++;
17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            j++;
17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if (*old_data[i] < *new_data[j])
17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i++;
17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            j++;
17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    out_n += old_n - i + new_n - j;
17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Create and fill the result response maps.
18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL (*out_response_map = cvCreateMat (1, out_n, CV_32SC1));
18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    out_data = (*out_response_map)->data.i;
18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memcpy (out_data, first, old_n * sizeof (int));
18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    free_response = old_n;
18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0, j = 0; i < old_n && j < new_n; )
18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (*old_data[i] == *new_data[j])
18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *new_data[j] = (int)(old_data[i] - first);
18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i++;
18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            j++;
18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if (*old_data[i] < *new_data[j])
18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i++;
18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            out_data[free_response] = *new_data[j];
18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *new_data[j] = free_response++;
18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            j++;
18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (; j < new_n; j++)
18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        out_data[free_response] = *new_data[j];
18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *new_data[j] = free_response++;
18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT (free_response == out_n);
18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Change <responses> according to out response map.
18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    samples = _responses->cols + _responses->rows - 1;
18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    responses = _responses->data.i;
18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    first = new_response_map->data.i;
18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < samples; i++)
18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        responses[i] = first[responses[i]];
18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __END__
18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree(&old_data);
18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree(&new_data);
18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint icvGetNumberOfCluster( double* prob_vector, int num_of_clusters, float r,
18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           float outlier_thresh, int normalize_probs )
18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int max_prob_loc = 0;
18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("icvGetNumberOfCluster");
18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double prob, maxprob, sum;
18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT(prob_vector);
18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT(num_of_clusters >= 0);
18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    maxprob = prob_vector[0];
18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    max_prob_loc = 0;
18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    sum = maxprob;
18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 1; i < num_of_clusters; i++ )
18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prob = prob_vector[i];
18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sum += prob;
18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( prob > maxprob )
18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_prob_loc = i;
18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            maxprob = prob;
18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( normalize_probs && fabs(sum - 1.) > FLT_EPSILON )
18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < num_of_clusters; i++ )
18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prob_vector[i] /= sum;
18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( fabs(r - 1.) > FLT_EPSILON && fabs(sum - 1.) < outlier_thresh )
18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        max_prob_loc = -1;
18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return max_prob_loc;
18846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // End of icvGetNumberOfCluster
18866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid icvFindClusterLabels( const CvMat* probs, float outlier_thresh, float r,
18896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          const CvMat* labels )
18906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
18916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* counts = 0;
18926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("icvFindClusterLabels");
18946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
18956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nclusters, nsamples;
18976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
18986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double* probs_data;
18996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( ICV_IS_MAT_OF_TYPE(probs, CV_64FC1) );
19016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( ICV_IS_MAT_OF_TYPE(labels, CV_32SC1) );
19026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    nclusters = probs->cols;
19046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    nsamples  = probs->rows;
19056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( nsamples == labels->cols );
19066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( counts = cvCreateMat( 1, nclusters + 1, CV_32SC1 ) );
19086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvSetZero( counts ));
19096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < nsamples; i++ )
19106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
19116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        labels->data.i[i] = icvGetNumberOfCluster( probs->data.db + i*probs->cols,
19126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            nclusters, r, outlier_thresh, 1 );
19136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        counts->data.i[labels->data.i[i] + 1]++;
19146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
19156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT((int)cvSum(counts).val[0] == nsamples);
19166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Filling empty clusters with the vector, that has the maximal probability
19176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( j = 0; j < nclusters; j++ ) // outliers are ignored
19186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
19196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int maxprob_loc = -1;
19206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double maxprob = 0;
19216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( counts->data.i[j+1] ) // j-th class is not empty
19236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            continue;
19246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // look for the presentative, which is not lonely in it's cluster
19256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // and that has a maximal probability among all these vectors
19266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        probs_data = probs->data.db;
19276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nsamples; i++, probs_data++ )
19286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int label = labels->data.i[i];
19306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double prob;
19316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( counts->data.i[label+1] == 0 ||
19326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (counts->data.i[label+1] <= 1 && label != -1) )
19336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
19346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prob = *probs_data;
19356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( prob >= maxprob )
19366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                maxprob = prob;
19386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                maxprob_loc = i;
19396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // maxprob_loc == 0 <=> number of vectors less then number of clusters
19426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ASSERT( maxprob_loc >= 0 );
19436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        counts->data.i[labels->data.i[maxprob_loc] + 1]--;
19446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        labels->data.i[maxprob_loc] = j;
19456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        counts->data.i[j + 1]++;
19466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
19476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
19496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &counts );
19516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // End of icvFindClusterLabels
19526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file */
1954