Compression storage of special matrices

Source: Internet
Author: User
Tags rowcount

    1. Compression storage of symmetric matrices and symmetric matrices

set a n*n square a,a any element Aij, when and only if Aij = = Aji(0 <= i <= N-1 && 0 <= J <= N-1), then matrix A is a symmetric matrix. Separated by the diagonal of the matrix, it is divided into upper and lower triangles.

Compressed storage is called a matrix storage only need to store the upper triangle/lower triangle of data, so the maximum storage N (n+1)/2 data.

symmetric matrix and the corresponding relationship of compressed storage: Lower triangle storage i>=j,Symmetricmatrix[i][j] = = array[i* (i+1)/2+j].

650) this.width=650; "src="/e/u261/themes/default/images/spacer.gif "style=" Background:url ("/e/u261/lang/zh-cn/ Images/localimage.png ") no-repeat center;border:1px solid #ddd;" alt= "spacer.gif"/> Implementation code is as follows:

#include  <iostream>using namespace std;template <class T>class  Symmetricmatrix{public:symmetricmatrix (t * a, size_t size): _a (new T[size* (size+1)/2]) , _size (size* (size + 1)  / 2), _n (size) {size_t index = 0;for  (size_t  i = 0; i < size; i++) {for  (size_t j = 0; j  < size; j++) {if  (i >= j) {_a[index++] = a[size*i + j] ;//Deposit Data}else{break in one-dimensional array;}}} ~symmetricmatrix () {if  (_a) {delete[]_a;_a = null;_size = 0;}} T& access (size_t i, size_t j) {if  (i < j) {swap (I,&NBSP;J);//When it is the upper triangle, Exchange I and j}return _a[i* (i + 1)  / 2 + j];} Void display () {for  (size_t i = 0; i < _n; i++) {for  (size_ t j = 0; j < _n; j++){if  (i >= j) {cout << _a[i* (i + 1)  / 2 + j]  <<  " ";} else{cout << _a[j* (j + 1)  / 2 + i] <<  " ";}} Cout << endl;}} protected:size_t _size;//stores the number of data t * _a;//the pointer of the symmetric matrix after storage size_t _n;//the size of the symmetric matrix};

2. Sparse matrices

M*n Matrix, the number of valid values in the matrix is much smaller than the number of invalid values, and the distribution of these data is not regular .

For example, the following matrix:

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M01/7F/1D/wKioL1cUekXTHIOVAAAJWXulRyo033.png "title=" Qq20160418140641.png "alt=" Wkiol1cuekxthiovaaajwxulryo033.png "/>

650) this.width=650; "src="/e/u261/themes/default/images/spacer.gif "style=" Background:url ("/e/u261/lang/zh-cn/ Images/localimage.png ") no-repeat center;border:1px solid #ddd;" alt= "Spacer.gif"/> (1) Compressed storage of sparse matrices

compressed storage stores only a very small number of valid data. Using {row,col,value} ternary group to store each valid data, ternary group according to the position in the original matrix, in order to store the priority of the row in succession.

so the result of the above matrix compression storage is:

650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M00/7F/20/wKiom1cUefrgD4A3AAAEUJora9M325.png "title=" Qq20160418140843.png "alt=" Wkiom1cuefrgd4a3aaaeujora9m325.png "/>

definition of ternary group:

Template<typename t>struct triple//Ternary Group {triple<t>::triple ()//parameterless constructor {}triple (size_t row, size_t col, T Value)//constructor: _row (Row), _col (col), _value (value) {}size_t _row;//row size_t _col;//column T _value;//value};

Implementation code for compressed storage:

