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 Renn COPYRIGHT NOTICE 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ---------------- 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn The code has been derived from libsvm library (version 2.6) 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (http://www.csie.ntu.edu.tw/~cjlin/libsvm). 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Here is the orignal copyright: 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn------------------------------------------------------------------------------------------ 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Copyright (c) 2000-2003 Chih-Chung Chang and Chih-Jen Lin 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn All rights reserved. 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Redistribution and use in source and binary forms, with or without 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn modification, are permitted provided that the following conditions 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn are met: 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1. Redistributions of source code must retain the above copyright 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn notice, this list of conditions and the following disclaimer. 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2. Redistributions in binary form must reproduce the above copyright 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn notice, this list of conditions and the following disclaimer in the 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn documentation and/or other materials provided with the distribution. 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3. Neither name of copyright holders nor the names of its contributors 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn may be used to endorse or promote products derived from this software 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn without specific prior written permission. 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_SVM_MIN_CACHE_SIZE (40 << 20) /* 40Mb */ 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <stdarg.h> 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <ctype.h> 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if _MSC_VER >= 1200 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#pragma warning( disable: 4514 ) /* unreferenced inline functions */ 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 1 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef float Qfloat; 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define QFLOAT_TYPE CV_32F 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef double Qfloat; 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define QFLOAT_TYPE CV_64F 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Param Grid 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvParamGrid::check() const 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvParamGrid::check" ); 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( min_val > max_val ) 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Lower bound of the grid must be less then the upper one" ); 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( min_val < DBL_EPSILON ) 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Lower bound of the grid must be positive" ); 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( step < 1. + FLT_EPSILON ) 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Grid step must greater then 1" ); 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = true; 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvParamGrid CvSVM::get_default_grid( int param_id ) 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvParamGrid grid; 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( param_id == CvSVM::C ) 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.min_val = 0.1; 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.max_val = 500; 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.step = 5; // total iterations = 5 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( param_id == CvSVM::GAMMA ) 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.min_val = 1e-5; 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.max_val = 0.6; 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.step = 15; // total iterations = 4 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( param_id == CvSVM::P ) 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.min_val = 0.01; 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.max_val = 100; 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.step = 7; // total iterations = 4 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( param_id == CvSVM::NU ) 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.min_val = 0.01; 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.max_val = 0.2; 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.step = 3; // total iterations = 3 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( param_id == CvSVM::COEF ) 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.min_val = 0.1; 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.max_val = 300; 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.step = 14; // total iterations = 3 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( param_id == CvSVM::DEGREE ) 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.min_val = 0.01; 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.max_val = 4; 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grid.step = 7; // total iterations = 3 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvError( CV_StsBadArg, "CvSVM::get_default_grid", "Invalid type of parameter " 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "(use one of CvSVM::C, CvSVM::GAMMA et al.)", __FILE__, __LINE__ ); 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return grid; 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// SVM training parameters 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMParams::CvSVMParams() : 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type(CvSVM::C_SVC), kernel_type(CvSVM::RBF), degree(0), 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma(1), coef0(0), C(1), nu(0), p(0), class_weights(0) 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn term_crit = cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON ); 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMParams::CvSVMParams( int _svm_type, int _kernel_type, 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double _degree, double _gamma, double _coef0, 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double _Con, double _nu, double _p, 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* _class_weights, CvTermCriteria _term_crit ) : 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type(_svm_type), kernel_type(_kernel_type), 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree(_degree), gamma(_gamma), coef0(_coef0), 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C(_Con), nu(_nu), p(_p), class_weights(_class_weights), term_crit(_term_crit) 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////////////////////// SVM kernel /////////////////////////////////////// 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMKernel::CvSVMKernel() 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::clear() 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params = 0; 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_func = 0; 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMKernel::~CvSVMKernel() 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMKernel::CvSVMKernel( const CvSVMParams* _params, Calc _calc_func ) 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create( _params, _calc_func ); 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMKernel::create( const CvSVMParams* _params, Calc _calc_func ) 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params = _params; 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_func = _calc_func; 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !calc_func ) 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_func = params->kernel_type == CvSVM::RBF ? &CvSVMKernel::calc_rbf : 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params->kernel_type == CvSVM::POLY ? &CvSVMKernel::calc_poly : 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params->kernel_type == CvSVM::SIGMOID ? &CvSVMKernel::calc_sigmoid : 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMKernel::calc_linear; 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::calc_non_rbf_base( int vcount, int var_count, const float** vecs, 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* another, Qfloat* results, 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double alpha, double beta ) 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j, k; 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < vcount; j++ ) 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* sample = vecs[j]; 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double s = 0; 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k <= var_count - 4; k += 4 ) 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn s += sample[k]*another[k] + sample[k+1]*another[k+1] + 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sample[k+2]*another[k+2] + sample[k+3]*another[k+3]; 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; k < var_count; k++ ) 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn s += sample[k]*another[k]; 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn results[j] = (Qfloat)(s*alpha + beta); 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::calc_linear( int vcount, int var_count, const float** vecs, 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* another, Qfloat* results ) 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_non_rbf_base( vcount, var_count, vecs, another, results, 1, 0 ); 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::calc_poly( int vcount, int var_count, const float** vecs, 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* another, Qfloat* results ) 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat R = cvMat( 1, vcount, QFLOAT_TYPE, results ); 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_non_rbf_base( vcount, var_count, vecs, another, results, params->gamma, params->coef0 ); 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvPow( &R, &R, params->degree ); 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::calc_sigmoid( int vcount, int var_count, const float** vecs, 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* another, Qfloat* results ) 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j; 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_non_rbf_base( vcount, var_count, vecs, another, results, 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn -2*params->gamma, -2*params->coef0 ); 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // TODO: speedup this 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < vcount; j++ ) 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat t = results[j]; 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double e = exp(-fabs(t)); 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t > 0 ) 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn results[j] = (Qfloat)((1. - e)/(1. + e)); 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn results[j] = (Qfloat)((e - 1.)/(e + 1.)); 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::calc_rbf( int vcount, int var_count, const float** vecs, 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* another, Qfloat* results ) 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat R = cvMat( 1, vcount, QFLOAT_TYPE, results ); 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double gamma = -params->gamma; 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j, k; 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < vcount; j++ ) 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* sample = vecs[j]; 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double s = 0; 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k <= var_count - 4; k += 4 ) 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t0 = sample[k] - another[k]; 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t1 = sample[k+1] - another[k+1]; 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn s += t0*t0 + t1*t1; 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = sample[k+2] - another[k+2]; 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t1 = sample[k+3] - another[k+3]; 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn s += t0*t0 + t1*t1; 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; k < var_count; k++ ) 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t0 = sample[k] - another[k]; 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn s += t0*t0; 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn results[j] = (Qfloat)(s*gamma); 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvExp( &R, &R ); 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMKernel::calc( int vcount, int var_count, const float** vecs, 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* another, Qfloat* results ) 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Qfloat max_val = (Qfloat)(FLT_MAX*1e-3); 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j; 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (this->*calc_func)( vcount, var_count, vecs, another, results ); 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < vcount; j++ ) 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( results[j] > max_val ) 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn results[j] = max_val; 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Generalized SMO+SVMlight algorithm 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Solves: 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// min [0.5(\alpha^T Q \alpha) + b^T \alpha] 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// y^T \alpha = \delta 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// y_i = +1 or -1 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 0 <= alpha_i <= Cp for y_i = 1 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 0 <= alpha_i <= Cn for y_i = -1 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Given: 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Q, b, y, Cp, Cn, and an initial feasible point \alpha 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// l is the size of vectors and matrices 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// eps is the stopping criterion 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// solution will be put in \alpha, objective value will be put in obj 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVMSolver::clear() 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn G = 0; 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha = 0; 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y = 0; 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b = 0; 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[0] = buf[1] = 0; 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &storage ); 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = 0; 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn select_working_set_func = 0; 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_rho_func = 0; 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rows = 0; 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples = 0; 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn get_row_func = 0; 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::CvSVMSolver() 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = 0; 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::~CvSVMSolver() 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::CvSVMSolver( int _sample_count, int _var_count, const float** _samples, schar* _y, 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _alpha_count, double* _alpha, double _Cp, double _Cn, 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* _storage, CvSVMKernel* _kernel, GetRow _get_row, 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn SelectWorkingSet _select_working_set, CalcRho _calc_rho ) 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = 0; 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create( _sample_count, _var_count, _samples, _y, _alpha_count, _alpha, _Cp, _Cn, 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _storage, _kernel, _get_row, _select_working_set, _calc_rho ); 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::create( int _sample_count, int _var_count, const float** _samples, schar* _y, 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _alpha_count, double* _alpha, double _Cp, double _Cn, 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* _storage, CvSVMKernel* _kernel, GetRow _get_row, 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn SelectWorkingSet _select_working_set, CalcRho _calc_rho ) 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, svm_type; 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVMSolver::create" ); 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int rows_hdr_size; 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sample_count = _sample_count; 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_count = _var_count; 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples = _samples; 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y = _y; 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_count = _alpha_count; 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha = _alpha; 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = _kernel; 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C[0] = _Cn; 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C[1] = _Cp; 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn eps = kernel->params->term_crit.epsilon; 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_iter = kernel->params->term_crit.max_iter; 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = cvCreateChildMemStorage( _storage ); 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b = (double*)cvMemStorageAlloc( storage, alpha_count*sizeof(b[0])); 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_status = (schar*)cvMemStorageAlloc( storage, alpha_count*sizeof(alpha_status[0])); 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn G = (double*)cvMemStorageAlloc( storage, alpha_count*sizeof(G[0])); 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < 2; i++ ) 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf[i] = (Qfloat*)cvMemStorageAlloc( storage, sample_count*2*sizeof(buf[i][0]) ); 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = kernel->params->svm_type; 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn select_working_set_func = _select_working_set; 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !select_working_set_func ) 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn select_working_set_func = svm_type == CvSVM::NU_SVC || svm_type == CvSVM::NU_SVR ? 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::select_working_set_nu_svm : &CvSVMSolver::select_working_set; 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_rho_func = _calc_rho; 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !calc_rho_func ) 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn calc_rho_func = svm_type == CvSVM::NU_SVC || svm_type == CvSVM::NU_SVR ? 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::calc_rho_nu_svm : &CvSVMSolver::calc_rho; 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn get_row_func = _get_row; 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !get_row_func ) 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn get_row_func = params->svm_type == CvSVM::EPS_SVR || 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params->svm_type == CvSVM::NU_SVR ? &CvSVMSolver::get_row_svr : 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params->svm_type == CvSVM::C_SVC || 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params->svm_type == CvSVM::NU_SVC ? &CvSVMSolver::get_row_svc : 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::get_row_one_class; 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cache_line_size = sample_count*sizeof(Qfloat); 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // cache size = max(num_of_samples^2*sizeof(Qfloat)*0.25, 64Kb) 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // (assuming that for large training sets ~25% of Q matrix is used) 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cache_size = MAX( cache_line_size*sample_count/4, CV_SVM_MIN_CACHE_SIZE ); 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // the size of Q matrix row headers 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rows_hdr_size = sample_count*sizeof(rows[0]); 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( rows_hdr_size > storage->block_size ) 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "Too small storage block size" ); 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lru_list.prev = lru_list.next = &lru_list; 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rows = (CvSVMKernelRow*)cvMemStorageAlloc( storage, rows_hdr_size ); 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( rows, 0, rows_hdr_size ); 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = true; 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat* CvSVMSolver::get_row_base( int i, bool* _existed ) 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i1 = i < sample_count ? i : i - sample_count; 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMKernelRow* row = rows + i1; 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool existed = row->data != 0; 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat* data; 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( existed || cache_size <= 0 ) 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMKernelRow* del_row = existed ? row : lru_list.prev; 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn data = del_row->data; 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( data != 0 ); 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // delete row from the LRU list 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn del_row->data = 0; 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn del_row->prev->next = del_row->next; 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn del_row->next->prev = del_row->prev; 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn data = (Qfloat*)cvMemStorageAlloc( storage, cache_line_size ); 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cache_size -= cache_line_size; 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // insert row into the LRU list 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row->data = data; 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row->prev = &lru_list; 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row->next = lru_list.next; 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row->prev->next = row->next->prev = row; 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !existed ) 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel->calc( sample_count, var_count, samples, samples[i1], row->data ); 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _existed ) 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *_existed = existed; 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return row->data; 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat* CvSVMSolver::get_row_svc( int i, float* row, float*, bool existed ) 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !existed ) 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const schar* _y = y; 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j, len = sample_count; 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( _y && i < sample_count ); 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _y[i] > 0 ) 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < len; j++ ) 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row[j] = _y[j]*row[j]; 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < len; j++ ) 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row[j] = -_y[j]*row[j]; 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return row; 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat* CvSVMSolver::get_row_one_class( int, float* row, float*, bool ) 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return row; 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat* CvSVMSolver::get_row_svr( int i, float* row, float* dst, bool ) 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j, len = sample_count; 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat* dst_pos = dst; 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat* dst_neg = dst + len; 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( i >= len ) 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat* temp; 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( dst_pos, dst_neg, temp ); 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < len; j++ ) 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat t = row[j]; 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst_pos[j] = t; 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst_neg[j] = -t; 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return dst; 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat* CvSVMSolver::get_row( int i, float* dst ) 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool existed = false; 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* row = get_row_base( i, &existed ); 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return (this->*get_row_func)( i, row, dst, existed ); 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef is_upper_bound 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define is_upper_bound(i) (alpha_status[i] > 0) 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef is_lower_bound 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define is_lower_bound(i) (alpha_status[i] < 0) 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef is_free 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define is_free(i) (alpha_status[i] == 0) 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef get_C 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define get_C(i) (C[y[i]>0]) 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef update_alpha_status 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define update_alpha_status(i) \ 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_status[i] = (schar)(alpha[i] >= get_C(i) ? 1 : alpha[i] <= 0 ? -1 : 0) 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef reconstruct_gradient 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define reconstruct_gradient() /* empty for now */ 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::solve_generic( CvSVMSolutionInfo& si ) 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int iter = 0; 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, k; 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // 1. initialize gradient and alpha status 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn update_alpha_status(i); 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn G[i] = b[i]; 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(G[i]) > 1e200 ) 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_lower_bound(i) ) 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Qfloat *Q_i = get_row( i, buf[0] ); 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double alpha_i = alpha[i]; 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < alpha_count; j++ ) 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn G[j] += alpha_i*Q_i[j]; 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // 2. optimization loop 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;) 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const Qfloat *Q_i, *Q_j; 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double C_i, C_j; 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double old_alpha_i, old_alpha_j, alpha_i, alpha_j; 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double delta_alpha_i, delta_alpha_j; 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _DEBUG 6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(G[i]) > 1e+300 ) 6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(alpha[i]) > 1e16 ) 6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (this->*select_working_set_func)( i, j ) != 0 || iter++ >= max_iter ) 6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Q_i = get_row( i, buf[0] ); 6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Q_j = get_row( j, buf[1] ); 6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_i = get_C(i); 6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_j = get_C(j); 6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = old_alpha_i = alpha[i]; 6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = old_alpha_j = alpha[j]; 6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] != y[j] ) 6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double denom = Q_i[i]+Q_j[j]+2*Q_i[j]; 6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double delta = (-G[i]-G[j])/MAX(fabs(denom),FLT_EPSILON); 6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double diff = alpha_i - alpha_j; 6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i += delta; 6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j += delta; 6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( diff > 0 && alpha_j < 0 ) 6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = 0; 6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = diff; 6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( diff <= 0 && alpha_i < 0 ) 6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = 0; 6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = -diff; 6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( diff > C_i - C_j && alpha_i > C_i ) 6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = C_i; 6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = C_i - diff; 6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( diff <= C_i - C_j && alpha_j > C_j ) 6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = C_j; 6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = C_j + diff; 6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double denom = Q_i[i]+Q_j[j]-2*Q_i[j]; 6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double delta = (G[i]-G[j])/MAX(fabs(denom),FLT_EPSILON); 6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double sum = alpha_i + alpha_j; 6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i -= delta; 6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j += delta; 6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sum > C_i && alpha_i > C_i ) 6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = C_i; 6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = sum - C_i; 6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( sum <= C_i && alpha_j < 0) 6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = 0; 6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = sum; 6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sum > C_j && alpha_j > C_j ) 7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = C_j; 7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = sum - C_j; 7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( sum <= C_j && alpha_i < 0 ) 7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_i = 0; 7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_j = sum; 7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // update alpha 7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = alpha_i; 7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[j] = alpha_j; 7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn update_alpha_status(i); 7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn update_alpha_status(j); 7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // update G 7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_alpha_i = alpha_i - old_alpha_i; 7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_alpha_j = alpha_j - old_alpha_j; 7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < alpha_count; k++ ) 7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn G[k] += Q_i[k]*delta_alpha_i + Q_j[k]*delta_alpha_j; 7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // calculate rho 7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (this->*calc_rho_func)( si.rho, si.r ); 7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // calculate objective value 7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0, si.obj = 0; i < alpha_count; i++ ) 7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn si.obj += alpha[i] * (G[i] + b[i]); 7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn si.obj *= 0.5; 7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn si.upper_bound_p = C[1]; 7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn si.upper_bound_n = C[0]; 7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// return 1 if already optimal, return 0 otherwise 7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool 7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::select_working_set( int& out_i, int& out_j ) 7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // return i,j which maximize -grad(f)^T d , under constraint 7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // if alpha_i == C, d != +1 7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // if alpha_i == 0, d != -1 7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Gmax1 = -DBL_MAX; // max { -grad(f)_i * d | y_i*d = +1 } 7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int Gmax1_idx = -1; 7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Gmax2 = -DBL_MAX; // max { -grad(f)_i * d | y_i*d = -1 } 7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int Gmax2_idx = -1; 7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t; 7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] > 0 ) // y = +1 7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_upper_bound(i) && (t = -G[i]) > Gmax1 ) // d = +1 7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax1 = t; 7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax1_idx = i; 7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_lower_bound(i) && (t = G[i]) > Gmax2 ) // d = -1 7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax2 = t; 7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax2_idx = i; 7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else // y = -1 7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_upper_bound(i) && (t = -G[i]) > Gmax2 ) // d = +1 7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax2 = t; 7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax2_idx = i; 7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_lower_bound(i) && (t = G[i]) > Gmax1 ) // d = -1 7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax1 = t; 7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax1_idx = i; 7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out_i = Gmax1_idx; 7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out_j = Gmax2_idx; 7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return Gmax1 + Gmax2 < eps; 7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid 7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::calc_rho( double& rho, double& r ) 7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, nr_free = 0; 8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double ub = DBL_MAX, lb = -DBL_MAX, sum_free = 0; 8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double yG = y[i]*G[i]; 8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( is_lower_bound(i) ) 8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] > 0 ) 8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ub = MIN(ub,yG); 8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lb = MAX(lb,yG); 8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( is_upper_bound(i) ) 8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] < 0) 8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ub = MIN(ub,yG); 8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lb = MAX(lb,yG); 8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ++nr_free; 8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_free += yG; 8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rho = nr_free > 0 ? sum_free/nr_free : (ub + lb)*0.5; 8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r = 0; 8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool 8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::select_working_set_nu_svm( int& out_i, int& out_j ) 8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // return i,j which maximize -grad(f)^T d , under constraint 8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // if alpha_i == C, d != +1 8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // if alpha_i == 0, d != -1 8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Gmax1 = -DBL_MAX; // max { -grad(f)_i * d | y_i = +1, d = +1 } 8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int Gmax1_idx = -1; 8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Gmax2 = -DBL_MAX; // max { -grad(f)_i * d | y_i = +1, d = -1 } 8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int Gmax2_idx = -1; 8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Gmax3 = -DBL_MAX; // max { -grad(f)_i * d | y_i = -1, d = +1 } 8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int Gmax3_idx = -1; 8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Gmax4 = -DBL_MAX; // max { -grad(f)_i * d | y_i = -1, d = -1 } 8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int Gmax4_idx = -1; 8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t; 8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] > 0 ) // y == +1 8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_upper_bound(i) && (t = -G[i]) > Gmax1 ) // d = +1 8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax1 = t; 8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax1_idx = i; 8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_lower_bound(i) && (t = G[i]) > Gmax2 ) // d = -1 8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax2 = t; 8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax2_idx = i; 8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else // y == -1 8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_upper_bound(i) && (t = -G[i]) > Gmax3 ) // d = +1 8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax3 = t; 8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax3_idx = i; 8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_lower_bound(i) && (t = G[i]) > Gmax4 ) // d = -1 8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax4 = t; 8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Gmax4_idx = i; 8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( MAX(Gmax1 + Gmax2, Gmax3 + Gmax4) < eps ) 8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 1; 8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( Gmax1 + Gmax2 > Gmax3 + Gmax4 ) 8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out_i = Gmax1_idx; 8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out_j = Gmax2_idx; 8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out_i = Gmax3_idx; 8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn out_j = Gmax4_idx; 8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 0; 8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid 9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVMSolver::calc_rho_nu_svm( double& rho, double& r ) 9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int nr_free1 = 0, nr_free2 = 0; 9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double ub1 = DBL_MAX, ub2 = DBL_MAX; 9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double lb1 = -DBL_MAX, lb2 = -DBL_MAX; 9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double sum_free1 = 0, sum_free2 = 0; 9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double r1, r2; 9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < alpha_count; i++ ) 9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double G_i = G[i]; 9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] > 0 ) 9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( is_lower_bound(i) ) 9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ub1 = MIN( ub1, G_i ); 9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( is_upper_bound(i) ) 9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lb1 = MAX( lb1, G_i ); 9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ++nr_free1; 9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_free1 += G_i; 9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( is_lower_bound(i) ) 9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ub2 = MIN( ub2, G_i ); 9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( is_upper_bound(i) ) 9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lb2 = MAX( lb2, G_i ); 9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ++nr_free2; 9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_free2 += G_i; 9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r1 = nr_free1 > 0 ? sum_free1/nr_free1 : (ub1 + lb1)*0.5; 9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r2 = nr_free2 > 0 ? sum_free2/nr_free2 : (ub2 + lb2)*0.5; 9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rho = (r1 - r2)*0.5; 9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r = (r1 + r2)*0.5; 9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn///////////////////////// construct and solve various formulations /////////////////////// 9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/ 9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::solve_c_svc( int _sample_count, int _var_count, const float** _samples, schar* _y, 9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double _Cp, double _Cn, CvMemStorage* _storage, 9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMKernel* _kernel, double* _alpha, CvSVMSolutionInfo& _si ) 9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !create( _sample_count, _var_count, _samples, _y, _sample_count, 9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _alpha, _Cp, _Cn, _storage, _kernel, &CvSVMSolver::get_row_svc, 9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::select_working_set, &CvSVMSolver::calc_rho )) 9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = 0; 9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i] = -1; 9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !solve_generic( _si )) 9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] *= y[i]; 9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::solve_nu_svc( int _sample_count, int _var_count, const float** _samples, schar* _y, 9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* _storage, CvSVMKernel* _kernel, 9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double* _alpha, CvSVMSolutionInfo& _si ) 9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double sum_pos, sum_neg, inv_r; 9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !create( _sample_count, _var_count, _samples, _y, _sample_count, 9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _alpha, 1., 1., _storage, _kernel, &CvSVMSolver::get_row_svc, 9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::select_working_set_nu_svm, &CvSVMSolver::calc_rho_nu_svm )) 9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_pos = kernel->params->nu * sample_count * 0.5; 9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_neg = kernel->params->nu * sample_count * 0.5; 9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y[i] > 0 ) 9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = MIN(1.0, sum_pos); 10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_pos -= alpha[i]; 10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = MIN(1.0, sum_neg); 10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum_neg -= alpha[i]; 10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i] = 0; 10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !solve_generic( _si )) 10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_r = 1./_si.r; 10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] *= y[i]*inv_r; 10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _si.rho *= inv_r; 10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _si.obj *= (inv_r*inv_r); 10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _si.upper_bound_p = inv_r; 10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _si.upper_bound_n = inv_r; 10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::solve_one_class( int _sample_count, int _var_count, const float** _samples, 10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* _storage, CvSVMKernel* _kernel, 10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double* _alpha, CvSVMSolutionInfo& _si ) 10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, n; 10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double nu = _kernel->params->nu; 10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !create( _sample_count, _var_count, _samples, 0, _sample_count, 10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _alpha, 1., 1., _storage, _kernel, &CvSVMSolver::get_row_one_class, 10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::select_working_set, &CvSVMSolver::calc_rho )) 10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y = (schar*)cvMemStorageAlloc( storage, sample_count*sizeof(y[0]) ); 10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = cvRound( nu*sample_count ); 10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y[i] = 1; 10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i] = 0; 10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = i < n ? 1 : 0; 10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n < sample_count ) 10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[n] = nu * sample_count - n; 10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[n-1] = nu * sample_count - (n-1); 10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return solve_generic(_si); 10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::solve_eps_svr( int _sample_count, int _var_count, const float** _samples, 10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* _y, CvMemStorage* _storage, 10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMKernel* _kernel, double* _alpha, CvSVMSolutionInfo& _si ) 10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double p = _kernel->params->p, C = _kernel->params->C; 10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !create( _sample_count, _var_count, _samples, 0, 10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _sample_count*2, 0, C, C, _storage, _kernel, &CvSVMSolver::get_row_svr, 10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::select_working_set, &CvSVMSolver::calc_rho )) 10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y = (schar*)cvMemStorageAlloc( storage, sample_count*2*sizeof(y[0]) ); 10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha = (double*)cvMemStorageAlloc( storage, alpha_count*sizeof(alpha[0]) ); 10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = 0; 10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i] = p - _y[i]; 10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y[i] = 1; 10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i+sample_count] = 0; 10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i+sample_count] = p + _y[i]; 10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y[i+sample_count] = -1; 10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !solve_generic( _si )) 10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _alpha[i] = alpha[i] - alpha[i+sample_count]; 10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVMSolver::solve_nu_svr( int _sample_count, int _var_count, const float** _samples, 10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* _y, CvMemStorage* _storage, 10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMKernel* _kernel, double* _alpha, CvSVMSolutionInfo& _si ) 10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double C = _kernel->params->C, sum; 11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !create( _sample_count, _var_count, _samples, 0, 11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _sample_count*2, 0, 1., 1., _storage, _kernel, &CvSVMSolver::get_row_svr, 11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &CvSVMSolver::select_working_set_nu_svm, &CvSVMSolver::calc_rho_nu_svm )) 11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y = (schar*)cvMemStorageAlloc( storage, sample_count*2*sizeof(y[0]) ); 11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha = (double*)cvMemStorageAlloc( storage, alpha_count*sizeof(alpha[0]) ); 11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum = C * _kernel->params->nu * sample_count * 0.5; 11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha[i] = alpha[i + sample_count] = MIN(sum, C); 11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum -= alpha[i]; 11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i] = -_y[i]; 11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y[i] = 1; 11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn b[i + sample_count] = _y[i]; 11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y[i + sample_count] = -1; 11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !solve_generic( _si )) 11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _alpha[i] = alpha[i] - alpha[i+sample_count]; 11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////////////////////////////////////////////////////////////////////////////////////// 11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVM::CvSVM() 11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn decision_func = 0; 11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_labels = 0; 11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_weights = 0; 11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = 0; 11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_idx = 0; 11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = 0; 11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn solver = 0; 11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default_model_name = "my_svm"; 11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVM::~CvSVM() 11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::clear() 11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &decision_func ); 11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &class_labels ); 11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &class_weights ); 11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &storage ); 11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &var_idx ); 11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete kernel; 11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete solver; 11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = 0; 11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn solver = 0; 11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_all = 0; 11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv = 0; 11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total = 0; 11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSVM::CvSVM( const CvMat* _train_data, const CvMat* _responses, 11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* _var_idx, const CvMat* _sample_idx, CvSVMParams _params ) 11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn decision_func = 0; 11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_labels = 0; 11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_weights = 0; 11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = 0; 11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_idx = 0; 11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = 0; 11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn solver = 0; 11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default_model_name = "my_svm"; 11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn train( _train_data, _responses, _var_idx, _sample_idx, _params ); 11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint CvSVM::get_support_vector_count() const 11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return sv_total; 11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennconst float* CvSVM::get_support_vector(int i) const 11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return sv && (unsigned)i < (unsigned)sv_total ? sv[i] : 0; 11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVM::set_params( const CvSVMParams& _params ) 12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::set_params" ); 12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int kernel_type, svm_type; 12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params = _params; 12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type = params.kernel_type; 12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = params.svm_type; 12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type != LINEAR && kernel_type != POLY && 12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type != SIGMOID && kernel_type != RBF ) 12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Unknown/unsupported kernel type" ); 12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type == LINEAR ) 12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.gamma = 1; 12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.gamma <= 0 ) 12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "gamma parameter of the kernel must be positive" ); 12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type != SIGMOID && kernel_type != POLY ) 12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.coef0 = 0; 12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.coef0 < 0 ) 12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "The kernel parameter <coef0> must be positive or zero" ); 12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type != POLY ) 12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.degree = 0; 12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.degree <= 0 ) 12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "The kernel parameter <degree> must be positive" ); 12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type != C_SVC && svm_type != NU_SVC && 12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type != ONE_CLASS && svm_type != EPS_SVR && 12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type != NU_SVR ) 12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Unknown/unsupported SVM type" ); 12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == ONE_CLASS || svm_type == NU_SVC ) 12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.C = 0; 12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.C <= 0 ) 12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "The parameter C must be positive" ); 12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == C_SVC || svm_type == EPS_SVR ) 12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.nu = 0; 12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.nu <= 0 || params.nu >= 1 ) 12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "The parameter nu must be between 0 and 1" ); 12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type != EPS_SVR ) 12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.p = 0; 12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.p <= 0 ) 12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "The parameter p must be positive" ); 12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type != C_SVC ) 12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.class_weights = 0; 12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.term_crit = cvCheckTermCriteria( params.term_crit, DBL_EPSILON, INT_MAX ); 12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.term_crit.epsilon = MAX( params.term_crit.epsilon, DBL_EPSILON ); 12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = true; 12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::create_kernel() 12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = new CvSVMKernel(¶ms,0); 12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::create_solver( ) 12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn solver = new CvSVMSolver; 12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// switching function 12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVM::train1( int sample_count, int var_count, const float** samples, 12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const void* _responses, double Cp, double Cn, 12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* _storage, double* alpha, double& rho ) 12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //CV_FUNCNAME( "CvSVM::train1" ); 12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMSolutionInfo si; 12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int svm_type = params.svm_type; 12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn si.rho = 0; 12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = svm_type == C_SVC ? solver->solve_c_svc( sample_count, var_count, samples, (schar*)_responses, 12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cp, Cn, _storage, kernel, alpha, si ) : 12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == NU_SVC ? solver->solve_nu_svc( sample_count, var_count, samples, (schar*)_responses, 13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _storage, kernel, alpha, si ) : 13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == ONE_CLASS ? solver->solve_one_class( sample_count, var_count, samples, 13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _storage, kernel, alpha, si ) : 13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == EPS_SVR ? solver->solve_eps_svr( sample_count, var_count, samples, (float*)_responses, 13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _storage, kernel, alpha, si ) : 13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == NU_SVR ? solver->solve_nu_svr( sample_count, var_count, samples, (float*)_responses, 13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _storage, kernel, alpha, si ) : false; 13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rho = si.rho; 13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVM::do_train( int svm_type, int sample_count, int var_count, const float** samples, 13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* responses, CvMemStorage* temp_storage, double* alpha ) 13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::do_train" ); 13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMDecisionFunc* df = 0; 13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int sample_size = var_count*sizeof(samples[0][0]); 13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, k; 13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == ONE_CLASS || svm_type == EPS_SVR || svm_type == NU_SVR ) 13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sv_count = 0; 13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( decision_func = df = 13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (CvSVMDecisionFunc*)cvAlloc( sizeof(df[0]) )); 13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->rho = 0; 13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !train1( sample_count, var_count, samples, svm_type == ONE_CLASS ? 0 : 13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn responses->data.i, 0, 0, temp_storage, alpha, df->rho )) 13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count += fabs(alpha[i]) > 0; 13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total = df->sv_count = sv_count; 13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( df->alpha = (double*)cvMemStorageAlloc( storage, sv_count*sizeof(df->alpha[0])) ); 13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv = (float**)cvMemStorageAlloc( storage, sv_count*sizeof(sv[0]))); 13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = k = 0; i < sample_count; i++ ) 13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(alpha[i]) > 0 ) 13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv[k] = (float*)cvMemStorageAlloc( storage, sample_size )); 13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( sv[k], samples[i], sample_size ); 13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->alpha[k++] = alpha[i]; 13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int class_count = class_labels->cols; 13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* sv_tab = 0; 13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float** temp_samples = 0; 13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* class_ranges = 0; 13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* temp_y = 0; 13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( svm_type == CvSVM::C_SVC || svm_type == CvSVM::NU_SVC ); 13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::C_SVC && params.class_weights ) 13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* cw = params.class_weights; 13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MAT(cw) || cw->cols != 1 && cw->rows != 1 || 13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cw->rows + cw->cols - 1 != class_count || 13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MAT_TYPE(cw->type) != CV_32FC1 && CV_MAT_TYPE(cw->type) != CV_64FC1 ) 13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "params.class_weights must be 1d floating-point vector " 13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "containing as many elements as the number of classes" ); 13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( class_weights = cvCreateMat( cw->rows, cw->cols, CV_64F )); 13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvConvert( cw, class_weights )); 13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvScale( class_weights, class_weights, params.C )); 13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( decision_func = df = (CvSVMDecisionFunc*)cvAlloc( 13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (class_count*(class_count-1)/2)*sizeof(df[0]))); 13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv_tab = (int*)cvMemStorageAlloc( temp_storage, sample_count*sizeof(sv_tab[0]) )); 13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( sv_tab, 0, sample_count*sizeof(sv_tab[0]) ); 13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( class_ranges = (int*)cvMemStorageAlloc( temp_storage, 13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (class_count + 1)*sizeof(class_ranges[0]))); 13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( temp_samples = (const float**)cvMemStorageAlloc( temp_storage, 13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sample_count*sizeof(temp_samples[0]))); 13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( temp_y = (schar*)cvMemStorageAlloc( temp_storage, sample_count)); 13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_ranges[class_count] = 0; 13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSortSamplesByClasses( samples, responses, class_ranges, 0 ); 13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //check that while cross-validation there were the samples from all the classes 13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_ranges[class_count] <= 0 ) 13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "While cross-validation one or more of the classes have " 13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "been fell out of the sample. Try to enlarge <CvSVMParams::k_fold>" ); 13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == NU_SVC ) 14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // check if nu is feasible 14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(i = 0; i < class_count; i++ ) 14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ci = class_ranges[i+1] - class_ranges[i]; 14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = i+1; j< class_count; j++ ) 14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int cj = class_ranges[j+1] - class_ranges[j]; 14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.nu*(ci + cj)*0.5 > MIN( ci, cj ) ) 14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // !!!TODO!!! add some diagnostic 14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; // exit immediately; will release the model and return NULL pointer 14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // train n*(n-1)/2 classifiers 14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < class_count; i++ ) 14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = i+1; j < class_count; j++, df++ ) 14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int si = class_ranges[i], ci = class_ranges[i+1] - si; 14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sj = class_ranges[j], cj = class_ranges[j+1] - sj; 14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double Cp = params.C, Cn = Cp; 14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k1 = 0, sv_count = 0; 14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < ci; k++ ) 14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp_samples[k] = samples[si + k]; 14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp_y[k] = 1; 14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < cj; k++ ) 14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp_samples[ci + k] = samples[sj + k]; 14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp_y[ci + k] = -1; 14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_weights ) 14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cp = class_weights->data.db[i]; 14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cn = class_weights->data.db[j]; 14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !train1( ci + cj, var_count, temp_samples, temp_y, 14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cp, Cn, temp_storage, alpha, df->rho )) 14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < ci + cj; k++ ) 14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count += fabs(alpha[k]) > 0; 14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->sv_count = sv_count; 14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( df->alpha = (double*)cvMemStorageAlloc( temp_storage, 14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count*sizeof(df->alpha[0]))); 14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( df->sv_index = (int*)cvMemStorageAlloc( temp_storage, 14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count*sizeof(df->sv_index[0]))); 14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < ci; k++ ) 14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(alpha[k]) > 0 ) 14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_tab[si + k] = 1; 14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->sv_index[k1] = si + k; 14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->alpha[k1++] = alpha[k]; 14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < cj; k++ ) 14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(alpha[ci + k]) > 0 ) 14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_tab[sj + k] = 1; 14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->sv_index[k1] = sj + k; 14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->alpha[k1++] = alpha[ci + k]; 14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // allocate support vectors and initialize sv_tab 14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0, k = 0; i < sample_count; i++ ) 14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sv_tab[i] ) 14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_tab[i] = ++k; 14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total = k; 14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv = (float**)cvMemStorageAlloc( storage, sv_total*sizeof(sv[0]))); 14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0, k = 0; i < sample_count; i++ ) 14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sv_tab[i] ) 14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv[k] = (float*)cvMemStorageAlloc( storage, sample_size )); 14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( sv[k], samples[i], sample_size ); 14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn k++; 14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df = (CvSVMDecisionFunc*)decision_func; 15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // set sv pointers 15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < class_count; i++ ) 15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = i+1; j < class_count; j++, df++ ) 15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < df->sv_count; k++ ) 15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df->sv_index[k] = sv_tab[df->sv_index[k]]-1; 15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( (unsigned)df->sv_index[k] < (unsigned)sv_total ); 15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = true; 15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVM::train( const CvMat* _train_data, const CvMat* _responses, 15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* _var_idx, const CvMat* _sample_idx, CvSVMParams _params ) 15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* responses = 0; 15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* temp_storage = 0; 15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float** samples = 0; 15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::train" ); 15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int svm_type, sample_count, var_count, sample_size; 15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int block_size = 1 << 16; 15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double* alpha; 15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( set_params( _params )); 15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = _params.svm_type; 15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Prepare training data and related parameters */ 15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvPrepareTrainData( "CvSVM::train", _train_data, CV_ROW_SAMPLE, 15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type != CvSVM::ONE_CLASS ? _responses : 0, 15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::C_SVC || 15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::NU_SVC ? CV_VAR_CATEGORICAL : 15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_VAR_ORDERED, _var_idx, _sample_idx, 15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn false, &samples, &sample_count, &var_count, &var_all, 15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &responses, &class_labels, &var_idx )); 15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sample_size = var_count*sizeof(samples[0][0]); 15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // make the storage block size large enough to fit all 15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // the temporary vectors and output support vectors. 15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sample_count*(int)sizeof(CvSVMKernelRow)); 15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sample_count*2*(int)sizeof(double) + 1024 ); 15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sample_size*2 + 1024 ); 15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( storage = cvCreateMemStorage(block_size)); 15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( temp_storage = cvCreateChildMemStorage(storage)); 15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( alpha = (double*)cvMemStorageAlloc(temp_storage, sample_count*sizeof(double))); 15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create_kernel(); 15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create_solver(); 15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !do_train( svm_type, sample_count, var_count, samples, responses, temp_storage, alpha )) 15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = true; // model has been trained succesfully 15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete solver; 15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn solver = 0; 15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &temp_storage ); 15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &responses ); 15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &samples ); 15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 || !ok ) 15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool CvSVM::train_auto( const CvMat* _train_data, const CvMat* _responses, 15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* _var_idx, const CvMat* _sample_idx, CvSVMParams _params, int k_fold, 15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvParamGrid C_grid, CvParamGrid gamma_grid, CvParamGrid p_grid, 15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvParamGrid nu_grid, CvParamGrid coef_grid, CvParamGrid degree_grid ) 15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool ok = false; 15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* responses = 0; 15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* responses_local = 0; 15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* temp_storage = 0; 15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float** samples = 0; 16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float** samples_local = 0; 16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::train_auto" ); 16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int svm_type, sample_count, var_count, sample_size; 16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int block_size = 1 << 16; 16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double* alpha; 16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, k; 16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvRNG rng = cvRNG(-1); 16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // all steps are logarithmic and must be > 1 16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double degree_step = 10, g_step = 10, coef_step = 10, C_step = 10, nu_step = 10, p_step = 10; 16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double gamma = 0, C = 0, degree = 0, coef = 0, p = 0, nu = 0; 16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_degree = 0, best_gamma = 0, best_coef = 0, best_C = 0, best_nu = 0, best_p = 0; 16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float min_error = FLT_MAX, error; 16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _params.svm_type == CvSVM::ONE_CLASS ) 16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if(!train( _train_data, _responses, _var_idx, _sample_idx, _params )) 16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return true; 16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( k_fold < 2 ) 16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Parameter <k_fold> must be > 1" ); 16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(set_params( _params )); 16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = _params.svm_type; 16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // All the parameters except, possibly, <coef0> are positive. 16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // <coef0> is nonnegative 16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( C_grid.step <= 1 ) 16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_grid.min_val = C_grid.max_val = params.C; 16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_grid.step = 10; 16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(C_grid.check()); 16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( gamma_grid.step <= 1 ) 16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma_grid.min_val = gamma_grid.max_val = params.gamma; 16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma_grid.step = 10; 16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(gamma_grid.check()); 16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( p_grid.step <= 1 ) 16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_grid.min_val = p_grid.max_val = params.p; 16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_grid.step = 10; 16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(p_grid.check()); 16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( nu_grid.step <= 1 ) 16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_grid.min_val = nu_grid.max_val = params.nu; 16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_grid.step = 10; 16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(nu_grid.check()); 16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( coef_grid.step <= 1 ) 16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_grid.min_val = coef_grid.max_val = params.coef0; 16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_grid.step = 10; 16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(coef_grid.check()); 16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( degree_grid.step <= 1 ) 16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_grid.min_val = degree_grid.max_val = params.degree; 16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_grid.step = 10; 16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(degree_grid.check()); 16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // these parameters are not used: 16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.kernel_type != CvSVM::POLY ) 16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_grid.min_val = degree_grid.max_val = params.degree; 16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.kernel_type == CvSVM::LINEAR ) 16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma_grid.min_val = gamma_grid.max_val = params.gamma; 16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.kernel_type != CvSVM::POLY && params.kernel_type != CvSVM::SIGMOID ) 16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_grid.min_val = coef_grid.max_val = params.coef0; 16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::NU_SVC || svm_type == CvSVM::ONE_CLASS ) 16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_grid.min_val = C_grid.max_val = params.C; 16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::C_SVC || svm_type == CvSVM::EPS_SVR ) 16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_grid.min_val = nu_grid.max_val = params.nu; 16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type != CvSVM::EPS_SVR ) 16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_grid.min_val = p_grid.max_val = params.p; 16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( g_step > 1 && degree_step > 1 && coef_step > 1); 16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( p_step > 1 && C_step > 1 && nu_step > 1 ); 16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Prepare training data and related parameters */ 17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(cvPrepareTrainData( "CvSVM::train_auto", _train_data, CV_ROW_SAMPLE, 17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type != CvSVM::ONE_CLASS ? _responses : 0, 17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::C_SVC || 17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::NU_SVC ? CV_VAR_CATEGORICAL : 17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_VAR_ORDERED, _var_idx, _sample_idx, 17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn false, &samples, &sample_count, &var_count, &var_all, 17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &responses, &class_labels, &var_idx )); 17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sample_size = var_count*sizeof(samples[0][0]); 17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // make the storage block size large enough to fit all 17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // the temporary vectors and output support vectors. 17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sample_count*(int)sizeof(CvSVMKernelRow)); 17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sample_count*2*(int)sizeof(double) + 1024 ); 17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sample_size*2 + 1024 ); 17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(storage = cvCreateMemStorage(block_size)); 17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(temp_storage = cvCreateChildMemStorage(storage)); 17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(alpha = (double*)cvMemStorageAlloc(temp_storage, sample_count*sizeof(double))); 17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create_kernel(); 17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create_solver(); 17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int testset_size = sample_count/k_fold; 17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int trainset_size = sample_count - testset_size; 17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int last_testset_size = sample_count - testset_size*(k_fold-1); 17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int last_trainset_size = sample_count - last_testset_size; 17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const bool is_regression = (svm_type == EPS_SVR) || (svm_type == NU_SVR); 17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size_t resp_elem_size = CV_ELEM_SIZE(responses->type); 17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size_t size = 2*last_trainset_size*sizeof(samples[0]); 17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples_local = (const float**) cvAlloc( size ); 17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( samples_local, 0, size ); 17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn responses_local = cvCreateMat( 1, trainset_size, CV_MAT_TYPE(responses->type) ); 17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvZero( responses_local ); 17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // randomly permute samples and responses 17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sample_count; i++ ) 17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i1 = cvRandInt( &rng ) % sample_count; 17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i2 = cvRandInt( &rng ) % sample_count; 17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float* temp; 17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float t; 17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y; 17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( samples[i1], samples[i2], temp ); 17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( is_regression ) 17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( responses->data.fl[i1], responses->data.fl[i2], t ); 17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( responses->data.i[i1], responses->data.i[i2], y ); 17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C = C_grid.min_val; 17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.C = C; 17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma = gamma_grid.min_val; 17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.gamma = gamma; 17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p = p_grid.min_val; 17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.p = p; 17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu = nu_grid.min_val; 17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.nu = nu; 17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef = coef_grid.min_val; 17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.coef0 = coef; 17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree = degree_grid.min_val; 17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.degree = degree; 17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float** test_samples_ptr = (float**)samples; 17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* true_resp = responses->data.ptr; 17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int test_size = testset_size; 17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int train_size = trainset_size; 17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn error = 0; 17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < k_fold; k++ ) 17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( samples_local, samples, sizeof(samples[0])*test_size*k ); 17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( samples_local + test_size*k, test_samples_ptr + test_size, 17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(samples[0])*(sample_count - testset_size*(k+1)) ); 17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( responses_local->data.ptr, responses->data.ptr, resp_elem_size*test_size*k ); 17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( responses_local->data.ptr + resp_elem_size*test_size*k, 17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn true_resp + resp_elem_size*test_size, 17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(samples[0])*(sample_count - testset_size*(k+1)) ); 17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( k == k_fold - 1 ) 17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn test_size = last_testset_size; 18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn train_size = last_trainset_size; 18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn responses_local->cols = last_trainset_size; 18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Train SVM on <train_size> samples 18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !do_train( svm_type, train_size, var_count, 18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (const float**)samples_local, responses_local, temp_storage, alpha ) ) 18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Compute test set error on <test_size> samples 18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat s = cvMat( 1, var_count, CV_32FC1 ); 18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < test_size; i++, true_resp += resp_elem_size, test_samples_ptr++ ) 18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float resp; 18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn s.data.fl = *test_samples_ptr; 18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn resp = predict( &s ); 18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn error += is_regression ? powf( resp - *(float*)true_resp, 2 ) 18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn : ((int)resp != *(int*)true_resp); 18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( min_error > error ) 18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn min_error = error; 18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_degree = degree; 18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_gamma = gamma; 18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_coef = coef; 18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_C = C; 18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_nu = nu; 18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_p = p; 18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree *= degree_grid.step; 18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( degree < degree_grid.max_val ); 18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef *= coef_grid.step; 18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( coef < coef_grid.max_val ); 18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu *= nu_grid.step; 18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( nu < nu_grid.max_val ); 18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p *= p_grid.step; 18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( p < p_grid.max_val ); 18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma *= gamma_grid.step; 18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( gamma < gamma_grid.max_val ); 18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C *= C_grid.step; 18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( C < C_grid.max_val ); 18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn min_error /= (float) sample_count; 18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.C = best_C; 18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.nu = best_nu; 18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.p = best_p; 18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.gamma = best_gamma; 18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.degree = best_degree; 18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.coef0 = best_coef; 18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(ok = do_train( svm_type, sample_count, var_count, samples, responses, temp_storage, alpha )); 18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete solver; 18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn solver = 0; 18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &temp_storage ); 18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &responses ); 18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &responses_local ); 18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &samples ); 18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &samples_local ); 18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 || !ok ) 18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ok; 18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat CvSVM::predict( const CvMat* sample ) const 18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool local_alloc = 0; 18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float result = 0; 18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* row_sample = 0; 18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Qfloat* buffer = 0; 18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::predict" ); 18856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 18876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int class_count; 18896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int var_count, buf_sz; 18906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !kernel ) 18926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "The SVM should be trained first" ); 18936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_count = class_labels ? class_labels->cols : 18956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.svm_type == ONE_CLASS ? 1 : 0; 18966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvPreparePredictData( sample, var_all, var_idx, 18986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_count, 0, &row_sample )); 18996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_count = get_var_count(); 19016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buf_sz = sv_total*sizeof(buffer[0]) + (class_count+1)*sizeof(int); 19036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( buf_sz <= CV_MAX_LOCAL_SIZE ) 19046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( buffer = (Qfloat*)cvStackAlloc( buf_sz )); 19066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn local_alloc = 1; 19076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 19096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( buffer = (Qfloat*)cvAlloc( buf_sz )); 19106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.svm_type == EPS_SVR || 19126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.svm_type == NU_SVR || 19136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.svm_type == ONE_CLASS ) 19146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMDecisionFunc* df = (CvSVMDecisionFunc*)decision_func; 19166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, sv_count = df->sv_count; 19176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double sum = -df->rho; 19186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel->calc( sv_count, var_count, (const float**)sv, row_sample, buffer ); 19206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sv_count; i++ ) 19216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum += buffer[i]*df->alpha[i]; 19226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = params.svm_type == ONE_CLASS ? (float)(sum > 0) : (float)sum; 19246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( params.svm_type == C_SVC || 19266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.svm_type == NU_SVC ) 19276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMDecisionFunc* df = (CvSVMDecisionFunc*)decision_func; 19296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* vote = (int*)(buffer + sv_total); 19306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, k; 19316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( vote, 0, class_count*sizeof(vote[0])); 19336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel->calc( sv_total, var_count, (const float**)sv, row_sample, buffer ); 19346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < class_count; i++ ) 19366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = i+1; j < class_count; j++, df++ ) 19386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double sum = -df->rho; 19406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sv_count = df->sv_count; 19416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < sv_count; k++ ) 19426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum += df->alpha[k]*buffer[df->sv_index[k]]; 19436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vote[sum > 0 ? i : j]++; 19456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 1, k = 0; i < class_count; i++ ) 19496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( vote[i] > vote[k] ) 19516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn k = i; 19526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = (float)(class_labels->data.i[k]); 19556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 19576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "INTERNAL ERROR: Unknown SVM type, " 19586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "the SVM structure is probably corrupted" ); 19596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 19616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sample && (!CV_IS_MAT(sample) || sample->data.fl != row_sample) ) 19636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &row_sample ); 19646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !local_alloc ) 19666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &buffer ); 19676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 19696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 19706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::write_params( CvFileStorage* fs ) 19736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 19746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //CV_FUNCNAME( "CvSVM::write_params" ); 19756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 19776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int svm_type = params.svm_type; 19796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int kernel_type = params.kernel_type; 19806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const char* svm_type_str = 19826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::C_SVC ? "C_SVC" : 19836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::NU_SVC ? "NU_SVC" : 19846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::ONE_CLASS ? "ONE_CLASS" : 19856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::EPS_SVR ? "EPS_SVR" : 19866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::NU_SVR ? "NU_SVR" : 0; 19876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const char* kernel_type_str = 19886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type == CvSVM::LINEAR ? "LINEAR" : 19896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type == CvSVM::POLY ? "POLY" : 19906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type == CvSVM::RBF ? "RBF" : 19916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type == CvSVM::SIGMOID ? "SIGMOID" : 0; 19926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type_str ) 19946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteString( fs, "svm_type", svm_type_str ); 19956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 19966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "svm_type", svm_type ); 19976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // save kernel 19996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, "kernel", CV_NODE_MAP + CV_NODE_FLOW ); 20006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type_str ) 20026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteString( fs, "type", kernel_type_str ); 20036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 20046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "type", kernel_type ); 20056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type == CvSVM::POLY || !kernel_type_str ) 20076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "degree", params.degree ); 20086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type != CvSVM::LINEAR || !kernel_type_str ) 20106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "gamma", params.gamma ); 20116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type == CvSVM::POLY || kernel_type == CvSVM::SIGMOID || !kernel_type_str ) 20136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "coef0", params.coef0 ); 20146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct(fs); 20166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::C_SVC || svm_type == CvSVM::EPS_SVR || 20186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::NU_SVR || !svm_type_str ) 20196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "C", params.C ); 20206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::NU_SVC || svm_type == CvSVM::ONE_CLASS || 20226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type == CvSVM::NU_SVR || !svm_type_str ) 20236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "nu", params.nu ); 20246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::EPS_SVR || !svm_type_str ) 20266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "p", params.p ); 20276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, "term_criteria", CV_NODE_MAP + CV_NODE_FLOW ); 20296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.term_crit.type & CV_TERMCRIT_EPS ) 20306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "epsilon", params.term_crit.epsilon ); 20316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( params.term_crit.type & CV_TERMCRIT_ITER ) 20326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "iterations", params.term_crit.max_iter ); 20336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 20346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 20366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 20376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::write( CvFileStorage* fs, const char* name ) 20406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 20416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::write" ); 20426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 20446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, var_count = get_var_count(), df_count, class_count; 20466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvSVMDecisionFunc* df = decision_func; 20476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_ML_SVM ); 20496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn write_params( fs ); 20516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "var_all", var_all ); 20536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "var_count", var_count ); 20546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_count = class_labels ? class_labels->cols : 20566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn params.svm_type == CvSVM::ONE_CLASS ? 1 : 0; 20576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_count ) 20596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "class_count", class_count ); 20616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_labels ) 20636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWrite( fs, "class_labels", class_labels ); 20646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_weights ) 20666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWrite( fs, "class_weights", class_weights ); 20676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( var_idx ) 20706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWrite( fs, "var_idx", var_idx ); 20716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // write the joint collection of support vectors 20736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "sv_total", sv_total ); 20746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, "support_vectors", CV_NODE_SEQ ); 20756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sv_total; i++ ) 20766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, 0, CV_NODE_SEQ + CV_NODE_FLOW ); 20786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteRawData( fs, sv[i], var_count, "f" ); 20796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 20806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 20836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // write decision functions 20856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df_count = class_count > 1 ? class_count*(class_count-1)/2 : 1; 20866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df = decision_func; 20876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, "decision_functions", CV_NODE_SEQ ); 20896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < df_count; i++ ) 20906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sv_count = df[i].sv_count; 20926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, 0, CV_NODE_MAP ); 20936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteInt( fs, "sv_count", sv_count ); 20946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteReal( fs, "rho", df[i].rho ); 20956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, "alpha", CV_NODE_SEQ+CV_NODE_FLOW ); 20966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteRawData( fs, df[i].alpha, df[i].sv_count, "d" ); 20976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 20986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_count > 1 ) 20996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 21006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartWriteStruct( fs, "index", CV_NODE_SEQ+CV_NODE_FLOW ); 21016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvWriteRawData( fs, df[i].sv_index, df[i].sv_count, "i" ); 21026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 21036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 21046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 21056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( sv_count == sv_total ); 21066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 21076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 21086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 21096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteStruct( fs ); 21106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 21126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 21136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::read_params( CvFileStorage* fs, CvFileNode* svm_node ) 21166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 21176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::read_params" ); 21186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 21206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int svm_type, kernel_type; 21226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMParams _params; 21236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode* tmp_node = cvGetFileNodeByName( fs, svm_node, "svm_type" ); 21256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode* kernel_node; 21266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !tmp_node ) 21276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "svm_type tag is not found" ); 21286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_NODE_TYPE(tmp_node->tag) == CV_NODE_INT ) 21306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = cvReadInt( tmp_node, -1 ); 21316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 21326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 21336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const char* svm_type_str = cvReadString( tmp_node, "" ); 21346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = 21356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( svm_type_str, "C_SVC" ) == 0 ? CvSVM::C_SVC : 21366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( svm_type_str, "NU_SVC" ) == 0 ? CvSVM::NU_SVC : 21376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( svm_type_str, "ONE_CLASS" ) == 0 ? CvSVM::ONE_CLASS : 21386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( svm_type_str, "EPS_SVR" ) == 0 ? CvSVM::EPS_SVR : 21396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( svm_type_str, "NU_SVR" ) == 0 ? CvSVM::NU_SVR : -1; 21406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type < 0 ) 21426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "Missing of invalid SVM type" ); 21436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 21446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_node = cvGetFileNodeByName( fs, svm_node, "kernel" ); 21466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !kernel_node ) 21476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "SVM kernel tag is not found" ); 21486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp_node = cvGetFileNodeByName( fs, kernel_node, "type" ); 21506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !tmp_node ) 21516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "SVM kernel type tag is not found" ); 21526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_NODE_TYPE(tmp_node->tag) == CV_NODE_INT ) 21546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type = cvReadInt( tmp_node, -1 ); 21556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 21566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 21576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const char* kernel_type_str = cvReadString( tmp_node, "" ); 21586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel_type = 21596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( kernel_type_str, "LINEAR" ) == 0 ? CvSVM::LINEAR : 21606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( kernel_type_str, "POLY" ) == 0 ? CvSVM::POLY : 21616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( kernel_type_str, "RBF" ) == 0 ? CvSVM::RBF : 21626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn strcmp( kernel_type_str, "SIGMOID" ) == 0 ? CvSVM::SIGMOID : -1; 21636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel_type < 0 ) 21656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "Missing of invalid SVM kernel type" ); 21666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 21676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.svm_type = svm_type; 21696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.kernel_type = kernel_type; 21706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.degree = cvReadRealByName( fs, kernel_node, "degree", 0 ); 21716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.gamma = cvReadRealByName( fs, kernel_node, "gamma", 0 ); 21726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.coef0 = cvReadRealByName( fs, kernel_node, "coef0", 0 ); 21736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.C = cvReadRealByName( fs, svm_node, "C", 0 ); 21756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.nu = cvReadRealByName( fs, svm_node, "nu", 0 ); 21766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.p = cvReadRealByName( fs, svm_node, "p", 0 ); 21776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.class_weights = 0; 21786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp_node = cvGetFileNodeByName( fs, svm_node, "term_criteria" ); 21806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( tmp_node ) 21816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 21826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.term_crit.epsilon = cvReadRealByName( fs, tmp_node, "epsilon", -1. ); 21836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.term_crit.max_iter = cvReadIntByName( fs, tmp_node, "iterations", -1 ); 21846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.term_crit.type = (_params.term_crit.epsilon >= 0 ? CV_TERMCRIT_EPS : 0) + 21856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (_params.term_crit.max_iter >= 0 ? CV_TERMCRIT_ITER : 0); 21866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 21876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 21886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _params.term_crit = cvTermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 1000, FLT_EPSILON ); 21896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set_params( _params ); 21916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 21936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 21946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvSVM::read( CvFileStorage* fs, CvFileNode* svm_node ) 21976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 21986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const double not_found_dbl = DBL_MAX; 21996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "CvSVM::read" ); 22016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 22036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, var_count, df_count, class_count; 22056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int block_size = 1 << 16, sv_size; 22066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode *sv_node, *df_node; 22076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMDecisionFunc* df; 22086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 22096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !svm_node ) 22116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "The requested element is not found" ); 22126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn clear(); 22146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // read SVM parameters 22166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn read_params( fs, svm_node ); 22176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // and top-level data 22196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total = cvReadIntByName( fs, svm_node, "sv_total", -1 ); 22206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_all = cvReadIntByName( fs, svm_node, "var_all", -1 ); 22216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_count = cvReadIntByName( fs, svm_node, "var_count", var_all ); 22226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_count = cvReadIntByName( fs, svm_node, "class_count", 0 ); 22236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sv_total <= 0 || var_all <= 0 || var_count <= 0 || var_count > var_all || class_count < 0 ) 22256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); 22266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( class_labels = (CvMat*)cvReadByName( fs, svm_node, "class_labels" )); 22286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( class_weights = (CvMat*)cvReadByName( fs, svm_node, "class_weights" )); 22296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( var_idx = (CvMat*)cvReadByName( fs, svm_node, "comp_idx" )); 22306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_count > 1 && (!class_labels || 22326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn !CV_IS_MAT(class_labels) || class_labels->cols != class_count)) 22336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "Array of class labels is missing or invalid" ); 22346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( var_count < var_all && (!var_idx || !CV_IS_MAT(var_idx) || var_idx->cols != var_count) ) 22366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "var_idx array is missing or invalid" ); 22376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // read support vectors 22396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_node = cvGetFileNodeByName( fs, svm_node, "support_vectors" ); 22406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !sv_node || !CV_NODE_IS_SEQ(sv_node->tag)) 22416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "Missing or invalid sequence of support vectors" ); 22426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sv_total*(int)sizeof(CvSVMKernelRow)); 22446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, sv_total*2*(int)sizeof(double)); 22456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = MAX( block_size, var_all*(int)sizeof(double)); 22466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( storage = cvCreateMemStorage( block_size )); 22476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv = (float**)cvMemStorageAlloc( storage, 22486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total*sizeof(sv[0]) )); 22496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvStartReadSeq( sv_node->data.seq, &reader, 0 )); 22516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_size = var_count*sizeof(sv[0][0]); 22526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sv_total; i++ ) 22546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode* sv_elem = (CvFileNode*)reader.ptr; 22566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( var_count == 1 || (CV_NODE_IS_SEQ(sv_elem->tag) && 22576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_elem->data.seq->total == var_count) ); 22586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( sv[i] = (float*)cvMemStorageAlloc( storage, sv_size )); 22606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvReadRawData( fs, sv_elem, sv[i], "f" )); 22616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( sv_node->data.seq->elem_size, reader ); 22626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // read decision functions 22656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df_count = class_count > 1 ? class_count*(class_count-1)/2 : 1; 22666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df_node = cvGetFileNodeByName( fs, svm_node, "decision_functions" ); 22676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !df_node || !CV_NODE_IS_SEQ(df_node->tag) || 22686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df_node->data.seq->total != df_count ) 22696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "decision_functions is missing or is not a collection " 22706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "or has a wrong number of elements" ); 22716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( df = decision_func = (CvSVMDecisionFunc*)cvAlloc( df_count*sizeof(df[0]) )); 22736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( df_node->data.seq, &reader, 0 ); 22746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < df_count; i++ ) 22766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode* df_elem = (CvFileNode*)reader.ptr; 22786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode* alpha_node = cvGetFileNodeByName( fs, df_elem, "alpha" ); 22796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sv_count = cvReadIntByName( fs, df_elem, "sv_count", -1 ); 22816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( sv_count <= 0 ) 22826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "sv_count is missing or non-positive" ); 22836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df[i].sv_count = sv_count; 22846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df[i].rho = cvReadRealByName( fs, df_elem, "rho", not_found_dbl ); 22866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fabs(df[i].rho - not_found_dbl) < DBL_EPSILON ) 22876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "rho is missing" ); 22886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !alpha_node ) 22906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "alpha is missing in the decision function" ); 22916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( df[i].alpha = (double*)cvMemStorageAlloc( storage, 22936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count*sizeof(df[i].alpha[0]))); 22946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( sv_count == 1 || CV_NODE_IS_SEQ(alpha_node->tag) && 22956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn alpha_node->data.seq->total == sv_count ); 22966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvReadRawData( fs, alpha_node, df[i].alpha, "d" )); 22976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_count > 1 ) 22996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFileNode* index_node = cvGetFileNodeByName( fs, df_elem, "index" ); 23016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !index_node ) 23026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsParseError, "index is missing in the decision function" ); 23036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( df[i].sv_index = (int*)cvMemStorageAlloc( storage, 23046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count*sizeof(df[i].sv_index[0]))); 23056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( sv_count == 1 || CV_NODE_IS_SEQ(index_node->tag) && 23066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index_node->data.seq->total == sv_count ); 23076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvReadRawData( fs, index_node, df[i].sv_index, "i" )); 23086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 23106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df[i].sv_index = 0; 23116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( df_node->data.seq->elem_size, reader ); 23136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn create_kernel(); 23166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 23186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 23196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0 23216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void* 23236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCloneSVM( const void* _src ) 23246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 23256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMModel* dst = 0; 23266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "icvCloneSVM" ); 23286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 23306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvSVMModel* src = (const CvSVMModel*)_src; 23326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int var_count, class_count; 23336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, sv_total, df_count; 23346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sv_size; 23356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SVM(src) ) 23376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( !src ? CV_StsNullPtr : CV_StsBadArg, "Input pointer is NULL or invalid" ); 23386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // 0. create initial CvSVMModel structure 23406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dst = icvCreateSVM() ); 23416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->params = src->params; 23426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->params.weight_labels = 0; 23436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->params.weights = 0; 23446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->var_all = src->var_all; 23466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( src->class_labels ) 23476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->class_labels = cvCloneMat( src->class_labels ); 23486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( src->class_weights ) 23496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->class_weights = cvCloneMat( src->class_weights ); 23506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( src->comp_idx ) 23516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->comp_idx = cvCloneMat( src->comp_idx ); 23526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn var_count = src->comp_idx ? src->comp_idx->cols : src->var_all; 23546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn class_count = src->class_labels ? src->class_labels->cols : 23556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn src->params.svm_type == CvSVM::ONE_CLASS ? 1 : 0; 23566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total = dst->sv_total = src->sv_total; 23576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dst->storage = cvCreateMemStorage( src->storage->block_size )); 23586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dst->sv = (float**)cvMemStorageAlloc( dst->storage, 23596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_total*sizeof(dst->sv[0]) )); 23606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_size = var_count*sizeof(dst->sv[0][0]); 23626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < sv_total; i++ ) 23646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dst->sv[i] = (float*)cvMemStorageAlloc( dst->storage, sv_size )); 23666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( dst->sv[i], src->sv[i], sv_size ); 23676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn df_count = class_count > 1 ? class_count*(class_count-1)/2 : 1; 23706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dst->decision_func = cvAlloc( df_count*sizeof(CvSVMDecisionFunc) )); 23726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < df_count; i++ ) 23746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvSVMDecisionFunc *sdf = 23766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (const CvSVMDecisionFunc*)src->decision_func+i; 23776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMDecisionFunc *ddf = 23786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (CvSVMDecisionFunc*)dst->decision_func+i; 23796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sv_count = sdf->sv_count; 23806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ddf->sv_count = sv_count; 23816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ddf->rho = sdf->rho; 23826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ddf->alpha = (double*)cvMemStorageAlloc( dst->storage, 23836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count*sizeof(ddf->alpha[0]))); 23846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( ddf->alpha, sdf->alpha, sv_count*sizeof(ddf->alpha[0])); 23856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( class_count > 1 ) 23876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ddf->sv_index = (int*)cvMemStorageAlloc( dst->storage, 23896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sv_count*sizeof(ddf->sv_index[0]))); 23906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( ddf->sv_index, sdf->sv_index, sv_count*sizeof(ddf->sv_index[0])); 23916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 23936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ddf->sv_index = 0; 23946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 23976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 && dst ) 23996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvReleaseSVM( &dst ); 24006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return dst; 24026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 24036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int icvRegisterSVMType() 24056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 24066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTypeInfo info; 24076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( &info, 0, sizeof(info) ); 24086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.flags = 0; 24106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.header_size = sizeof( info ); 24116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.is_instance = icvIsSVM; 24126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.release = (CvReleaseFunc)icvReleaseSVM; 24136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.read = icvReadSVM; 24146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.write = icvWriteSVM; 24156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.clone = icvCloneSVM; 24166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info.type_name = CV_TYPE_NAME_ML_SVM; 24176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvRegisterType( &info ); 24186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 1; 24206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 24216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int svm = icvRegisterSVMType(); 24246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* The function trains SVM model with optimal parameters, obtained by using cross-validation. 24266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennThe parameters to be estimated should be indicated by setting theirs values to FLT_MAX. 24276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennThe optimal parameters are saved in <model_params> */ 24286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvStatModel* 24296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvTrainSVM_CrossValidation( const CvMat* train_data, int tflag, 24306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* responses, 24316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvStatModelParams* model_params, 24326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvStatModelParams* cross_valid_params, 24336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* comp_idx, 24346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvMat* sample_idx, 24356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvParamGrid* degree_grid, 24366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvParamGrid* gamma_grid, 24376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvParamGrid* coef_grid, 24386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvParamGrid* C_grid, 24396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvParamGrid* nu_grid, 24406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvParamGrid* p_grid ) 24416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 24426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvStatModel* svm = 0; 24436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvTainSVMCrossValidation"); 24456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 24466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double degree_step = 7, 24486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn g_step = 15, 24496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_step = 14, 24506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_step = 20, 24516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_step = 5, 24526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_step = 7; // all steps must be > 1 24536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double degree_begin = 0.01, degree_end = 2; 24546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double g_begin = 1e-5, g_end = 0.5; 24556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double coef_begin = 0.1, coef_end = 300; 24566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double C_begin = 0.1, C_end = 6000; 24576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double nu_begin = 0.01, nu_end = 0.4; 24586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double p_begin = 0.01, p_end = 100; 24596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double rate = 0, gamma = 0, C = 0, degree = 0, coef = 0, p = 0, nu = 0; 24616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_rate = 0; 24636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_degree = degree_begin; 24646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_gamma = g_begin; 24656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_coef = coef_begin; 24666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_C = C_begin; 24676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_nu = nu_begin; 24686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double best_p = p_begin; 24696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSVMModelParams svm_params, *psvm_params; 24716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvCrossValidationParams* cv_params = (CvCrossValidationParams*)cross_valid_params; 24726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int svm_type, kernel; 24736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int is_regression; 24746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !model_params ) 24766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "" ); 24776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !cv_params ) 24786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "" ); 24796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params = *(CvSVMModelParams*)model_params; 24816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params = (CvSVMModelParams*)model_params; 24826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_type = svm_params.svm_type; 24836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn kernel = svm_params.kernel_type; 24846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.degree = svm_params.degree > 0 ? svm_params.degree : 1; 24866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.gamma = svm_params.gamma > 0 ? svm_params.gamma : 1; 24876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.coef0 = svm_params.coef0 > 0 ? svm_params.coef0 : 1e-6; 24886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.C = svm_params.C > 0 ? svm_params.C : 1; 24896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.nu = svm_params.nu > 0 ? svm_params.nu : 1; 24906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.p = svm_params.p > 0 ? svm_params.p : 1; 24916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( degree_grid ) 24936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(degree_grid->max_val == 0 && degree_grid->min_val == 0 && 24956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_grid->step == 0) ) 24966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( degree_grid->min_val > degree_grid->max_val ) 24986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 24996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "low bound of grid should be less then the upper one"); 25006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( degree_grid->step <= 1 ) 25016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "grid step should be greater 1" ); 25026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_begin = degree_grid->min_val; 25036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_end = degree_grid->max_val; 25046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_step = degree_grid->step; 25056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_begin = degree_end = svm_params.degree; 25096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( gamma_grid ) 25116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(gamma_grid->max_val == 0 && gamma_grid->min_val == 0 && 25136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma_grid->step == 0) ) 25146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( gamma_grid->min_val > gamma_grid->max_val ) 25166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 25176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "low bound of grid should be less then the upper one"); 25186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( gamma_grid->step <= 1 ) 25196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "grid step should be greater 1" ); 25206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn g_begin = gamma_grid->min_val; 25216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn g_end = gamma_grid->max_val; 25226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn g_step = gamma_grid->step; 25236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn g_begin = g_end = svm_params.gamma; 25276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( coef_grid ) 25296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(coef_grid->max_val == 0 && coef_grid->min_val == 0 && 25316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_grid->step == 0) ) 25326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( coef_grid->min_val > coef_grid->max_val ) 25346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 25356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "low bound of grid should be less then the upper one"); 25366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( coef_grid->step <= 1 ) 25376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "grid step should be greater 1" ); 25386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_begin = coef_grid->min_val; 25396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_end = coef_grid->max_val; 25406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_step = coef_grid->step; 25416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_begin = coef_end = svm_params.coef0; 25456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( C_grid ) 25476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(C_grid->max_val == 0 && C_grid->min_val == 0 && C_grid->step == 0)) 25496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( C_grid->min_val > C_grid->max_val ) 25516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 25526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "low bound of grid should be less then the upper one"); 25536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( C_grid->step <= 1 ) 25546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "grid step should be greater 1" ); 25556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_begin = C_grid->min_val; 25566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_end = C_grid->max_val; 25576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_step = C_grid->step; 25586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_begin = C_end = svm_params.C; 25626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( nu_grid ) 25646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if(!(nu_grid->max_val == 0 && nu_grid->min_val == 0 && nu_grid->step==0)) 25666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( nu_grid->min_val > nu_grid->max_val ) 25686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 25696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "low bound of grid should be less then the upper one"); 25706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( nu_grid->step <= 1 ) 25716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "grid step should be greater 1" ); 25726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_begin = nu_grid->min_val; 25736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_end = nu_grid->max_val; 25746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_step = nu_grid->step; 25756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_begin = nu_end = svm_params.nu; 25796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( p_grid ) 25816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(p_grid->max_val == 0 && p_grid->min_val == 0 && p_grid->step == 0)) 25836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( p_grid->min_val > p_grid->max_val ) 25856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, 25866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "low bound of grid should be less then the upper one"); 25876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( p_grid->step <= 1 ) 25886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "grid step should be greater 1" ); 25896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_begin = p_grid->min_val; 25906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_end = p_grid->max_val; 25916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_step = p_grid->step; 25926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_begin = p_end = svm_params.p; 25966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // these parameters are not used: 25986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel != CvSVM::POLY ) 25996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn degree_begin = degree_end = svm_params.degree; 26006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel == CvSVM::LINEAR ) 26026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn g_begin = g_end = svm_params.gamma; 26036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( kernel != CvSVM::POLY && kernel != CvSVM::SIGMOID ) 26056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn coef_begin = coef_end = svm_params.coef0; 26066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::NU_SVC || svm_type == CvSVM::ONE_CLASS ) 26086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn C_begin = C_end = svm_params.C; 26096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type == CvSVM::C_SVC || svm_type == CvSVM::EPS_SVR ) 26116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nu_begin = nu_end = svm_params.nu; 26126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( svm_type != CvSVM::EPS_SVR ) 26146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_begin = p_end = svm_params.p; 26156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn is_regression = cv_params->is_regression; 26176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_rate = is_regression ? FLT_MAX : 0; 26186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( g_step > 1 && degree_step > 1 && coef_step > 1); 26206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( p_step > 1 && C_step > 1 && nu_step > 1 ); 26216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( degree = degree_begin; degree <= degree_end; degree *= degree_step ) 26236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.degree = degree; 26256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf("degree = %.3f\n", degree ); 26266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( gamma= g_begin; gamma <= g_end; gamma *= g_step ) 26276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.gamma = gamma; 26296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf(" gamma = %.3f\n", gamma ); 26306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( coef = coef_begin; coef <= coef_end; coef *= coef_step ) 26316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.coef0 = coef; 26336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf(" coef = %.3f\n", coef ); 26346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( C = C_begin; C <= C_end; C *= C_step ) 26356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.C = C; 26376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf(" C = %.3f\n", C ); 26386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( nu = nu_begin; nu <= nu_end; nu *= nu_step ) 26396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.nu = nu; 26416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf(" nu = %.3f\n", nu ); 26426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( p = p_begin; p <= p_end; p *= p_step ) 26436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int well; 26456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn svm_params.p = p; 26466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf(" p = %.3f\n", p ); 26476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(rate = cvCrossValidation( train_data, tflag, responses, &cvTrainSVM, 26496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cross_valid_params, (CvStatModelParams*)&svm_params, comp_idx, sample_idx )); 26506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn well = rate > best_rate && !is_regression || rate < best_rate && is_regression; 26526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( well || (rate == best_rate && C < best_C) ) 26536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_rate = rate; 26556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_degree = degree; 26566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_gamma = gamma; 26576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_coef = coef; 26586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_C = C; 26596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_nu = nu; 26606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn best_p = p; 26616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf(" rate = %.2f\n", rate ); 26636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //printf("The best:\nrate = %.2f%% degree = %f gamma = %f coef = %f c = %f nu = %f p = %f\n", 26706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // best_rate, best_degree, best_gamma, best_coef, best_C, best_nu, best_p ); 26716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params->C = best_C; 26736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params->nu = best_nu; 26746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params->p = best_p; 26756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params->gamma = best_gamma; 26766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params->degree = best_degree; 26776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn psvm_params->coef0 = best_coef; 26786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL(svm = cvTrainSVM( train_data, tflag, responses, model_params, comp_idx, sample_idx )); 26806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 26826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return svm; 26846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 26856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 26876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */ 26896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2690