使用模板表达式的向量类

类别:编程语言 点击:0 评论:0 推荐:

// numeric.h

#ifndef _NUMERIC_H_
#define _NUMERIC_H_

#include <memory>       // memcpy
#include <iostream>     // std::
using namespace std;

namespace numeric {

#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) > (b)) ? (b) : (a))

template <class T>
class expr_add
{
public:
    static inline T apply(const T& a, const T& b)
        {
            return a + b;
        }
};

template <class T>
class expr_sub
{
public:
    static inline T apply(const T& a, const T& b)
        {
            return a - b;
        }
};

template <class T>
class expr_mul
{
public:
    static inline T apply(const T& a, const T& b)
        {
            return a * b;
        }
};

template <class T>
class expr_div
{
public:
    static inline T apply(const T& a, const T& b)
        {
            return a / b;
        }
};

template <class A, class B, class Op>
class tpl_expr
{
    const  A& a_;
    const  B& b_;

public:
    tpl_expr(const A& a, const B& b) : a_(a), b_(b) { }

    inline double operator[](size_t i) const
        {
            return Op::apply(a_[i], b_[i]);
        }
};

template <class B, class Op>
class tpl_expr <double, B, Op>
{
    const double& a_;
    const B&      b_;

public:
    tpl_expr(const double& a, const B& b) : a_(a), b_(b) { }

    inline double operator[](size_t i) const
    {
        return Op::apply(a_, b_[i]);
    }
};

template <class B, class Op>
class tpl_expr <int, B, Op>
{
    const int& a_;
    const B&   b_;

public:
    tpl_expr(const int& a, const B& b) : a_(a), b_(b) { }

    inline double operator[](size_t i) const
    {
        return Op::apply(a_, b_[i]);
    }
};

template <class A, class Op>
class tpl_expr <A, double, Op>
{
    const A&      a_;
    const double& b_;

public:
    tpl_expr(const A& a, const double& b) : a_(a), b_(b) { }

    inline double operator[](size_t i) const
    {
        return Op::apply(a_[i], b_);
    }
};

template <class A, class Op>
class tpl_expr <A, int, Op>
{
    const A&   a_;
    const int& b_;

public:
    tpl_expr(const A& a, const int& b) : a_(a), b_(b) { }

    inline double operator[](size_t i) const
    {
        return Op::apply(a_[i], b_);
    }
};

template <class A, class B>
tpl_expr<A, B, expr_add<double> > operator+(const A& a, const B& b)
{
    return tpl_expr<A, B, expr_add<double> >(a, b);
}

template <class A, class B>
tpl_expr<A, B, expr_sub<double> > operator-(const A& a, const B& b)
{
    return tpl_expr<A, B, expr_sub<double> >(a, b);
}

template <class A, class B>
tpl_expr<A, B, expr_mul<double> > operator*(const A& a, const B& b)
{
    return tpl_expr<A, B, expr_mul<double> >(a, b);
}

template <class A, class B>
tpl_expr<A, B, expr_div<double> > operator/(const A& a, const B& b)
{
    return tpl_expr<A, B, expr_div<double> >(a, b);
}

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

class vector
{
protected:
    size_t  dim;
    double *ets;

public:
    // 由已知向量个数和向量元素数组来构造一个向量
    vector(size_t n, const double* const pd)
        : dim(n)
        {
            ets = new double[dim];
            memcpy(ets, pd, dim*sizeof(double));
        }
   
    vector(size_t n = 0, double d = 0.0)
        : dim(n)
        {
            ets = new double[dim];
            for (size_t i=0; i<dim; ++i) {
                ets[i] = d;
            }
        }
   
    vector(const vector& v)
        {
            dim = v.dim;
            ets = new double[dim];
            memcpy(ets, v.ets, sizeof(double)*dim);
        }

    vector& operator=(const vector& v)
        {
            if (this != &v) {   // 防止自己拷贝自己
                if (dim != v.dim) {
                    exit(1);
                }
                memcpy(ets, v.ets, sizeof(double)*dim);
            }
            return *this;
        }

    ~vector()      
        {
            delete[] ets;
        }

public:
    inline double operator[](size_t i) const
        {
            return ets[i];
        }
   
    inline double& operator[](size_t i)
        {
            return ets[i];
        }

public:
    size_t get_dim() const 
        {
            return dim;
        }

    double* get_ptr() const
        {
            return ets;
        }

    double sum_element() const
        {
            double tmp = 0;
            for (size_t i=0; i<dim; ++i) {
                tmp += ets[i];
            }
            return tmp;
        }

    double min_element() const
        {
            double tmp = ets[0];
            for (size_t i=0; i<dim; ++i) {
                if (tmp > ets[i]) {
                    tmp = ets[i];
                }
            }
            return tmp;
        }

    double max_element() const
        {
            double tmp = ets[0];
            for (size_t i=0; i<dim; ++i) {
                if (tmp < ets[i]) {
                    tmp = ets[i];
                }
            }
            return tmp;
        }

public:
    vector& operator+()
        {
            return *this;
        }

    vector& operator-()
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] = -ets[i];
            }
            return *this;
        }

public:
    vector& operator+=(const vector& v)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] += v[i];
            }
            return *this;
        }

    vector& operator-=(const vector& v)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] -= v[i];
            }
            return *this;
        }

    vector& operator*=(const vector& v)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] *= v[i];
            }
            return *this;
        }

    vector& operator/=(const vector& v)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] /= v[i];
            }
            return *this;
        }

    vector& operator+=(const double& d)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] += d;
            }
            return *this;
        }

    vector& operator-=(const double& d)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] -= d;
            }
            return *this;
        }

    vector& operator*=(const double& d)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] *= d;
            }
            return *this;
        }

    vector& operator/=(const double& d)
        {
            double tmp = 1/d;
            for (size_t i=0; i<dim; ++i) {
                ets[i] *= tmp;
            }
            return *this;
        }

public:
    template <class A, class B, class Op>
    vector& operator=(const tpl_expr<A, B, Op>& expr)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] = expr[i];
            }
            return *this;
        }

    template <class A, class B, class Op>
    vector& operator+=(const tpl_expr<A, B, Op>& expr)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] += expr[i];
            }
            return *this;
        }

    template <class A, class B, class Op>
    vector& operator-=(const tpl_expr<A, B, Op>& expr)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] -= expr[i];
            }
            return *this;
        }

    template <class A, class B, class Op>
    vector& operator*=(const tpl_expr<A, B, Op>& expr)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] *= expr[i];
            }
            return *this;
        }

    template <class A, class B, class Op>
    vector& operator/=(const tpl_expr<A, B, Op>& expr)
        {
            for (size_t i=0; i<dim; ++i) {
                ets[i] /= expr[i];
            }
            return *this;
        }
};

};

#endif  // _NUMERIC_H_

// test.cpp

#include <ctime>
#include <iostream>
#include <valarray>
using namespace std;

#include "numeric.h"
using namespace numeric;

void main()
{
    int m = 10000, n=10000;
//  vector x(m, 1), y(m, 2), z(m, 3);
    valarray<double> x(1, m), y(2, m), z(3, m);

    clock_t time;

    time = clock();
    for (size_t i=0; i<n; ++i) {
        z = 0.5-(x - y)*1.0;
    }

    time = clock() - time;

    cout << z[0] << endl;
    cout << time/1000.0 << endl;
}

本文地址:http://com.8s8s.com/it/it26660.htm