boost/uBLAS,Primal Perceptron Algorithm,重定向

来源:互联网 发布:龙之信条捏脸数据 编辑:程序博客网 时间:2024/06/06 14:21

 

今天写了一小段代码,一是试用一个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
+1false);
        
        w 
= zero_vector<double>(N+1);

        
if (__debug) {
            std::cout
<<"" << x<< std::endl;
            std::cout
<<"" << y<< std::endl;
            std::cout
<<"" << 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。

原创粉丝点击