精华内容
下载资源
问答
  • matrix.h
    千次阅读
    2017-05-05 08:04:01

    matrix.h头文件实现功能如其名,它定义了两个类,分别为:

    class Matrix_;
    class Matrix;

    其中Matrix继承于Matrix_,其中Matrix_提供了对矩阵对象最为基本的访问操作,序列化操作。而Matrix是用了模版的方法扩大了矩阵对象的灵活性,让其适用于更多的数据类型。

    下面我们来看看Matrix_类。

    类成员:

    size_t rows;
    size_t cols;
    size_t stride;
    flann_datatype_t type;
    uchar * data;

    其中rows标明矩阵的行数,cols表明矩阵的列数,stride为步伐,也就是一个特征的长度,单位字节。type标明该矩阵所储存的数据类型。data表明该矩阵指向的数据结构的首部(头指针)。

    类方法:

    Matrix_();
    Matrix_(void * data_,size_t rows_,size_t cols_,flann_datatype_t type_,size_t stride_=0));
    inline void* operator[](size_t index)const ;
    void * ptr() const;
    void serialize(Archive& ar);

    前两个为构造函数,不多叙述。
    第三个为重载操作符[],根据索引号获得相应特征的头指针。
    void * ptr() const,直接返回data。
    seriallize(Archive & ar);将对象矩阵序列化,若Archive类型为OutputArchive,则是将矩阵存储在OutputArchive对应的文件中,存储的顺序为rows,cols,stride,type,data对应的数据块;若Archive类型为InputArchive,则是将在InputArchive对应的文件中的数据加载到该对象中,加载的顺序于存储的顺序相同。
    不懂Archive的,可以参考Archive

    Matrix类继承于Matrix_,它更加灵活,其重写了ptr(),operator[]这两个函数,返回值为对应类型的指针。

    更多相关内容
  • 这是一些矩阵算法的集合,例如矩阵求逆,LU分解,高斯消除,矩阵乘法,矩阵功率,矩阵加法,矩阵减法等。此软件包还包含上述算法的调试信息
  • 和矩阵相关的头文件matrix.h

    热门讨论 2012-12-17 14:23:31
    调试C++程序时,提示not such file"matrix.h"时,只需要在头文件中新建一个matrix.h文件,将本文档中的内容复制过去即可
  • 矩阵matrix.h

    2017-03-16 21:26:28
    矩阵头文件
  • 实现了矩阵中的各种操作, 包括矩阵相加,相减,矩阵乘法,矩阵转秩,余子式,求行列式的值,求矩阵特征值,LU 分解,QR 分解,求现行方程组的解等等。 是任何做科学计算工作者必备的类库。 此类库也是C++初学者极...
  • 本系列为darknet源码解析,本次解析src/matrix.h 与 src/matrix.c 两个。 matrix.h 中的包含的代码如下: #ifndef MATRIX_H #define MATRIX_H #include "darknet.h" // 将矩阵m中的数据拷贝到内存中 matrix copy...

    本系列为darknet源码解析,本次解析src/matrix.h 与 src/matrix.c 两个。

    matrix.h 中的包含的代码如下:

    #ifndef MATRIX_H
    #define MATRIX_H
    #include "darknet.h"
    
    // 将矩阵m中的数据拷贝到内存中
    matrix copy_matrix(matrix m);
    // 可视化
    void print_matrix(matrix m);
    
    //从矩阵中采样m行数据,返回采样后的结果;
    matrix hold_out_matrix(matrix *m, int n);
    
    // 矩阵的行数和列数进行resize操作,resize矩阵大小是size * size
    matrix resize_matrix(matrix m, int size);
    //获取矩阵中某一列数据,并把该列删除掉
    float *pop_column(matrix *m, int c);
    
    #endif

    首先,我们分析matrix.h 中的源码,基础数据结构list 定义在 darknet.h 中,其定义如下:

    typedef struct matrix{
        int rows, cols; // 行数,列数
        float **vals; // 二维float数组
    } matrix;
    

     matrix.c 中函数的详细分析如下,

    #include "matrix.h"
    #include "utils.h"
    #include "blas.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <math.h>
    
    
    /**
     * 释放矩阵的存储空间
     * @param matrix 待释放存储空间矩阵 m
     */
    void free_matrix(matrix m)
    {
        int i;
        // 逐行释放存储空间;
        for(i = 0; i < m.rows; ++i) free(m.vals[i]);
        free(m.vals);
    }
    
    
    /**
     * emmm...... 暂时不能理解这波操作,先空在这里,看上层怎么用???
     * @param truth 矩阵
     * @param guess
     * @param k 取top的个数
     * @return 查找的准确率
     */
    
    float matrix_topk_accuracy(matrix truth, matrix guess, int k)
    {
        // 申请k个int类型存储空间,
        int *indexes = calloc(k, sizeof(int));
        int n = truth.cols;// n 保存truth矩阵的列数
        int i,j;
        int correct = 0;
        for(i = 0; i < truth.rows; ++i){
    
            // top_K 查找guess.vals[i] 数组中 top-k 个, index保存在 indexes
            top_k(guess.vals[i], n, k, indexes);
    
            // 逐一遍历这top-k个数据
            for(j = 0; j < k; ++j){
                int class = indexes[j]; // 取index
                if(truth.vals[i][class]){ //对应 truth.vals[i][class] 位置是否非0
                    ++correct; // 非0 就表示满足
                    break;
                }
            }
        }
        free(indexes); // 释放index
        return (float)correct/truth.rows; // 返回比例,看样子是准确度。
    }
    
    /**
     * 矩阵与常数乘法操作,将矩阵m中每个元素都放大scale倍
     * @param m 矩阵
     * @param scale 乘子
     */
    void scale_matrix(matrix m, float scale)
    {
        int i,j;
        for(i = 0; i < m.rows; ++i){
            for(j = 0; j < m.cols; ++j){
                m.vals[i][j] *= scale;
            }
        }
    }
    
    
    /**
     * 矩阵的行数和列数进行resize操作,resize矩阵大小是size * size
     * @param m 待调整矩阵
     * @param size 调整后的矩阵大小为 size * size
     * @return resize后的矩阵
     */
    matrix resize_matrix(matrix m, int size)
    {
        int i;
        if (m.rows == size) return m; // 如果矩阵行数不发现变化,则不做任何调整;
        if (m.rows < size) { // 调整后矩阵行数变多
    
            /* 函数名:recalloc
               函数原型:extern void *realloc (void *mem_address, unsigned int newsize);
               函数功能:动态调整内存,先判断当前的指针是否有足够的连续空间,如果有,则扩大mem_address指向的地址,
               并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据全部拷贝到新分配的内存区域,
               而后对原来meme_address所指向的内存区域进行释放【这里是自动释放,不需要手动释放】,同时返回新分配内存区域的首地址。
               如果失败则返回空指针NULL;
            */
            m.vals = realloc(m.vals, size*sizeof(float*)); // 重新申请内存空间
            for (i = m.rows; i < size; ++i) {
                m.vals[i] = calloc(m.cols, sizeof(float)); // 每一行的存储空间也要重新申请,每一行保存size 个数据
            }
        } else if (m.rows > size) { // 调整后矩阵行数减少
            for (i = size; i < m.rows; ++i) { // 释放多余的存储空间
                free(m.vals[i]); 
            }
            m.vals = realloc(m.vals, size*sizeof(float*)); // 分配每一行存储空间,每一行保存size 个数据
        }
        m.rows = size;
        return m; // m是一个size*size 大小的矩阵
    }
    
    
    /**
     * 两个矩阵的加法操作
     * @param from 矩阵
     * @param to 矩阵
     * 最后结果写入到矩阵 to 中
     */
    void matrix_add_matrix(matrix from, matrix to)
    {
        assert(from.rows == to.rows && from.cols == to.cols);
        int i,j;
        for(i = 0; i < from.rows; ++i){
            for(j = 0; j < from.cols; ++j){
                to.vals[i][j] += from.vals[i][j];
            }
        }
    }
    
    
    /**
     * 将矩阵m中的数据拷贝到内存中
     * @param m 待拷贝数据
     * @return 返回存储在内存中矩阵
     */
    matrix copy_matrix(matrix m)
    {
        matrix c = {0};
        c.rows = m.rows;
        c.cols = m.cols;
        c.vals = calloc(c.rows, sizeof(float *));
        int i;
        for(i = 0; i < c.rows; ++i){
            c.vals[i] = calloc(c.cols, sizeof(float));
            // copy_cpu() 定义在 blas.h 中
            // void copy_cpu(int N, float *X, int INCX, float *Y, int INCY);
    
            /* blas.c 中
             * void copy_cpu(int N, float *X, int INCX, float *Y, int INCY)
               {
                    int i;
                    for(i = 0; i < N; ++i) Y[i*INCY] = X[i*INCX];
               }
             */
            // 将矩阵m的内容拷贝到矩阵c中
            copy_cpu(c.cols, m.vals[i], 1, c.vals[i], 1);
        }
        return c;
    }
    
    
    
    /**
     * 矩阵初始化
     * @param rows 行数
     * @param cols 列数
     * @return 初始化结果
     */
    matrix make_matrix(int rows, int cols)
    {
        int i;
        matrix m;
        m.rows = rows;
        m.cols = cols;
        m.vals = calloc(m.rows, sizeof(float *));// 申请存储空间
        for(i = 0; i < m.rows; ++i){
            m.vals[i] = calloc(m.cols, sizeof(float));
        }
        return m;
    }
    
    
    /**
     * 从矩阵中采样m行数据,返回采样后的结果;
     * @param m 待采样的数据
     * @param n 抽取的行数
     * @return 采样后的结果;
     */
    matrix hold_out_matrix(matrix *m, int n)
    {
        int i;
        matrix h;
        h.rows = n;
        h.cols = m->cols;
        h.vals = calloc(h.rows, sizeof(float *)); //申请新矩阵的存储空间
        for(i = 0; i < n; ++i){
            int index = rand()%m->rows; // 随机抽取一行
            h.vals[i] = m->vals[index];
            m->vals[index] = m->vals[--(m->rows)]; // 把最后一行的数据覆盖到 index行上
        }
        return h;
    }
    
    /**
     * 获取矩阵中某一列数据,并把该列删除掉
     * @param m 待删除矩阵
     * @param c 列的index
     * @return 返回指定列
     */
    float *pop_column(matrix *m, int c)
    {
        //
        float *col = calloc(m->rows, sizeof(float));
        int i, j;
    
        for(i = 0; i < m->rows; ++i){
            col[i] = m->vals[i][c]; // 逐行获取第c列
            for(j = c; j < m->cols-1; ++j){
                m->vals[i][j] = m->vals[i][j+1]; // 将c+1 到 m.cols-1列向左平移
            }
        }
        --m->cols; // 列数自减1
        return col;
    }
    
    /**
     * 读取文件,并将文件中的数据加载到矩阵matrix中
     * @param filename  文件的存储位置
     * @return 矩阵
     */
    matrix csv_to_matrix(char *filename)
    {
        FILE *fp = fopen(filename, "r");
        if(!fp) file_error(filename); // 如果不能打印文件,保存退出程序
    
        matrix m;
        m.cols = -1;
    
        char *line;
    
        int n = 0;
        int size = 1024;
        m.vals = calloc(size, sizeof(float*));
        while((line = fgetl(fp))){ // fgetl 读取文件中一行数据
            // 统计字符串中有多少个 ',' 字符和 '\0', 遇到第一个'\0'字符结束;
            // 相当于统计line中包含多少个数据,其实这就是矩阵的列数
            if(m.cols == -1) m.cols = count_fields(line);
    
            if(n == size){ //如果处理到第1024行,需要重新扩充 m.vals的存储空间
                size *= 2;
                m.vals = realloc(m.vals, size*sizeof(float*));
            }
            m.vals[n] = parse_fields(line, m.cols); // 解析字符数组中m.cols个float小数,返回是一个float类型指针
            free(line); // 释放line存储空间
            ++n; //统计处理行数
        }
        m.vals = realloc(m.vals, n*sizeof(float*)); // 之前开辟的空间是1024的整数倍,此时需要根据n来实际分配内存空间
        m.rows = n;
        return m; // 返回结果
    }
    
    /**
     * 可视化打印矩阵m,打印格式按照csv格式
     * @param m
     */
    void matrix_to_csv(matrix m)
    {
        int i, j;
    
        for(i = 0; i < m.rows; ++i){
            for(j = 0; j < m.cols; ++j){
                if(j > 0) printf(",");
                printf("%.17g", m.vals[i][j]); //自动选择合适的表示法输出
            }
            printf("\n");
        }
    }
    
    /**
     * 可视化打印矩阵m
     * @param m
     */
    void print_matrix(matrix m)
    {
        int i, j;
        printf("%d X %d Matrix:\n",m.rows, m.cols); //打印行和列数
        printf(" __");
        for(j = 0; j < 16*m.cols-1; ++j) printf(" ");
        printf("__ \n");
    
        printf("|  ");
        for(j = 0; j < 16*m.cols-1; ++j) printf(" ");
        printf("  |\n");
    
        for(i = 0; i < m.rows; ++i){
            printf("|  ");
            for(j = 0; j < m.cols; ++j){
                printf("%15.7f ", m.vals[i][j]);
            }
            printf(" |\n");
        }
        printf("|__");
        for(j = 0; j < 16*m.cols-1; ++j) printf(" ");
        printf("__|\n");
    }
    

    完,

    展开全文
  • C++矩阵运算类(Matrix.h

    万次阅读 多人点赞 2017-10-06 11:59:34
    这个类数据类型是double,包含了常用的矩阵计算,多数方法经过实践验证,也难免有不足之处,如有发现欢迎指出。 https://github.com/ims0/comTutor/tree/master/matrix ...stdlib.h> #include <...

    这个类数据类型是double,包含了常用的矩阵计算,多数方法经过实践验证,也难免有不足之处,如有发现欢迎指出。

    https://github.com/ims0/comTutor/tree/master/matrix

    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <cmath>
    using namespace std;
    #ifndef _In_opt_
      #define _In_opt_
    #endif
    #ifndef _Out_
      #define _Out_
    #endif
    
    
    typedef unsigned Index_T;
    class Matrix
    {
    private:
        Index_T m_row, m_col;
        Index_T m_size;
        Index_T m_curIndex;
        double *m_ptr;//数组指针
    public:
        Matrix(Index_T r, Index_T c) :m_row(r), m_col(c)//非方阵构造
        {
            m_size = r*c;
            if (m_size>0)
            {
                m_ptr = new double[m_size];
            }
            else
                m_ptr = NULL;
        };
        Matrix(Index_T r, Index_T c, double val ) :m_row(r), m_col(c)// 赋初值val
        {
            m_size = r*c;
            if (m_size>0)
            {
                m_ptr = new double[m_size];
            }
            else
                m_ptr = NULL;
        };
        Matrix(Index_T n) :m_row(n), m_col(n)//方阵构造
        {
            m_size = n*n;
            if (m_size>0)
            {
                m_ptr = new double[m_size];
            }
            else
                m_ptr = NULL;
        };
        Matrix(const Matrix &rhs)//拷贝构造
        {
            m_row = rhs.m_row;
            m_col = rhs.m_col;
            m_size = rhs.m_size;
            m_ptr = new double[m_size];
            for (Index_T i = 0; i<m_size; i++)
                m_ptr[i] = rhs.m_ptr[i];
        }
    
        ~Matrix()
        {
            if (m_ptr != NULL)
            {
                delete[]m_ptr;
                m_ptr = NULL;
            }
        }
    
        Matrix  &operator=(const Matrix&);  //如果类成员有指针必须重写赋值运算符,必须是成员
        friend istream &operator>>(istream&, Matrix&);
    
        friend ofstream &operator<<(ofstream &out, Matrix &obj);  // 输出到文件
        friend ostream &operator<<(ostream&, Matrix&);          // 输出到屏幕
        friend Matrix &operator<<(Matrix &mat, const double val);
        friend Matrix& operator,(Matrix &obj, const double val);
        friend Matrix  operator+(const Matrix&, const Matrix&);
        friend Matrix  operator-(const Matrix&, const Matrix&);
        friend Matrix  operator*(const Matrix&, const Matrix&);  //矩阵乘法
        friend Matrix  operator*(double, const Matrix&);  //矩阵乘法
        friend Matrix  operator*(const Matrix&, double);  //矩阵乘法
    
        friend Matrix  operator/(const Matrix&, double);  //矩阵 除以单数
    
        Matrix multi(const Matrix&); // 对应元素相乘
        Matrix mtanh(); // 对应元素相乘
        Index_T row()const{ return m_row; }
        Index_T col()const{ return m_col; }
        Matrix getrow(Index_T index); // 返回第index 行,索引从0 算起
        Matrix getcol(Index_T index); // 返回第index 列
    
        Matrix cov(_In_opt_ bool flag = true);   //协方差阵 或者样本方差
        double det();   //行列式
        Matrix solveAb(Matrix &obj);  // b是行向量或者列向量
        Matrix diag();  //返回对角线元素
        //Matrix asigndiag();  //对角线元素
        Matrix T()const;   //转置
        void sort(bool);//true为从小到大
        Matrix adjoint();
        Matrix inverse();
        void QR(_Out_ Matrix&, _Out_ Matrix&)const;
        Matrix eig_val(_In_opt_ Index_T _iters = 1000);
        Matrix eig_vect(_In_opt_ Index_T _iters = 1000);
    
        double norm1();//1范数
        double norm2();//2范数
        double mean();// 矩阵均值
        double*operator[](Index_T i){ return m_ptr + i*m_col; }//注意this加括号, (*this)[i][j]
        void zeromean(_In_opt_  bool flag = true);//默认参数为true计算列
        void normalize(_In_opt_  bool flag = true);//默认参数为true计算列
        Matrix exponent(double x);//每个元素x次幂
        Matrix  eye();//对角阵
        void  maxlimit(double max,double set=0);//对角阵
    };
    
    /*
    类方法的实现
    */
    
    Matrix Matrix::mtanh() // 对应元素 tanh()
    {
        Matrix ret(m_row, m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] = tanh(m_ptr[i]);
        }
        return ret;
    }
    /*
     * 递归调用
     */
    double calcDet(Index_T n, double *&aa)
    {
        if (n == 1)
            return aa[0];
        double *bb = new double[(n - 1)*(n - 1)];//创建n-1阶的代数余子式阵bb
        double sum = 0.0;
        for (Index_T Ai = 0; Ai<n; Ai++)
        {
            for (Index_T Bi = 0; Bi < n - 1; Bi++)//把aa阵第一列各元素的代数余子式存到bb
            {
                Index_T offset =  Bi < Ai ? 0 : 1; //bb中小于Ai的行,同行赋值,等于的错过,大于的加一
                for (Index_T j = 0; j<n - 1; j++)
                {
                    bb[Bi*(n - 1) + j] = aa[(Bi + offset)*n + j + 1];
                }
            }
            int flag = (Ai % 2 == 0 ? 1 : -1);//因为列数为0,所以行数是偶数时候,代数余子式为1.
            sum += flag* aa[Ai*n] * calcDet(n - 1, bb);//aa第一列各元素与其代数余子式积的和即为行列式
        }
        delete[]bb;
        return sum;
    }
    
    Matrix Matrix::solveAb(Matrix &obj)
    {
        Matrix ret(m_row, 1);
        if (m_size == 0 || obj.m_size == 0)
        {
            cout << "solveAb(Matrix &obj):this or obj is null" << endl;
            return ret;
        }
        if (m_row != obj.m_size)
        {
            cout << "solveAb(Matrix &obj):the row of two matrix is not equal!" << endl;
            return ret;
        }
    
        double *Dx = new double[m_row*m_row];
        for (Index_T i = 0; i<m_row; i++)
        {
            for (Index_T j = 0; j<m_row; j++)
            {
                Dx[i*m_row + j] = m_ptr[i*m_row + j];
            }
        }
        double D = calcDet(m_row, Dx);
        if (D == 0)
        {
            cout << "Cramer法则只能计算系数矩阵为满秩的矩阵" << endl;
            return  ret;
        }
    
        for (Index_T j = 0; j<m_row; j++)
        {
            for (Index_T i = 0; i<m_row; i++)
            {
                for (Index_T j = 0; j<m_row; j++)
                {
                    Dx[i*m_row + j] = m_ptr[i*m_row + j];
                }
            }
            for (Index_T i = 0; i<m_row; i++)
            {
                Dx[i*m_row + j] = obj.m_ptr[i]; //obj赋值给第j列
            }
    
            //for( int i=0;i<m_row;i++) //print
            //{
            //    for(int j=0; j<m_row;j++)
            //    {
            //        cout<< Dx[i*m_row+j]<<"\t";
            //    }
            //    cout<<endl;
            //}
            ret[j][0] = calcDet(m_row, Dx) / D;
    
        }
    
        delete[]Dx;
        return ret;
    }
    
    Matrix Matrix::getrow(Index_T index)//返回行
    {
        Matrix ret(1, m_col); //一行的返回值
    
        for (Index_T i = 0; i< m_col; i++)
        {
    
             ret[0][i] = m_ptr[(index) *m_col + i] ;
    
        }
        return ret;
    }
    
    Matrix Matrix::getcol(Index_T index)//返回列
    {
        Matrix ret(m_row, 1); //一列的返回值
    
    
        for (Index_T i = 0; i< m_row; i++)
        {
    
            ret[i][0] = m_ptr[i *m_col + index];
    
        }
        return ret;
    }
    
    Matrix Matrix::exponent(double x)//每个元素x次幂
    {
        Matrix ret(m_row, m_col);
        for (Index_T i = 0; i< m_row; i++)
        {
            for (Index_T j = 0; j < m_col; j++)
            {
                ret[i][j]= pow(m_ptr[i*m_col + j],x);
            }
        }
        return ret;
    }
    void Matrix::maxlimit(double max, double set)//每个元素x次幂
    {
    
        for (Index_T i = 0; i< m_row; i++)
        {
            for (Index_T j = 0; j < m_col; j++)
            {
                m_ptr[i*m_col + j] = m_ptr[i*m_col + j]>max ? 0 : m_ptr[i*m_col + j];
            }
        }
    
    }
    Matrix Matrix::eye()//对角阵
    {
    
        for (Index_T i = 0; i< m_row; i++)
        {
            for (Index_T j = 0; j < m_col; j++)
            {
                if (i == j)
                {
                    m_ptr[i*m_col + j] = 1.0;
                }
            }
        }
        return *this;
    }
    void Matrix::zeromean(_In_opt_  bool flag)
    {
        if (flag == true) //计算列均值
        {
            double *mean = new double[m_col];
            for (Index_T j = 0; j < m_col; j++)
            {
                mean[j] = 0.0;
                for (Index_T i = 0; i < m_row; i++)
                {
                    mean[j] += m_ptr[i*m_col + j];
                }
                mean[j] /= m_row;
            }
            for (Index_T j = 0; j < m_col; j++)
            {
    
                for (Index_T i = 0; i < m_row; i++)
                {
                    m_ptr[i*m_col + j] -= mean[j];
                }
            }
            delete[]mean;
        }
        else //计算行均值
        {
            double *mean = new double[m_row];
            for (Index_T i = 0; i< m_row; i++)
            {
                mean[i] = 0.0;
                for (Index_T j = 0; j < m_col; j++)
                {
                    mean[i] += m_ptr[i*m_col + j];
                }
                mean[i] /= m_col;
            }
            for (Index_T i = 0; i < m_row; i++)
            {
                for (Index_T j = 0; j < m_col; j++)
                {
                    m_ptr[i*m_col + j] -= mean[i];
                }
            }
            delete[]mean;
        }
    }
    
    void Matrix::normalize(_In_opt_  bool flag)
    {
        if (flag == true) //计算列均值
        {
            double *mean = new double[m_col];
    
            for (Index_T j = 0; j < m_col; j++)
            {
                mean[j] = 0.0;
                for (Index_T i = 0; i < m_row; i++)
                {
                    mean[j] += m_ptr[i*m_col + j];
                }
                mean[j] /= m_row;
            }
            for (Index_T j = 0; j < m_col; j++)
            {
    
                for (Index_T i = 0; i < m_row; i++)
                {
                    m_ptr[i*m_col + j] -= mean[j];
                }
            }
            ///计算标准差
            for (Index_T j = 0; j < m_col; j++)
            {
                mean[j] = 0;
                for (Index_T i = 0; i < m_row; i++)
                {
                    mean[j] += pow(m_ptr[i*m_col + j],2);//列平方和
                }
                    mean[j] = sqrt(mean[j] / m_row); // 开方
            }
            for (Index_T j = 0; j < m_col; j++)
            {
                for (Index_T i = 0; i < m_row; i++)
                {
                    m_ptr[i*m_col + j] /= mean[j];//列平方和
                }
            }
            delete[]mean;
        }
        else //计算行均值
        {
            double *mean = new double[m_row];
            for (Index_T i = 0; i< m_row; i++)
            {
                mean[i] = 0.0;
                for (Index_T j = 0; j < m_col; j++)
                {
                    mean[i] += m_ptr[i*m_col + j];
                }
                mean[i] /= m_col;
            }
            for (Index_T i = 0; i < m_row; i++)
            {
                for (Index_T j = 0; j < m_col; j++)
                {
                    m_ptr[i*m_col + j] -= mean[i];
                }
            }
            ///计算标准差
            for (Index_T i = 0; i< m_row; i++)
            {
                mean[i] = 0.0;
                for (Index_T j = 0; j < m_col; j++)
                {
                    mean[i] += pow(m_ptr[i*m_col + j], 2);//列平方和
                }
                mean[i] = sqrt(mean[i] / m_col); // 开方
            }
            for (Index_T i = 0; i < m_row; i++)
            {
                for (Index_T j = 0; j < m_col; j++)
                {
                    m_ptr[i*m_col + j] /= mean[i];
                }
            }
            delete[]mean;
        }
    }
    
    double Matrix::det()
    {
        if (m_col == m_row)
            return calcDet(m_row, m_ptr);
        else
        {
            cout << ("行列不相等无法计算") << endl;
            return 0;
        }
    }
    /
    istream& operator>>(istream &is, Matrix &obj)
    {
        for (Index_T i = 0; i<obj.m_size; i++)
        {
            is >> obj.m_ptr[i];
        }
        return is;
    }
    
    ostream& operator<<(ostream &out, Matrix &obj)
    {
        for (Index_T i = 0; i < obj.m_row; i++) //打印逆矩阵
        {
            for (Index_T j = 0; j < obj.m_col; j++)
            {
                out << (obj[i][j]) << "\t";
            }
            out << endl;
        }
        return out;
    }
    ofstream& operator<<(ofstream &out, Matrix &obj)//打印逆矩阵到文件
    {
        for (Index_T i = 0; i < obj.m_row; i++)
        {
            for (Index_T j = 0; j < obj.m_col; j++)
            {
                out << (obj[i][j]) << "\t";
            }
            out << endl;
        }
        return out;
    }
    
    Matrix& operator<<(Matrix &obj, const double val)
    {
        *obj.m_ptr = val;
        obj.m_curIndex = 1;
        return obj;
    }
    Matrix& operator,(Matrix &obj, const double val)
    {
        if( obj.m_curIndex == 0 || obj.m_curIndex > obj.m_size - 1 )
        {
            return obj;
        }
        *(obj.m_ptr + obj.m_curIndex) = val;
        ++obj.m_curIndex;
        return obj;
    }
    
    Matrix operator+(const Matrix& lm, const Matrix& rm)
    {
        if (lm.m_col != rm.m_col || lm.m_row != rm.m_row)
        {
            Matrix temp(0, 0);
            temp.m_ptr = NULL;
            cout << "operator+(): 矩阵shape 不合适,m_col:"
                << lm.m_col << "," << rm.m_col << ".  m_row:" << lm.m_row << ", " << rm.m_row << endl;
            return temp; //数据不合法时候,返回空矩阵
        }
        Matrix ret(lm.m_row, lm.m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] = lm.m_ptr[i] + rm.m_ptr[i];
        }
        return ret;
    }
    Matrix operator-(const Matrix& lm, const Matrix& rm)
    {
        if (lm.m_col != rm.m_col || lm.m_row != rm.m_row)
        {
            Matrix temp(0, 0);
            temp.m_ptr = NULL;
            cout << "operator-(): 矩阵shape 不合适,m_col:"
                <<lm.m_col<<","<<rm.m_col<<".  m_row:"<< lm.m_row <<", "<< rm.m_row << endl;
    
            return temp; //数据不合法时候,返回空矩阵
        }
        Matrix ret(lm.m_row, lm.m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] = lm.m_ptr[i] - rm.m_ptr[i];
        }
        return ret;
    }
    Matrix operator*(const Matrix& lm, const Matrix& rm)  //矩阵乘法
    {
        if (lm.m_size == 0 || rm.m_size == 0 || lm.m_col != rm.m_row)
        {
            Matrix temp(0, 0);
            temp.m_ptr = NULL;
            cout << "operator*(): 矩阵shape 不合适,m_col:"
                << lm.m_col << "," << rm.m_col << ".  m_row:" << lm.m_row << ", " << rm.m_row << endl;
            return temp; //数据不合法时候,返回空矩阵
        }
        Matrix ret(lm.m_row, rm.m_col);
        for (Index_T i = 0; i<lm.m_row; i++)
        {
            for (Index_T j = 0; j< rm.m_col; j++)
            {
                for (Index_T k = 0; k< lm.m_col; k++)//lm.m_col == rm.m_row
                {
                    ret.m_ptr[i*rm.m_col + j] += lm.m_ptr[i*lm.m_col + k] * rm.m_ptr[k*rm.m_col + j];
                }
            }
        }
        return ret;
    }
    Matrix operator*(double val, const Matrix& rm)  //矩阵乘 单数
    {
        Matrix ret(rm.m_row, rm.m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] = val * rm.m_ptr[i];
        }
        return ret;
    }
    Matrix operator*(const Matrix&lm, double val)  //矩阵乘 单数
    {
        Matrix ret(lm.m_row, lm.m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] = val * lm.m_ptr[i];
        }
        return ret;
    }
    
    Matrix operator/(const Matrix&lm, double val)  //矩阵除以 单数
    {
        Matrix ret(lm.m_row, lm.m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] =  lm.m_ptr[i]/val;
        }
        return ret;
    }
    Matrix Matrix::multi(const Matrix&rm)// 对应元素相乘
    {
        if (m_col != rm.m_col || m_row != rm.m_row)
        {
            Matrix temp(0, 0);
            temp.m_ptr = NULL;
            cout << "multi(const Matrix&rm): 矩阵shape 不合适,m_col:"
                << m_col << "," << rm.m_col << ".  m_row:" << m_row << ", " << rm.m_row << endl;
            return temp; //数据不合法时候,返回空矩阵
        }
        Matrix ret(m_row,m_col);
        for (Index_T i = 0; i<ret.m_size; i++)
        {
            ret.m_ptr[i] = m_ptr[i] * rm.m_ptr[i];
        }
        return ret;
    
    }
    
    Matrix&  Matrix::operator=(const Matrix& rhs)
    {
        if (this != &rhs)
        {
            m_row = rhs.m_row;
            m_col = rhs.m_col;
            m_size = rhs.m_size;
            if (m_ptr != NULL)
                delete[] m_ptr;
            m_ptr = new double[m_size];
            for (Index_T i = 0; i<m_size; i++)
            {
                m_ptr[i] = rhs.m_ptr[i];
            }
        }
        return *this;
    }
    //||matrix||_2  求A矩阵的2范数
    double Matrix::norm2()
    {
        double norm = 0;
        for (Index_T i = 0; i < m_size; ++i)
        {
            norm += m_ptr[i] * m_ptr[i];
        }
        return (double)sqrt(norm);
    }
    double Matrix::norm1()
    {
        double sum = 0;
        for (Index_T i = 0; i < m_size; ++i)
        {
            sum += abs(m_ptr[i]);
        }
        return sum;
    }
    double Matrix::mean()
    {
        double sum = 0;
        for (Index_T i = 0; i < m_size; ++i)
        {
            sum += (m_ptr[i]);
        }
        return sum/m_size;
    }
    
    
    
    
    void Matrix::sort(bool flag)
    {
        double tem;
        for (Index_T i = 0; i<m_size; i++)
        {
            for (Index_T j = i + 1; j<m_size; j++)
            {
                if (flag == true)
                {
                    if (m_ptr[i]>m_ptr[j])
                    {
                        tem = m_ptr[i];
                        m_ptr[i] = m_ptr[j];
                        m_ptr[j] = tem;
                    }
                }
                else
                {
                    if (m_ptr[i]<m_ptr[j])
                    {
                        tem = m_ptr[i];
                        m_ptr[i] = m_ptr[j];
                        m_ptr[j] = tem;
                    }
                }
    
            }
        }
    }
    Matrix Matrix::diag()
    {
        if (m_row != m_col)
        {
            Matrix m(0);
            cout << "diag():m_row != m_col" << endl;
            return m;
        }
        Matrix m(m_row);
        for (Index_T i = 0; i<m_row; i++)
        {
            m.m_ptr[i*m_row + i] = m_ptr[i*m_row + i];
        }
        return m;
    }
    Matrix Matrix::T()const
    {
        Matrix tem(m_col, m_row);
        for (Index_T i = 0; i<m_row; i++)
        {
            for (Index_T j = 0; j<m_col; j++)
            {
                tem[j][i] = m_ptr[i*m_col + j];// (*this)[i][j]
            }
        }
        return tem;
    }
    void  Matrix::QR(Matrix &Q, Matrix &R) const
    {
        //如果A不是一个二维方阵,则提示错误,函数计算结束
        if (m_row != m_col)
        {
            printf("ERROE: QR() parameter A is not a square matrix!\n");
            return;
        }
        const Index_T N = m_row;
        double *a = new double[N];
        double *b = new double[N];
    
        for (Index_T j = 0; j < N; ++j)  //(Gram-Schmidt) 正交化方法
        {
            for (Index_T i = 0; i < N; ++i)  //第j列的数据存到a,b
                a[i] = b[i] = m_ptr[i * N + j];
    
            for (Index_T i = 0; i<j; ++i)  //第j列之前的列
            {
                R.m_ptr[i * N + j] = 0;  //
                for (Index_T m = 0; m < N; ++m)
                {
                    R.m_ptr[i * N + j] += a[m] * Q.m_ptr[m *N + i]; //R[i,j]值为Q第i列与A的j列的内积
                }
                for (Index_T m = 0; m < N; ++m)
                {
                    b[m] -= R.m_ptr[i * N + j] * Q.m_ptr[m * N + i]; //
                }
            }
    
            double norm = 0;
            for (Index_T i = 0; i < N; ++i)
            {
                norm += b[i] * b[i];
            }
            norm = (double)sqrt(norm);
    
            R.m_ptr[j*N + j] = norm; //向量b[]的2范数存到R[j,j]
    
            for (Index_T i = 0; i < N; ++i)
            {
                Q.m_ptr[i * N + j] = b[i] / norm; //Q 阵的第j列为单位化的b[]
            }
        }
        delete[]a;
        delete[]b;
    }
    Matrix Matrix::eig_val(_In_opt_ Index_T _iters)
    {
        if (m_size == 0 || m_row != m_col)
        {
            cout << "矩阵为空或者非方阵!" << endl;
            Matrix rets(0);
            return rets;
        }
        //if (det() == 0)
        //{
        //  cout << "非满秩矩阵没法用QR分解计算特征值!" << endl;
        //  Matrix rets(0);
        //  return rets;
        //}
        const Index_T N = m_row;
        Matrix matcopy(*this);//备份矩阵
        Matrix Q(N), R(N);
        /*当迭代次数足够多时,A 趋于上三角矩阵,上三角矩阵的对角元就是A的全部特征值。*/
        for (Index_T k = 0; k < _iters; ++k)
        {
            //cout<<"this:\n"<<*this<<endl;
            QR(Q, R);
            *this = R*Q;
            /*  cout<<"Q:\n"<<Q<<endl;
            cout<<"R:\n"<<R<<endl;  */
        }
        Matrix val = diag();
        *this = matcopy;//恢复原始矩阵;
        return val;
    }
    Matrix Matrix::eig_vect(_In_opt_ Index_T _iters)
    {
        if (m_size == 0 || m_row != m_col)
        {
            cout << "矩阵为空或者非方阵!" << endl;
            Matrix rets(0);
            return rets;
        }
        if (det() == 0)
        {
          cout << "非满秩矩阵没法用QR分解计算特征向量!" << endl;
          Matrix rets(0);
          return rets;
        }
        Matrix matcopy(*this);//备份矩阵
        Matrix eigenValue = eig_val(_iters);
        Matrix ret(m_row);
        const Index_T NUM = m_col;
        double eValue;
        double sum, midSum, diag;
        Matrix copym(*this);
        for (Index_T count = 0; count < NUM; ++count)
        {
            //计算特征值为eValue,求解特征向量时的系数矩阵
            *this = copym;
            eValue = eigenValue[count][count];
    
            for (Index_T i = 0; i < m_col; ++i)//A-lambda*I
            {
                m_ptr[i * m_col + i] -= eValue;
            }
            //cout<<*this<<endl;
            //将 this为阶梯型的上三角矩阵
            for (Index_T i = 0; i < m_row - 1; ++i)
            {
                diag = m_ptr[i*m_col + i];  //提取对角元素
                for (Index_T j = i; j < m_col; ++j)
                {
                    m_ptr[i*m_col + j] /= diag; //【i,i】元素变为1
                }
                for (Index_T j = i + 1; j<m_row; ++j)
                {
                    diag = m_ptr[j *  m_col + i];
                    for (Index_T q = i; q < m_col; ++q)//消去第i+1行的第i个元素
                    {
                        m_ptr[j*m_col + q] -= diag*m_ptr[i*m_col + q];
                    }
                }
            }
            //cout<<*this<<endl;
            //特征向量最后一行元素置为1
            midSum = ret.m_ptr[(ret.m_row - 1) * ret.m_col + count] = 1;
            for (int m = m_row - 2; m >= 0; --m)
            {
                sum = 0;
                for (Index_T j = m + 1; j < m_col; ++j)
                {
                    sum += m_ptr[m *  m_col + j] * ret.m_ptr[j * ret.m_col + count];
                }
                sum = -sum / m_ptr[m *  m_col + m];
                midSum += sum * sum;
                ret.m_ptr[m * ret.m_col + count] = sum;
            }
            midSum = sqrt(midSum);
            for (Index_T i = 0; i < ret.m_row; ++i)
            {
                ret.m_ptr[i * ret.m_col + count] /= midSum; //每次求出一个列向量
            }
        }
        *this = matcopy;//恢复原始矩阵;
        return ret;
    }
    Matrix Matrix::cov(bool flag)
    {
        //m_row 样本数,column 变量数
        if (m_col == 0)
        {
            Matrix m(0);
            return m;
        }
        double *mean = new double[m_col]; //均值向量
    
        for (Index_T j = 0; j<m_col; j++) //init
        {
            mean[j] = 0.0;
        }
        Matrix ret(m_col);
        for (Index_T j = 0; j<m_col; j++) //mean
        {
            for (Index_T i = 0; i<m_row; i++)
            {
                mean[j] += m_ptr[i*m_col + j];
            }
            mean[j] /= m_row;
        }
        Index_T i, k, j;
        for (i = 0; i<m_col; i++) //第一个变量
        {
            for (j = i; j<m_col; j++) //第二个变量
            {
                for (k = 0; k<m_row; k++) //计算
                {
                    ret[i][j] += (m_ptr[k*m_col + i] - mean[i])*(m_ptr[k*m_col + j] - mean[j]);
    
                }
                if (flag == true)
                {
                    ret[i][j] /= (m_row-1);
                }
                else
                {
                    ret[i][j] /= (m_row);
                }
            }
        }
        for (i = 0; i<m_col; i++) //补全对应面
        {
            for (j = 0; j<i; j++)
            {
                ret[i][j] = ret[j][i];
            }
        }
        return ret;
    }
    
    /*
     * 返回代数余子式
     */
    double CalcAlgebraicCofactor( Matrix& srcMat, Index_T ai, Index_T aj)
    {
        Index_T temMatLen = srcMat.row()-1;
        Matrix temMat(temMatLen);
        for (Index_T bi = 0; bi < temMatLen; bi++)
        {
            for (Index_T bj = 0; bj < temMatLen; bj++)
            {
                Index_T rowOffset = bi < ai ? 0 : 1;
                Index_T colOffset = bj < aj ? 0 : 1;
                temMat[bi][bj] = srcMat[bi + rowOffset][bj + colOffset];
            }
        }
        int flag = (ai + aj) % 2 == 0 ? 1 : -1;
        return flag * temMat.det();
    }
    
    /*
     * 返回伴随阵
     */
    Matrix Matrix::adjoint()
    {
        if (m_row != m_col)
        {
            return Matrix(0);
        }
    
        Matrix adjointMat(m_row);
        for (Index_T ai = 0; ai < m_row; ai++)
        {
            for (Index_T aj = 0; aj < m_row; aj++)
            {
                adjointMat.m_ptr[aj*m_row + ai] = CalcAlgebraicCofactor(*this, ai, aj);
            }
        }
        return adjointMat;
    }
    
    Matrix Matrix::inverse()
    {
        double detOfMat = det();
        if (detOfMat == 0)
        {
            cout << "行列式为0,不能计算逆矩阵。" << endl;
            return Matrix(0);
        }
        return adjoint()/detOfMat;
    }
    
    

     

    展开全文
  • 矩阵与数值分析中三次样条差值代码 需包含Matrix.h头文件
  • f:\file\vs\teststm32\testst1\testst1\main.cpp(3): fatal error C1083: 无法打开包括文件: “matrix.h”: No such file or directory 解决办法:修改 项目-》配置属性-》VC++目录 中的包含目录和库目录 ...

    vs2015工程,加载自定义文件matrix,出现编译错误:

    1>f:\file\vs\teststm32\testst1\testst1\main.cpp(3): fatal error C1083: 无法打开包括文件: “matrix.h”: No such file or directory

    解决办法:修改 项目-》配置属性-》VC++目录 中的包含目录和库目录

    展开全文
  • 这个错误一般都是包括路径的问题,比如我把matrix.h放在了...../include/kutility文件夹下,我在工程中的包含目录里加入了路径,...../include 然后在工程代码开头写的是#include "matrix.h",就不对,出现题目所示...
  • 1.在vs解决方案里面右击选择属性 ...2. 在C/C++ 的常规目录下 的 附加包含目录中,包含进去matlab的库文件 D:\Program Files\MATLAB\R2010a\extern\include (当然要看你的matlab具体的安装目录)
  • C++中矩阵的基本运算写法(Matrix.h

    千次阅读 2019-09-22 22:28:12
    矩阵类: 这个类数据类型是double,包含了常用的矩阵计算,多数方法经过实践验证 #include<iostream> #include <fstream>...stdlib.h> #include <cmath> using namespace std...
  • C++matrix头文件.rar

    2021-03-29 10:03:10
    C++matrix矩阵运算头文件
  • Keil编译提示缺少core_cmFunc.h和core_cmInstr.h等文件,下载后解压,把CMSIS文件放在:D:\Program Files\Keil\ARM\CMSIS 即可
  • 具体实现了c++矩阵运算的类库,可以使用该库进行相关的设计
  • 基于C++内置double类型和C++98标准,独立封装(除C++基本类型和语法,未使用任何第三方库或者语言内置标准库),包含: 1. 矩阵加法、减法、乘法和数乘运算 2. 矩阵求秩 3. 矩阵QR分解 4. 矩阵行列式和求逆 ...
  • matrix.zip

    2019-11-26 22:52:09
    矩阵的数组实现方式,使用见文章:https://blog.csdn.net/qq_41453285/article/details/103264337
  • HLS_Matrix.rar

    2021-12-16 09:55:41
    用于对应博客文章生成IP 使用,
  • SPARSEMATRIX.rar_Visual_C++_

    2021-08-12 02:19:09
    C++ implementation of a sparse matrix structure
  • 脂质体Libmatrix是一个快速,高效且易于使用的C线性代数库。... 链接到gcc : 制造: 恭喜您的图书馆现已生成用法将matrix.h文件和libmatrix.a复制到您的项目文件夹中。 使用include指令将库包含在C文件中# inclu
  • 完整版 Golub_G.H.__van_Loan_C.F._Matrix_computations__3ed.pdf
  • 根据任意的BCH码生成多项式计算改码的生成矩阵G以及校验矩阵H
  • Arduino-LedMatrix.zip

    2019-09-18 11:06:36
    Arduino-LedMatrix.zip,灵活而强大的Arduino库,用于控制芯片MAX7219和MAX7221LED矩阵,Arduino是一家开源软硬件公司和制造商社区。Arduino始于21世纪初,深受电子制造商的欢迎,Arduino通过开源系统提供了很多灵活性...
  • moutain && matrix.zip

    2020-05-03 10:30:05
    mountain:储存器山的测试代码用于定量测试固有的cache大小,空间局部性对吞吐量的影响; matrix:矩阵乘法考虑从编码者的角度提升cache的性能,定量分析几种循环方式对cache性能影响
  • 计算双目视觉模型下投影矩阵的vs2008平台下c++程序代码
  • matrix.rarmatrix.rarmatrix.rarmatrix.rarmatrix.rar
  • Arduino UNO驱动RGB点阵彩屏,在32*64的全彩单板上测试过,彩屏单板为HUB75接口。 买了几块点阵市面上的LED点阵单板(非8*8、7219点阵屏、ws2812、oled12864),还有两块...matrix.drawPixel(7, 12, matrix.Color...
  • Eigen Matrix 详解

    千次阅读 2019-05-20 16:57:53
    https://blog.csdn.net/sn_gis/article/details/79015488
  • 矩阵运算库 C语言 (Matrix_hub)

    千次阅读 2020-02-12 16:51:11
    Matrix_hub ======================================= 矩阵运算库--C语言 --------------------------------------- ##The lib of Matrix operation for C language. (矩阵运算库--C语言) Author: Amoiensis Email...
  • dlib数据结构matrix

    千次阅读 2018-04-14 10:10:05
    备忘用,赋值操作setcolm或者setrowm#include &lt;dlib/image_io.h&gt; #include &lt;dlib/image_transforms.h&gt; #include&lt;iostream&gt; using namespace std;... matrix&l...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 141,759
精华内容 56,703
关键字:

matrix.h