Update:2014-2-26 LinJM @HQU 『 libsvm专栏地址:http://blog.csdn.net/column/details/libsvm.html 』
svm.cpp总共有3159行代码,实现了svm算法的核心功能,里面总共有Cache、Kernel、ONE_CLASS_Q、QMatrix、Solver、Solver_NU、SVC_Q、SVR_Q 8个类(如下图1所示),而它们之间的继承和组合关系如图2、图3所示。在这些类中Cache、Kernel、Solver是核心类,对整个算法起支撑作用。在以后的博文中我们将对这3个核心类做重点注解分析,另外还将对svm.cpp中的svm_train函数做一个注解分析。
图1
图2
图3
#include "svm.h" int libsvm_version = LIBSVM_VERSION; typedef float Qfloat; typedef signed char schar; //inline函数解决频繁调用小函数大量消耗栈空间;static函数为静态函数/或内部函数,指函数的调用范围只局限于本文件 #ifndef min template <class T> static inline T min(T x,T y) { return (x<y)?x:y; } #endif #ifndef max template <class T> static inline T max(T x,T y) { return (x>y)?x:y; } #endif template <class T> static inline void swap(T& x, T& y) { T t=x; x=y; y=t; }
template <class S, class T> static inline void clone(T*& dst, S* src, int n) { dst = new T[n]; memcpy((void *)dst,(void *)src,sizeof(T)*n); }
static inline double powi(double base, int times) { double tmp = base, ret = 1.0; for(int t=times; t>0; t/=2) { if(t%2==1) ret*=tmp; tmp = tmp * tmp; } return ret; }
static void print_string_stdout(const char *s) { fputs(s,stdout); fflush(stdout); } static void (*svm_print_string) (const char *) = &print_string_stdout; #if 1 static void info(const char *fmt,...) { char buf[BUFSIZ]; va_list ap; va_start(ap,fmt); vsprintf(buf,fmt,ap); va_end(ap); (*svm_print_string)(buf); } #else static void info(const char *fmt,...) {} #endif
在libsvm中有如下代码:
static void print_string_stdout(const char *s) { fputs(s,stdout); fflush(stdout); } static void (*svm_print_string) (const char *) = &print_string_stdout;我在论坛中曾经发帖:
看了Pump天天学习同学的回复,我才回想起来:第六行那原来是个函数指针,平时没用到,就给忘了,只能拿出教材重新来学习一遍:
函数指针是指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关:
// pf points to function returning bool thar takes two const string references bool (*pf) (const string &, const string &);这个语句将pf声明为指向函数的指针,它所指向的函数带有两个const string &类型的形参和bool类型的返回值。
注意:*pf两侧的圆括号是必需的,若没有,则就不是函数指针了。
// declares a function named pf that returns a bool* bool *pf (const string &, const string &)
函数指针类型相当冗长。使用typedef为指针类型定义同义词,可将函数指针的使用大大简化
typedef bool (*cmpFn)(const string &, const string &)该定义表示cmpFn是一种指向函数的指针类型的名字。该指针类型为:“指向返回bool类型并带有两个const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用cmpFn即可,不必每次都把整个函数类型声明全部写出来。
通过指针调用函数
指向函数的指针可用于调用它所指向的函数,可以不需要使用解引用操作符,直接通过指针调用函数:
bool lengthCmp(const string&, const string &); cmpFn pf = lengthCmp; lengthCmp=("hi","bye");//direct call pf("hi","bye");//equivalent call: pf1 implicitly dereferenced (*pf)("hi","bye");//equivalent call: pf1 explicitly dereferenced
Ref:《C++ Primer 4th》pp237-239
本文地址:http://blog.csdn.net/linj_m/article/details/19542421
微博:林建民-机器视觉