Template<typename T>class Sparsematrix{public:sparsematrix () {}//use a vector sequence table to store information about triples Sparsematrix (T * A, size _t m, size_t N, const T & Invalid): _rowsize (M), _colsize (n), _invalid (invalid) {for (size_t i = 0; i < m; i++) {for (SI ze_t j = 0; J < N; J + +)//traversal by binary array {if (A[i*n + j]! = Invalid)//is not invalid data {triple<t> cur (i, J, A[i*n + j]); _a.push_back (cur);}}} Protected:vector <Triple<T>> _a;size_t _rowsize;size_t _colsize; T _invalid;};

(2) Transpose of sparse matrices

swap the rows and columns of the original matrix, that is, the data on [I][j] and [j][i] positions.

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/7F/1D/wKioL1cUfJXBya7rAAAW17qk6v4073.png "title=" Qq20160418141640.png "alt=" Wkiol1cufjxbya7raaaw17qk6v4073.png "/>

Normal transpose (column transpose)

The triples in the vector are placed in the new container in accordance with the column precedence of the original matrix, and the values of the rows and columns are exchanged

sparsematrix<t> transport () {assert (_a.size ()  < 0) ;//Create a new matrix that swaps the values of rows and columns Sparsematrix<t> ret;ret._rowsize = _colsize;ret._colsize = _ rowsize;ret._invalid = _invalid;//Two cycles for  (size_t i = 0; i < _ colsize; i++)//By the column of the original matrix scan {size_t index = 0;while  (Index < _a.size ()) {if   (_a[index]._col == i)//If the column values in the Triples =i//Exchange The values of the rows and columns, put the new matrix {triple<t> tmp (_a[index]._col,  _a[index]._row, _a[index]._value); Ret._a.push_back (TMP);} index++;} if  (_a.size ()  == ret._a.size ()) {break;//Two containers are the same size, Break}}return ret;} 

With this method you can effectively transpose the matrix, let's take a look at the time complexity of this function: O (col * _a.size ())--The sum of the elements of the Matrix's column * matrix.

If you have a lot of elements, you'll waste a lot of time. Is there a way to turn a two-tier loop into a loop? Pay the price of space, in exchange for time efficiency.

Quick Transpose

We only use a single layer of loops to iterate through all the elements in the container _a and place the element in the specified position. So we need an array Rowstar to hold the position of the element I. Before we define this array, we also need an array of rowcount to implement the number of elements in the first row of the statistical matrix. So that we can more easily know where the element I should be stored.

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/7F/1E/wKioL1cUgh7xfJ6XAAAl71YfXUA333.png "title=" Qq20160418144014.png "alt=" wkiol1cugh7xfj6xaaal71yfxua333.png "/> Implementation code is as follows:

Sparsematrix<t> fasttransport () {assert (_a.size ()  > 0); sparsematrix<t> ret;ret._rowsize = _colsize;//row values are exchanged ret._colsize = _rowsize;ret. _invalid = _invalid;int * rowcount = new int[_colsize];int *  rowstart = new int[_colsize];//initialization of RowCount and Rowstart to 0memset (rowcount, 0, sizeof (int) *  _colsize); memset (rowstart, 0, sizeof (int)  * _colsize);//Initialize size_t index =  0;while  (Index < _a.size ()) {Rowcount[_a[index]._col]++;++index;} rowstart[0] = 0;for  (size_t i = 1; i < _colsize; i++) { ROWSTART[I]&NBSP;=&NBSP;ROWSTART[I&NBSP;-&NBSP;1]&NBSP;+&NBSP;ROWCOUNT[I&NBSP;-&NBSP;1];} Ret._a.resize (_a.size ());//Copy Order table _a, same capacity index = 0; triple<t> tmp;while  (Index < _a.size ()) {Size_t rowindex = _a[index ]._col;//Number of rows size_t row = rowstart[rowindex];//the starting position of the current row//interchange row and column Tmp._col = _a[index]._row;tmp._row = _a[index]._ col;tmp._value = _a[index]._value;ret._a[row] = tmp;//the TMP into the calculated position of RET Rowstart[row]++;index ++;} Delete[] rowcount;delete[] rowstart;return ret;}

This function has a time complexity of O (col + _a.size ()) and is much more efficient than normal transpose.

Finally, enclose the complete code (sparse matrix):

#pragma  once#include <iostream> #include  <vector> #include  <assert.h>using  namespace std;template<typename t>struct triple//Ternary Group {Triple<T>::Triple ()// Parameterless constructor {}triple (Size_t row, size_t col, t value): _row (Row), _col (col), _value (value) {} size_t _row;//row size_t _col;//column t _value;//value};template<typename t>class  Sparsematrix{public:sparsematrix ()//non-parametric constructor {}        // The vector sequence table is used to store the information of ternary group Sparsematrix (t * a, size_t m, size_t n, const t  & invalid): _rowsize (M), _colsize (n), _invalid (invalid) {for  (size_t i = 0;  i < m; i++) {for  (size_t j = 0; j < n; j++) { if  (a[i*n + j] != invalid) {triple<t> cur (i, j, a[i*n + &NBSP;J]); _a.push_back (cur);}}} Void display ()Print Matrix {size_t index = 0;for  (size_t i = 0; i < _rowsize;  i++) {for  (size_t j = 0; j < _colsize; j++) {if  ((Index  < _a.size ())  && _a[index]._row == i&&_a[index]._col == &NBSP;J) {cout << _a[index]._value <<  " "; index++;} else{cout << _invalid <<  " ";}} Cout << endl;} Cout << endl;} Normal transpose Sparsematrix<t> transport () {assert (_a.size ()   " 0);//Create a new matrix, swap the values of rows and columns Sparsematrix<t > ret;ret._rowsize = _colsize;ret._colsize = _rowsize;ret._invalid = _ invalid;//Two cycles for  (size_t i = 0; i < _colsize; i++)//By column scan of the original matrix {Size_ t index = 0;while  (Index < _a.size ()) {if  (_a[index]._col == i) If the column values in the triples are =i//, the values of the rows and columns are exchanged,Put the new matrix {triple<t> tmp (_a[index]._col, _a[index]._row, _a[index]._value); Ret._a.push_back ( TMP);} index++;} if  (_a.size ()  == ret._a.size ()) {break;//Two containers are the same size, Break}}return ret;} Quick Transpose Sparsematrix<t> fasttransport () {assert (_a.size ()  > 0); sparsematrix<t> ret;ret._rowsize = _colsize;//row values are exchanged ret._colsize = _rowsize;ret. _invalid = _invalid;int * rowcount = new int[_colsize];int *  rowstart = new int[_colsize];//initialization of RowCount and Rowstart to 0memset (rowcount, 0, sizeof (int) *  _colsize); memset (rowstart, 0, sizeof (int)  * _colsize);//Initialize size_t index =  0;while  (Index < _a.size ()) {Rowcount[_a[index]._col]++;++index;} rowstart[0] = 0;for  (size_t i = 1; i < _colsize; i++) { Rowstart[i] = rowstart[i - 1] + rowcount[i&NBSP;-&NBSP;1];} Ret._a.resize (_a.size ());//Copy Order table _a, same capacity index = 0; triple<t> tmp;while  (Index < _a.size ()) {Size_t rowindex = _a[index ]._col;//number of rows size_t row = rowstart[rowindex];//the starting position of the current row//interchange rows and columns Tmp._col = _a[index]._row ; tmp._row = _a[index]._col;tmp._value = _a[index]._value;ret._a[row] = tmp;// Place TMP in the calculated position of RET rowstart[row]++;index++;} Delete[] rowcount;delete[] rowstart;return ret;} protected:vector <triple<t>> _a;//container size_t _rowsize;//row size_t _colsize;//column T  _invalid;//illegal value};void test () {int array[5][4] ={{ 1, 0, 3, 0, },{  0, 0, 0, 0, },{ 0, 0, 0, 0, },{ 1, 0, 3,  0, },{ 0, 0, 0, 0, },}; SPARSEMATRIX&LT;INT&GT;&NBSP;SM ((int*) array, 5, 4, 0); Sm. Display (); Sparsematrix<int> sm1;sm1 = sm. Fasttransport ();cout <<  "The matrix after transpose is: " &NBSP;&LT;&LT;&NBSP;ENDL&NBSP;&LT;&LT;&NBSP;ENDL;SM1. Display ();}

650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/7F/1E/wKioL1cUhT3hX2QwAAALrbRRIoc772.png "title=" Qq20160418145336.png "alt=" Wkiol1cuht3hx2qwaaalrbrrioc772.png "/>

This article is from the "Progressive Space" blog, make sure to keep this source http://10824050.blog.51cto.com/10814050/1765046

Compression storage of special matrices

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.