This commit is contained in:
vasiloglou
2007-06-23 16:17:56 +00:00
parent e0a324e2f3
commit de3c55dfe9
7 changed files with 2485 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
100
7.346300e-001
7.374979e-001
6.936535e-001
6.702775e-001
3.585772e-001
3.788121e-002
6.882729e-001
5.103941e-001
9.355582e-002
6.561860e-001
2.742218e-001
8.160376e-001
4.988111e-001
4.135763e-001
7.811456e-002
1.533728e-001
7.781087e-001
7.116524e-002
6.191919e-001
7.837094e-001
3.357823e-001
4.321649e-001
9.888512e-001
6.287611e-001
5.200221e-001
8.553515e-001
2.970969e-001
6.629188e-001
2.882765e-001
4.245862e-001
2.932094e-001
8.619233e-002
3.591635e-001
5.709677e-001
1.852744e-001
7.045443e-001
1.094038e-001
3.699633e-001
9.528905e-001
4.761181e-001
7.107067e-001
4.244987e-001
9.773447e-002
1.779219e-001
1.568666e-001
9.488745e-001
5.287958e-001
1.639944e-001
6.588165e-001
7.308261e-001
1.184186e-001
9.766621e-001
8.974463e-001
5.587714e-002
2.780151e-001
8.585589e-001
5.404314e-001
3.657045e-001
7.672973e-001
9.261288e-001
9.578967e-001
3.975565e-001
7.885566e-001
2.553015e-001
3.865935e-001
3.717164e-001
8.374367e-002
4.662825e-002
2.722296e-001
4.231244e-001
2.592126e-001
9.676257e-001
2.489725e-001
6.949686e-001
4.222361e-001
8.012153e-001
9.405026e-001
1.749261e-001
8.117695e-001
1.439838e-001
2.903612e-001
6.262911e-001
3.743479e-001
9.042863e-001
5.591988e-001
4.358584e-001
8.493601e-001
9.298170e-001
8.974617e-001
7.291850e-001
5.741265e-002
8.949562e-001
5.714349e-002
7.734559e-001
4.302593e-001
3.125377e-001
4.284127e-001
7.553944e-001
9.414088e-001
8.817028e-001
+14
View File
@@ -0,0 +1,14 @@
librule(
name="sparse",
headers=["sparse_matrix.h", "conjugate_gradient.cc" ],
deplibs=["fastlib:fastlib"]
);
binrule(
name="sparse_test",
sources=["sparse_matrix_unit.cc"],
headers=["sparse_matrix.h"],
deplibs=["fastlib:fastlib"]
);
@@ -0,0 +1,51 @@
/*
* =====================================================================================
*
* Filename: conjugate_gradient.cc
*
* Description:
*
* Version: 1.0
* Created: 06/21/2007 01:13:30 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
namespace sparse {
// solves the problem A*x=b
// where A is sparse semipositive definite
template<typename T>
void ConjugateGradient(Matrix<T> &A, T *b, T* x, T tolerance) {
index_t dimension=A.get_dimension();
T* r = NewVector(dimension);
T* p = NewVector(dimension);
A.Multiply(x,r); // r=A*x
VectorMinus(b, r) // r=b-r;
memcpy(p, r, dimension*sizeof(T));
T *temp1=NewVector(dimension);
while() {
A.Multiply(p, temp1); // temp1=A*p;
T rr=VectorDotProduct(r, r, dimension);
T alpha=rr/VectorDotProduct(temp1, p, dimension); // a=(r,r)/(A*p,p)
VectorPlusTimes(x, alpha, p, dimension, x); // x=x+a*p
T error=alpha*VectorDotProduct(p, p)/VectorDotProduct(x, x);
if (error<tolerance) {
break;
}
VectorMinusTimes(r, alpha, temp1, r); // r=r-a*A*p;
// beta=(r_j+1, r_j+1) / (r_j, r_j)
T beta=VectorDotProduct(r, r, dimension)/rr;
// p = r + b*p
VectorPlusTimes(r, beta, p, dimension, p);
}
DeleteVector(r, dimension);
DeleteVector(p, dimension);
DeleteVector(temp1, dimension);
}
};
+319
View File
@@ -0,0 +1,319 @@
/*
* =====================================================================================
*
* Filename: sparse_matrix.h
*
* Description:
*
* Version: 1.0
* Created: 06/20/2007 02:40:16 PM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#ifndef SPARSE_MATRIX_H_
#define SPARSE_MATRIX_H_
#include <errno.h>
#include <algorithm>
#include <string>
#include <sys/mman.h>
#include "fastlib/fastlib.h"
using namespace std;
namespace sparse {
template<typename T>
class Matrix {
public:
typedef pair<index_t, T> NonZeroElement_t;
template<typename > friend class Matrix;
Matrix(){
allocation_flag_=false;
}
~Matrix(){};
void Init(index_t dimension,
int32 max_non_zero) {
dimension_=dimension;
max_non_zero_=max_non_zero;
index_t alloc_size = dimension_ *
max_non_zero_ * sizeof(NonZeroElement_t);
ptr_rows_ = (NonZeroElement_t *)mmap(NULL, alloc_size,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (ptr_rows_==MAP_FAILED) {
FATAL("Couldn't allocate memory for the ptr_rows_, error: %s\n",
strerror(errno));
}
allocation_flag_=true;
row_elements_=(int32 *)mmap(NULL, dimension_*sizeof(int32) ,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Fill();
}
void Init(NonZeroElement_t *ptr_rows,
index_t dimension,
int32 max_non_zero) {
ptr_rows_=ptr_rows;
dimension_=dimension;
max_non_zero_=max_non_zero;
row_elements_=(int32 *)mmap(NULL, dimension_*sizeof(int32) ,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Fill();
}
void Init(string file) {
FILE *fp=fopen(file.c_str(), "r");
if (fp==NULL) {
FATAL("Error %s while trying to open %s\n",
strerror(errno), file.c_str());
}
fscanf(fp, "%i %i\n", dimension_, max_non_zero_);
index_t alloc_size = dimension_ *
max_non_zero_ * sizeof(NonZeroElement_t);
ptr_rows_ = (NonZeroElement_t *)mmap(NULL, alloc_size,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (ptr_rows_==MAP_FAILED) {
FATAL("Couldn't allocate memory for the ptr_rows_, error: %s\n",
strerror(errno));
}
allocation_flag_=true;
row_elements_=(int32 *)mmap(NULL, dimension_*sizeof(int32) ,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
Fill();
long long i,j;
double val;
while (feof(fp)==false) {
fscanf(fp,"%lli %lli %lg\n", &i, &j, &val);
this->set(i, j, val);
}
fclose(fp);
}
void Destruct() {
if (allocation_flag_==true) {
index_t alloc_size = dimension_ *
max_non_zero_ * sizeof(NonZeroElement_t);
munmap(ptr_rows_, alloc_size);
}
munmap(row_elements_, dimension_*sizeof(int32));
}
inline T get(index_t i, index_t j) {
index_t row = i*max_non_zero_;
DEBUG_ASSERT_MSG(i<dimension_ && i>=0,
"Tried to access row %lli > %lli\n",
(signed long long)i,
(signed long long)dimension_);
for(int32 k=0; k<row_elements_[i]; k++) {
if (ptr_rows_[row+k].first ==j) {
return ptr_rows_[row+k].second;
}
}
FATAL("Tried to access %lli, %lli "
"element which is zero",
(signed long long)i,
(signed long long)j);
}
inline void set(index_t i, index_t j, T value) {
index_t row = i*max_non_zero_;
DEBUG_ASSERT_MSG(i<dimension_ && i>=0,
"Tried to access row %lli > %lli\n",
(signed long long)i,
(signed long long)dimension_);
DEBUG_ASSERT_MSG(row_elements_[i]<max_non_zero_,
"The matrix is overfull, increase sparsity\n");
int32 k=row_elements_[i];
row_elements_[i]++;
ptr_rows_[row+k].first=j;
ptr_rows_[row+k].second=value;
}
void Advise() {
if (madvise(ptr_rows_,
dimension_*max_non_zero_*sizeof(NonZeroElement_t),
MADV_SEQUENTIAL)==-1) {
NONFATAL("Advising failed error %s\n", strerror(errno));
}
}
void UnAdvise() {
if (madvise(ptr_rows_,
dimension_*max_non_zero_*sizeof(NonZeroElement_t),
MADV_NORMAL)==-1) {
NONFATAL("Advising failed error %s\n", strerror(errno));
}
}
void Multiply(T* vec, T* result) {
for(index_t i=0; i<dimension_; i++) {
result[i]=0;
index_t row=i*max_non_zero_;
for(index_t k=0; k<row_elements_[i]; k++) {
result[i]+=ptr_rows_[row+k].second *
vec[ptr_rows_[row+k].first];
}
}
}
void MakeFast() {
for(index_t i=0; i<dimension_; i++) {
std::sort(ptr_rows_+i*(max_non_zero_),
ptr_rows_+i*(max_non_zero_)+row_elements_[i]);
}
}
inline T FastGet(index_t i, index_t j) {
index_t ind = BinarySearch(i*max_non_zero_,
i*max_non_zero_+row_elements_[i],
j);
FATAL("You are trying to access %lli , %lli "
"which is nonzero\n",
(signed long long)i,
(signed long long)j);
return ptr_rows_[ind].second;
}
inline bool IsZero(index_t i, index_t j) {
index_t ind = BinarySearch(i*max_non_zero_,
i*max_non_zero_+row_elements_[i]-1,
j);
return ind==-1;
}
index_t get_dimension() {
return dimension_;
}
index_t get_non_zeros_elements() {
index_t total=0;
for(index_t i=0; i<dimension_; i++) {
total+=row_elements_[i];
}
return total;
}
private:
NonZeroElement_t *ptr_rows_;
index_t dimension_;
int32 max_non_zero_;
bool allocation_flag_;
int32 *row_elements_;
void Fill() {
for(index_t i=0; i<dimension_; i++) {
for(int32 j=0; j<max_non_zero_; j++){
ptr_rows_[i*max_non_zero_+j].first=-1;
}
row_elements_[i]=0;
}
}
inline index_t BinarySearch(index_t low,
index_t high,
index_t value) {
while(low <= high) {
index_t mid=(low+high)/2;
if (ptr_rows_[mid].first > value) {
high=mid-1;
} else {
if (ptr_rows_[mid].first < value) {
low=mid+1;
} else {
return mid;
}
}
}
return -1;
}
};
// solves the problem A*x=b
// where A is sparse semipositive definite
template<typename T>
void ConjugateGradient(Matrix<T> &A, T *b, T* x);
template<typename T>
inline T VectorDotProduct(T* a, T* b, index_t size) {
T result=0;
for(index_t i=0; i<size; i++) {
result+=a[i]*b[i];
}
return result;
}
template<typename T>
inline void VectorPlus(T* a, T* b, index_t size, T* c) {
for(index_t i=0; i<size; i++) {
c[i]=a[i]+b[i];
}
}
template<typename T>
inline void VectorPlusTimes(T* a, T scalar, T* b, index_t size, T* c) {
for(index_t i=0; i<size; i++) {
c[i]=a[i]+scalar*b[i];
}
}
template<typename T>
inline void VectorMinusTimes(T* a, T scalar, T* b, index_t size, T* c) {
for(index_t i=0; i<size; i++) {
c[i]=a[i]-scalar*b[i];
}
}
template<typename T>
inline void VectorMinus(T* a, T* b, index_t size, T* c) {
for(index_t i=0; i<size; i++) {
c[i]=a[i]-b[i];
}
}
template<typename T>
inline void VectorMultiplyScalar(T* vector_in, T scalar, index_t size,
T* vector_out) {
for(index_t i=0; i<size; i++) {
vector_out[i]=vector_in[i]*scalar;
}
}
template<typename T>
inline T *NewVector(index_t size) {
T* out = (T*)mmap(NULL, size*sizeof(T),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (madvise(out, size*sizeof(T),
MADV_SEQUENTIAL)==-1) {
NONFATAL("Advising failed error %s\n", strerror(errno));
}
return out;
}
template<typename T>
inline void DeleteVector(T* vector, index_t size) {
if (munmap(vector, size*sizeof(T))<0) {
NONFATAL("Failed to unmap memory, error:%s\n", strerror(errno));
}
}
template<typename T>
T *ReadVectorFromFile(string filename) {
FILE *fp;
fp=fopen(filename.c_str(), "r");
if (fp==NULL) {
FATAL("Error %s while trying to open %s\n", strerror(errno));
}
long long size;
fscanf(fp, "%lli\n", &size);
T *ptr = NewVector<T>(size);
index_t i=0;
while (!feof(fp)) {
double value;
fscanf(fp, "%lg", &value);
ptr[i]=(T)value;
i++;
}
fclose(fp);
return ptr;
}
};
#endif // SPARSE_MATRIX_H_
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
/*
* =====================================================================================
*
* Filename: sparse_matrix_unit.cc
*
* Description:
*
* Version: 1.0
* Created: 06/22/2007 09:35:38 AM EDT
* Revision: none
* Compiler: gcc
*
* Author: Nikolaos Vasiloglou (NV), nvasil@ieee.org
* Company: Georgia Tech Fastlab-ESP Lab
*
* =====================================================================================
*/
#include "fastlib/fastlib.h"
#include "base/test.h"
#include "u/nvasil/sparse/sparse_matrix.h"
namespace sparse {
template<typename T>
class MatrixTest {
public:
void Init(){
size_=100;
non_zero_=10;
matrix_.Init(100, 10);
for(index_t i=0; i<size_; i++) {
for(index_t j=0; j<non_zero_; j++) {
matrix_.set(i, j, float32(i*size_+j));
}
}
matrixfile_="sparse_matrix.txt";
xfile_="xfile.txt";
bfile_="bfile.txt";
};
void Destruct(){
matrix_.Destruct();
}
void TestAccess(){
for(index_t i=0; i<size_; i++) {
for(index_t j=0; j<non_zero_; j++) {
TEST_ASSERT(matrix_.get(i, j)==float32(i*size_+j));
}
}
}
void TestConjugateGradient() {
matrix_.Destruct();
matrix_.Init(matrixfile_);
T *b=ReadVectorFromFile<T>(bfile_);
T *x=ReadVectorFromFile<T>(xfile_);
T *xconjg=NewVector<T>(size_);
ConjugateGradient(matrix_, b, xconjg);
for(index_t i=0; i<size_; i++) {
TEST_DOUBLE_APPROX(xconjg[i], x[i], 0.0001);
}
}
void TestAll() {
Init();
TestAccess();
Destruct();
Init();
TestConjugateGradient();
Destruct();
}
private:
Matrix<T> matrix_;
index_t size_;
index_t non_zero_;
string matrixfile_;
string xfile_;
string bfile_;
};
};
int main(int argc, char *argv[]) {
sparse::MatrixTest<float32> matrix_test;
matrix_test.TestAll();
}
+101
View File
@@ -0,0 +1,101 @@
100
1.996082e-001
1.889655e-001
9.194082e-002
1.192612e-001
1.178196e-001
6.371303e-002
8.445448e-002
7.254164e-002
1.501248e-001
7.637947e-002
1.017771e-001
1.586293e-001
1.454267e-001
9.962082e-002
1.618512e-001
1.169950e-001
1.602426e-001
1.503602e-001
9.723121e-002
1.544979e-001
1.282722e-001
1.969347e-001
1.400065e-001
1.401031e-001
1.943900e-001
1.063137e-001
1.159788e-001
1.402335e-001
1.962225e-001
1.223936e-001
9.956518e-002
7.307372e-002
1.328334e-001
1.739886e-001
1.178861e-001
1.750638e-001
1.567168e-001
7.882769e-002
1.143720e-001
1.498869e-001
1.465052e-001
1.251158e-001
1.358222e-001
1.373314e-001
1.610891e-001
6.361812e-002
1.505142e-001
9.882921e-002
7.997550e-002
1.352742e-001
1.058145e-001
1.007919e-001
1.257767e-001
1.393872e-001
8.415361e-002
1.252699e-001
1.477836e-001
1.410945e-001
1.449693e-001
7.195210e-002
1.410983e-001
1.530136e-001
9.629503e-002
9.223418e-002
1.493975e-001
1.702489e-001
1.085944e-001
2.034601e-001
1.499395e-001
9.145450e-002
8.656999e-002
1.806174e-001
1.534616e-001
1.759834e-001
1.462790e-001
1.833845e-001
1.217257e-001
1.349850e-001
1.359490e-001
1.315232e-001
1.183845e-001
7.881309e-002
1.944763e-001
7.765502e-002
1.662613e-001
1.018637e-001
1.385411e-001
1.492866e-001
1.521674e-001
8.788967e-002
1.452975e-001
1.085360e-001
1.243462e-001
1.241706e-001
1.349890e-001
1.493517e-001
2.081636e-001
1.325996e-001
1.267389e-001
1.164725e-001