今天写了一小段代码,一是试用一个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
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
static
const
bool
__debug
=
true
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using
namespace
boost::numeric::ublas;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
BinaryTrainingData
...
{
public:
unsigned N,L;
matrix<double> x;
vector<int> y;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
void read() ...{
scanf("%u %u", &N, &L);
x.resize(L,N, false);
y.resize(L);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
for (unsigned i = 0; i<L; ++i) ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
for (unsigned j=0; j<N; j++) ...{
scanf("%lf", &(x(i,j)));
}
scanf("%d", &(y(i)) );
}
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
LinearPrimal
...
{
private:
unsigned N,L;
matrix<double> x;
vector<int> y;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public:
vector<double> w;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
project(x, range(0,L), range(0,N)) = data.x;
y = data.y;
w.resize(N+1, false);
w = zero_vector<double>(N+1);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (__debug) ...{
std::cout<<"x " << x<< std::endl;
std::cout<<"y " << y<< std::endl;
std::cout<<"w " << w<< std::endl;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
void operator ()(double yita) ...{
assert(yita>0);
column(x,N) = scalar_vector<double>(L,0.0);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
double t;
double R = -1.0;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
bool mistake;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
do ...{
mistake = false;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
for (unsigned i=0; i<L; ++i) ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if ( y(i)*inner_prod(w, row(x,i)) <=0 ) ...{
w += w + yita * y(i) * row(x,i);
mistake = true;
}
}
} while(mistake);
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
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()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
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。