今天写了一小段代码,一是试用一个uBLAS,二是学习一下Preceptron Algorithm的最原始形式,三是意外用了一下file重定向到stdin的功能。
#include <stdio.h>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
static const bool __debug = true;
using namespace boost::numeric::ublas;

class BinaryTrainingData ...{
public:
unsigned N,L;
matrix<double> x;
vector<int> y;
void read() ...{
scanf("%u %u", &N, &L);
x.resize(L,N, false);
y.resize(L);

for (unsigned i = 0; i<L; ++i) ...{
for (unsigned j=0; j<N; j++) ...{
scanf("%lf", &(x(i,j)));
}
scanf("%d", &(y(i)) );
}
}
};

class LinearPrimal ...{
private:
unsigned N,L;
matrix<double> x;
vector<int> y;
public:
vector<double> w;

LinearPrimal(const BinaryTrainingData & data) ...{
assert(data.N>=1);
assert(data.L>=1);
N = data.N;
L = data.L;
x.resize(L,N+1,false);
y.resize(L,false);
project(x, range(0,L), range(0,N)) = data.x;
y = data.y;
w.resize(N+1, false);
w = zero_vector<double>(N+1);

if (__debug) ...{
std::cout<<"x " << x<< std::endl;
std::cout<<"y " << y<< std::endl;
std::cout<<"w " << w<< std::endl;
}
}

void operator ()(double yita) ...{
assert(yita>0);
column(x,N) = scalar_vector<double>(L,0.0);
double t;
double R = -1.0;
for (unsigned i=0; i<L; ++i) ...{
t = norm_2(row(x,i));
if (t>R) R = t;
}
column(x,N) = scalar_vector<double>(L,R);
bool mistake;
do ...{
mistake = false;
for (unsigned i=0; i<L; ++i) ...{
if ( y(i)*inner_prod(w, row(x,i)) <=0 ) ...{
w += w + yita * y(i) * row(x,i);
mistake = true;
}
}
} while(mistake);
}
};

int main() ...{
BinaryTrainingData data;
freopen ("input.txt","r",stdin);
data.read();
fclose(stdin);
std::cout<<data.x<<std::endl;
std::cout<<data.y<<std::endl;
LinearPrimal lp(data);
lp(0.1);
std::cout<<"w = "<<lp.w<<std::endl;
return 0;
}boost/uBLAS与blitz一样,也是专用于数值运算的库,都运用了大量template expression。虽然uBLAS不像blitz那样可以创建高维数组,而只能创建一维的vector和二维的matrix,但易用性方面,确大大好于blitz。尽管两者的效率我还未曾比过,也没读过相关的比较数据,但通过这次试用以及对boost其它库的试用,我决定以后都用uBLAS来实现我的数值运算。
以下介绍一些区别
boost/uBLAS使用时只要引用.hpp文件就行了,而blitz需要引用.lib文件,而且若要开启debug功能,又要引用另一不同的.lib文件,设置上麻烦了一些。
blitz中创建数组一般用array<double, 4> a(3,3,3,3)这样的形式;而uBLAS中,只有matrix和vector,但却有scalar_matrix,zero_matrix,scalar_vector等等节约存储的形式。
blitz中引用array的部分时,一般使用a(Range(1,3),Range::all())的形式,但得到的这部分引用,却常不能再用内置函数进行处理;uBLAS中,也有range,但还有row(),column这样方便的引用方式,引用后,仍能正常使用矩阵或向量函数进行处理。
uBLAS中包含了常用的矩阵和向量函数,如内积,外积,矩阵相乘,一阶矩,二阶矩等等;但blitz中只有少数几个,如内积,求和等,而且使用条件比较严格。
关于Perceptron Algorithm
这是用于线性分类的算法,代码中写的是最原始的形式,不多介绍
重定向
将输入文件,重定向到标准输入设备stdin是测试数据中常使用的方法。测试数据时,有时希望从文件读入,但有时希望手工输入。将输入数据的代码分两个版本cin/fin是个麻烦的事情,但如果用重定向,则改变输入是个两句话的简单事情。
#include <iostream>
using namespace std;
int main()
...{
int a;
freopen ("in.in","r",stdin);
freopen ("out.out","w",stdout);
cin>>a;
cout<<a<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}当io流与stdin/stdout同步时,还可以使用printf与scanf。
本文介绍了使用boost/uBLAS库实现Perceptron算法的过程,并对比了uBLAS与blitz库的区别,包括易用性和功能上的差异。
4648

被折叠的 条评论
为什么被折叠?



