00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
#include "SparseVMatrix.h"
00042
00043
namespace PLearn {
00044
using namespace std;
00045
00046
00049
PLEARN_IMPLEMENT_OBJECT(SparseVMatrix,
"ONE LINE DESC",
"NO HELP");
00050
00051 SparseVMatrix::SparseVMatrix(
const string& filename)
00052 : nelements(0), positions(0), values(0), rows(0)
00053 {
00054
load(filename);
00055 }
00056
00057 SparseVMatrix::SparseVMatrix(
VMat m)
00058 :
inherited(m.length(),m.width()), nelements(0), positions(0), values(0), rows(0)
00059 {
00060 fieldinfos = m->getFieldInfos();
00061
00062
if(m.
width()>USHRT_MAX)
00063
PLERROR(
"In SparseVMatrix constructor: m.width()=%d can't be greater than USHRT_MAX=%d",m.
width(),USHRT_MAX);
00064
Vec v(m.
width());
00065
real* vptr = v.
data();
00066
00067
00068
nelements = 0;
00069
if(m->hasStats())
00070 {
00071
for(
int j=0; j<m.
width(); j++)
00072 {
00073
const VMFieldStat& st = m->fieldStat(j);
00074
nelements += st.
nmissing() + st.
npositive() + st.
nnegative();
00075 }
00076 }
00077
else
00078 {
00079
for(
int i=0; i<m.
length(); i++)
00080 {
00081 m->getRow(i,v);
00082
for(
int j=0; j<v.
length(); j++)
00083
if(vptr[j]!=0.)
00084
nelements++;
00085 }
00086 }
00087
00088
00089
if(
nelements>0)
00090 {
00091
positions =
new unsigned short[
nelements];
00092
values =
new float[
nelements];
00093
int l=
length();
00094
rows =
new SparseVMatrixRow[l];
00095
00096
int pos = 0;
00097
00098
for(
int i=0; i<m.
length(); i++)
00099 {
00100 m->getRow(i,v);
00101 SparseVMatrixRow& r =
rows[i];
00102 r.
row_startpos = pos;
00103
int nelem = 0;
00104
for(
int j=0; j<v.
length(); j++)
00105
if(vptr[j]!=0.)
00106 {
00107
positions[pos] = j;
00108
values[pos] = (
float)vptr[j];
00109 pos++;
00110 nelem++;
00111 }
00112 r.
nelements = nelem;
00113 }
00114 }
00115 }
00116
00117
void
00118 SparseVMatrix::build()
00119 {
00120 inherited::build();
00121
build_();
00122 }
00123
00124
void
00125 SparseVMatrix::build_()
00126 {
00127
00128 }
00129
00130
void
00131 SparseVMatrix::declareOptions(
OptionList &ol)
00132 {
00133 inherited::declareOptions(ol);
00134 }
00135
00136 void SparseVMatrix::getNewRow(
int i,
const Vec& v)
const
00137
{
00138
#ifdef BOUNDCHECK
00139
if(i<0 || i>=
length())
00140
PLERROR(
"In SparseVMatrix::getNewRow, row number i=%d OUT OF BOUNDS (matrix is %dx%d)",i,
length(),
width());
00141
if(v.
length()!=
width())
00142
PLERROR(
"In SparseVMatrix::getNewRow, length of v (%d) is different from width of VMatris (%d)",v.
length(),
width());
00143
#endif
00144
00145
if(
nelements==0)
00146 v.
clear();
00147
else
00148 {
00149
SparseVMatrixRow row_i =
rows[i];
00150
float* valueptr =
values + row_i.
row_startpos;
00151
unsigned short* positionptr =
positions + row_i.
row_startpos;
00152
int n = row_i.
nelements;
00153
00154
real* vdata = v.
data();
00155
00156
int j = 0;
00157
while(n--)
00158 {
00159
int nextpos = (
int) *positionptr++;
00160
real nextval = (
real) *valueptr++;
00161
while(j<nextpos)
00162 vdata[j++] = 0.;
00163 vdata[j++] = nextval;
00164 }
00165
while(j<v.
length())
00166 vdata[j++] = 0.;
00167 }
00168 }
00169
00170 real SparseVMatrix::dot(
int i1,
int i2,
int inputsize)
const
00171
{
00172
#ifdef BOUNDCHECK
00173
if(i1<0 || i1>=
length() || i2<0 || i2>=
length() || inputsize>
width())
00174
PLERROR(
"IN SparseVMatrix::dot OUT OF BOUNDS");
00175
#endif
00176
00177
if(
nelements==0)
00178
return 0.;
00179
00180
SparseVMatrixRow row_1 =
rows[i1];
00181
float* valueptr_1 =
values + row_1.
row_startpos;
00182
unsigned short* positionptr_1 =
positions + row_1.
row_startpos;
00183
int n_1 = row_1.
nelements;
00184
00185
SparseVMatrixRow row_2 = rows[i2];
00186
float* valueptr_2 =
values + row_2.
row_startpos;
00187
unsigned short* positionptr_2 =
positions + row_2.
row_startpos;
00188
int n_2 = row_2.
nelements;
00189
00190
real res = 0.;
00191
00192
while(n_1 && n_2)
00193 {
00194
if(*positionptr_1>=inputsize)
00195
break;
00196
if(*positionptr_1==*positionptr_2)
00197 {
00198 res += (*valueptr_1)*(*valueptr_2);
00199 positionptr_1++;
00200 valueptr_1++;
00201 n_1--;
00202 positionptr_2++;
00203 valueptr_2++;
00204 n_2--;
00205 }
00206
else if(*positionptr_1<*positionptr_2)
00207 {
00208 positionptr_1++;
00209 valueptr_1++;
00210 n_1--;
00211 }
00212
else
00213 {
00214 positionptr_2++;
00215 valueptr_2++;
00216 n_2--;
00217 }
00218 }
00219
00220
return res;
00221 }
00222
00223 real SparseVMatrix::dot(
int i,
const Vec& v)
const
00224
{
00225
#ifdef BOUNDCHECK
00226
if(i<0 || i>=
length() || v.
length()>
width())
00227
PLERROR(
"IN SparseVMatrix::dot OUT OF BOUNDS");
00228
#endif
00229
00230
if(
nelements==0)
00231
return 0.;
00232
00233
SparseVMatrixRow row_i =
rows[i];
00234
float* valueptr =
values + row_i.
row_startpos;
00235
unsigned short* positionptr =
positions + row_i.
row_startpos;
00236
int n = row_i.
nelements;
00237
00238
real* vdata = v.
data();
00239
real res = 0.;
00240
00241
while(n--)
00242 {
00243
int nextpos = (
int) *positionptr++;
00244
real nextval = (
real) *valueptr++;
00245
if(nextpos>=v.
length())
00246
break;
00247 res += nextval*vdata[nextpos];
00248 }
00249
return res;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 SparseVMatrix::~SparseVMatrix()
00301 {
00302
if(
nelements>0)
00303 {
00304
delete[]
positions;
00305
delete[]
values;
00306
delete[]
rows;
00307 }
00308 }
00309
00310
00311 }