/
SimpleSparse.cpp
98 lines (93 loc) · 2.49 KB
/
SimpleSparse.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include<cmath>
#include<cstring>
#ifdef _OPENMP
#include<omp.h>
#endif
#include "SimpleSparse.h"
double SimpleSparse::logSumExpVal(long st, long en) const{//{{{
if(st<0)st = 0;
if((en == -1) || (en > T)) en = T;
if(st >= en) return 0;
long i;
double sumE = 0, m = val[st];
for(i = st; i < en; i++)if(val[i] > m)m = val[i];
for(i = st; i < en; i++)
sumE += exp(val[i] - m);
return m + log(sumE);
}//}}}
void SimpleSparse::sumRows(double res[]) const{//{{{
long i,r;
for(r=0;r<N;r++){
res[r]=0;
for(i=rowStart[r];i<rowStart[r+1];i++){
res[r]+=val[i];
}
}
}//}}}
void SimpleSparse::sumCols(double res[]) const{//{{{
memset(res,0,M*sizeof(double));
for(long i=0;i<T;i++)res[col[i]]+=val[i];
}//}}}
long SimpleSparse::countAboveDelta(double delta) const{//{{{
long i,count=0;
#pragma omp parallel for reduction(+:count)
for(i=0;i<T;i++){
if(val[i]>delta)count++;
}
return count;
}//}}}
void SimpleSparse::softmaxInplace(SimpleSparse *res){//{{{
double logRowSum = 0;
long i,r;
#pragma omp parallel for private(i,logRowSum)
for(r=0;r<N;r++){
logRowSum = logSumExpVal(rowStart[r],rowStart[r+1]);
for(i=rowStart[r];i<rowStart[r+1];i++){
val[i] = val[i] - logRowSum;
res->val[i] = exp( val[i] );
}
}
}//}}}
void SimpleSparse::softmax(SimpleSparse *res) const{//{{{
double logRowSum = 0;
long i,r;
#pragma omp parallel for private(i,logRowSum)
for(r=0;r<N;r++){
logRowSum = logSumExpVal(rowStart[r],rowStart[r+1]);
for(i=rowStart[r];i<rowStart[r+1];i++){
res->val[i] = exp(val[i] - logRowSum);
}
}
}//}}}
SimpleSparse::SimpleSparse(long n,long m, long t){//{{{
N=n;
M=m;
T=t;
val = new double[T];
base = true; // base matrix with it's own col & rowStart information
col = new int_least32_t[T];
rowStart = new int_least32_t[N+1];
//colStart = new long[M+1];
}//}}}
SimpleSparse::SimpleSparse(SimpleSparse *m0){//{{{
N=m0->N;
M=m0->M;
T=m0->T;
val = new double[T];
base = false; // use col & rowStart information from the base matrix m0
col = m0->col;
rowStart = m0->rowStart;
/*col = new long[T];
rowStart = new long[N+1];
memcpy(col, m0->col, T*sizeof(long));
memcpy(rowStart, m0->rowStart, (N+1)*sizeof(long));
*/
}//}}}
SimpleSparse::~SimpleSparse(){//{{{
delete[] val;
if(base){
// BEWARE there could be other matrices using this data
delete[] col;
delete[] rowStart;
}
}//}}}