00001 #include "MathLib.h"
00002
00003 MathLib::MathLib(void)
00004 {
00005 }
00006
00007 MathLib::~MathLib(void)
00008 {
00009 }
00010 using namespace momdp;
00011 namespace momdp
00012 {
00013
00014 void copy(DenseVector& result, const SparseVector& x)
00015 {
00016 result.resize( x.size() );
00017 FOREACH(SparseVector_Entry, xi, x.data)
00018 {
00019 result.data[xi->index] = xi->value;
00020 }
00021 }
00022
00023
00024 void copy(SparseVector& result, const DenseVector& x)
00025 {
00026 int num_filled;
00027 int i;
00028 vector<SparseVector_Entry>::iterator ri;
00029
00030
00031
00032 num_filled = 0;
00033 FOREACH(double, xi, x.data) {
00034 if (fabs(*xi) > SPARSE_EPS) num_filled++;
00035 }
00036
00037
00038
00039 result.resize( x.size() );
00040 result.data.resize(num_filled);
00041
00042
00043 i = 0;
00044 ri = result.data.begin();
00045 int rCount = 0;
00046 FOREACH(double, xi, x.data) {
00047 if (fabs(*xi) > SPARSE_EPS) {
00048 assert(rCount <= num_filled);
00049 ri->index = i;
00050 ri->value = *xi;
00051 ri++;
00052 rCount++;
00053 }
00054 i++;
00055 }
00056 }
00057
00058 void copy(SparseMatrix& result, kmatrix& A)
00059 {
00060 A.canonicalize();
00061 result.resize( A.size1(), A.size2() );
00062 FOREACH(kmatrix_entry, entry, A.data) {
00063 if (fabs(entry->value) > SPARSE_EPS) {
00064 result.push_back( entry->r, entry->c, entry->value );
00065 }
00066 }
00067 result.canonicalize();
00068 }
00069
00070
00071 void copy_from_column(SparseVector& result, const SparseMatrix& A,
00072 unsigned int c)
00073 {
00074 assert( 0 <= c && c < A.size2() );
00075
00076 vector<SparseVector_Entry>::const_iterator Ai;
00077
00078 vector<SparseVector_Entry>::iterator ri;
00079
00080
00081 SparseCol col = A.col(c);
00082
00083 result.resize( A.size1() );
00084 result.data.resize( col.end() - col.begin() );
00085 for (Ai = col.begin(), ri=result.data.begin(); Ai != col.end(); Ai++, ri++) {
00086 (*ri) = (*Ai);
00087 }
00088 }
00089
00090
00091 void copy_from_column(DenseVector& result, const SparseMatrix& A,
00092 unsigned int c)
00093 {
00094 assert( 0 <= c && c < A.size2() );
00095 vector<SparseVector_Entry>::const_iterator Ai, col_end;
00096
00097
00098 result.resize( A.size1() );
00099
00100 SparseCol col = A.col(c);
00101 for (Ai = col.begin(); Ai != col.end(); Ai++) {
00102 result(Ai->index) = Ai->value;
00103 }
00104 }
00105
00106
00107 void kmatrix_set_entry(kmatrix& A, unsigned int r, unsigned int c,
00108 double v)
00109 {
00110 A.push_back( r, c, v );
00111 }
00112
00113
00114 void kmatrix_transpose_in_place(kmatrix& A)
00115 {
00116 std::swap(A.size1_, A.size2_);
00117 FOREACH_NOCONST(kmatrix_entry, Ai, A.data) {
00118 std::swap( Ai->r, Ai->c );
00119 }
00120 A.canonicalize();
00121 }
00122
00123
00124 void mult(DenseVector& result, const SparseMatrix& A, const SparseVector& x)
00125 {
00126 A.mult(x, result);
00127 }
00128
00129 void mult(DenseVector& result, const SparseMatrix& A, const DenseVector& x)
00130 {
00131 A.mult(x, result);
00132 }
00133
00134
00135 void mult(SparseVector& result, const SparseMatrix& A, const SparseVector& x)
00136 {
00137 DenseVector tmp;
00138
00139 mult( tmp, A, x );
00140 copy( result, tmp );
00141 }
00142
00143
00144 void mult(DenseVector& result, const DenseVector& x, const SparseMatrix& A)
00145 {
00146 A.leftMult(x, result);
00147 }
00148
00149
00150
00151 void mult(DenseVector& result, const SparseVector& x, const SparseMatrix& A)
00152 {
00153 A.leftMult(x, result);
00154 }
00155
00156
00157 void mult(SparseVector& result, const SharedPointer<SparseVector> x, const SharedPointer<SparseMatrix> A)
00158 {
00159 mult(result, *x, *A);
00160 }
00161 void mult(SparseVector& result, const SharedPointer<SparseVector> x, const SparseMatrix& A)
00162 {
00163 mult(result, *x, A);
00164 }
00165 void mult(SparseVector& result, const SparseVector& x, const SharedPointer<SparseMatrix> A)
00166 {
00167 mult(result, x, *A);
00168 }
00169 void mult(SparseVector& result, const SparseVector& x, const SparseMatrix& A)
00170 {
00171 DenseVector tmp;
00172 mult(tmp,x,A);
00173 copy(result,tmp);
00174 }
00175
00176
00177 void emult(DenseVector& result, const DenseVector& x, const DenseVector& y)
00178 {
00179 assert( x.size() == y.size() );
00180 result.resize( x.size() );
00181 FOR (i, result.size()) {
00182 result(i) = x(i) * y(i);
00183 }
00184 }
00185
00186
00187 template <class T, class U> void emult_cc_internal(SparseVector& result, T xbegin, T xend, U ybegin, U yend)
00188 {
00189 U yi = ybegin;
00190 for (T xi = xbegin; xi != xend; xi++) {
00191 while (1) {
00192 if (yi == yend) return;
00193 if (yi->index >= xi->index) {
00194 if (yi->index == xi->index) {
00195 result.push_back( xi->index, xi->value * yi->value);
00196 }
00197 break;
00198 }
00199 yi++;
00200 }
00201 }
00202 }
00203
00204
00205 void emult(SparseVector& result, const SparseVector& x, const SparseVector& y) {
00206 assert( x.size() == y.size() );
00207 result.resize( x.size() );
00208
00209 emult_cc_internal( result, x.data.begin(), x.data.end(),
00210 y.data.begin(), y.data.end() );
00211
00212
00213 }
00214
00215
00216 void emult_column(SparseVector& result, const SparseMatrix& A, unsigned int c, const SparseVector& x)
00217 {
00218 assert( A.size1() == x.size() );
00219 assert( 0 <= c && c < A.size2() );
00220 result.resize( x.size() );
00221
00222 SparseCol col = A.col(c);
00223
00224 emult_cc_internal( result,
00225 col.begin(), col.end(),
00226 x.data.begin(), x.data.end() );
00227
00228
00229 }
00230
00231
00232 template <class T> void emult_dc_internal(DenseVector& result, const DenseVector& x, T ybegin, T yend)
00233 {
00234 int yind;
00235 for (T yi = ybegin; yi != yend; yi++) {
00236 yind = yi->index;
00237 result(yind) = x(yind) * yi->value;
00238 }
00239 }
00240
00241
00242 void emult(DenseVector& result, const DenseVector& x, const SparseVector& y)
00243 {
00244 assert( x.size() == y.size() );
00245 result.resize( x.size() );
00246 emult_dc_internal( result, x, y.data.begin(), y.data.end() );
00247 }
00248
00249
00250 void emult_column(DenseVector& result, const SparseMatrix& A, unsigned int c, const DenseVector& x)
00251 {
00252 assert( A.size1() == x.size() );
00253 assert( 0 <= c && c < A.size2() );
00254 result.resize( x.size() );
00255 SparseCol col = A.col(c);
00256 emult_dc_internal( result, x, col.begin(), col.end());
00257 }
00258
00259
00260 double inner_prod(const DenseVector& x, const SparseVector& y)
00261 {
00262 assert( x.size() == y.size() );
00263 double sum = 0.0;
00264 FOREACH(SparseVector_Entry, yi, y.data)
00265 {
00266 sum += x(yi->index) * yi->value;
00267 }
00268 return sum;
00269 }
00270
00271 double inner_prod(const SparseVector& x, const SparseVector& y)
00272 {
00273 if(x.size()!= y.size())
00274 printf("x size is : %d, y size is %d\n", (int)x.size(), (int)y.size());
00275 assert( x.size() == y.size() );
00276 double result;
00277
00278
00279 if(x.data.size()>=y.data.size() && (quickLog2(x.data.size())*y.data.size())< (x.data.size())){
00280
00281 result = inner_prod_binary(x, y);
00282 }
00283 else if(y.data.size()>x.data.size() && (quickLog2(y.data.size())*x.data.size())<(y.data.size())){
00284
00285 result = inner_prod_binary(y, x);
00286 }
00287 else{
00288 result = inner_prod_SparseVector_internal( x.data.begin(), x.data.end(),
00289 y.data.begin(), y.data.end() );
00290 }
00291 return result;
00292 }
00293
00294 int quickLog2(int n){
00295 int r = 0;
00296 while(n!= 0){
00297 n = n >> 1;
00298 r++;
00299 }
00300 return r;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 int binarySearch(const SparseVector &x, int lowerbound, int key)
00312 {
00313 int position;
00314
00315 int upperbound = x.data.size()-1;
00316
00317 position = ( lowerbound + upperbound)>>1;
00318
00319
00320
00321
00322
00323 while(((int)((x.data.at(position).index))!= key) && (lowerbound <= upperbound))
00324 {
00325 if (((int)(x.data.at(position).index)) > key)
00326 {
00327 }
00328 {
00329 lowerbound = position + 1;
00330 }
00331 position = (lowerbound + upperbound)>>1;
00332 if (position < 0 || position >= (int)x.data.size())
00333 break;
00334
00335 }
00336
00337
00338
00339
00340
00341
00342 return position;
00343
00344 }
00345
00346
00347
00348
00349 double inner_prod_binary(const SparseVector& x, const SparseVector& y)
00350 {
00351 double sum = 0.0;
00352 int xi_position;
00353 SparseVector_Entry xi;
00354 vector<SparseVector_Entry>::const_iterator yi;
00355
00356 xi_position = 0;
00357 for (yi = y.data.begin(); yi!=y.data.end() && xi_position<(int)x.data.size(); yi++)
00358 {
00359 xi = x.data.at(xi_position);
00360 if (xi.index == yi->index){
00361 sum+= xi.value*yi->value;
00362 }
00363 else{
00364
00365 xi_position = binarySearch(x, xi_position, yi->index);
00366
00367 if(xi_position> -1){
00368 xi = x.data.at(xi_position);
00369
00370 sum += xi.value * yi->value;
00371 }
00372 }
00373 xi_position++;
00374 }
00375
00376 return sum;
00377 }
00378
00379
00380
00381 double inner_prod_column(const SparseMatrix& A, unsigned int c, const SparseVector& x)
00382 {
00383 assert( A.size1() == x.size() );
00384 assert( 0 <= c && c < A.size2() );
00385 SparseCol col = A.col(c);
00386 return inner_prod_SparseVector_internal( col.begin(), col.end(), x.data.begin(), x.data.end() );
00387 }
00388
00389
00390 bool dominates(const DenseVector& x, const DenseVector& y, double eps)
00391 {
00392 FOR (i, x.size()) {
00393 if (x(i) < y(i) - eps) return false;
00394 }
00395 return true;
00396 }
00397
00398
00399 bool dominates(const SparseVector& x, const SparseVector& y, double eps)
00400 {
00401 vector<SparseVector_Entry>::const_iterator xi, xend;
00402
00403 vector<SparseVector_Entry>::const_iterator yi, yend;
00404
00405 unsigned int xind, yind;
00406 bool xdone = false, ydone = false;
00407
00408 assert( x.size() == y.size() );
00409
00410 #define CHECK_X() \
00411 if (xi == xend) { \
00412 xdone = true; \
00413 goto main_loop_done; \
00414 } else { \
00415 xind = xi->index; \
00416 }
00417
00418 #define CHECK_Y() \
00419 if (yi == yend) { \
00420 ydone = true; \
00421 goto main_loop_done; \
00422 } else { \
00423 yind = yi->index; \
00424 }
00425
00426 xi = x.data.begin();
00427 yi = y.data.begin();
00428 xend = x.data.end();
00429 yend = y.data.end();
00430
00431 CHECK_X();
00432 CHECK_Y();
00433
00434 while (1) {
00435 if (xind < yind) {
00436
00437 if (xi->value < -eps) return false;
00438 xi++;
00439 CHECK_X();
00440 } else if (xind == yind) {
00441
00442 if (xi->value < yi->value - eps) return false;
00443 xi++;
00444 yi++;
00445 CHECK_X();
00446 CHECK_Y();
00447 } else {
00448
00449 if (0 < yi->value - eps) return false;
00450 yi++;
00451 CHECK_Y();
00452 }
00453 }
00454
00455 main_loop_done:
00456 if (!xdone) {
00457 for (; xi != xend; xi++) {
00458 if (xi->value < -eps) return false;
00459 }
00460 } else if (!ydone) {
00461 for (; yi != yend; yi++) {
00462 if (0 < yi->value - eps) return false;
00463 }
00464 }
00465
00466 return true;
00467 }
00468
00469
00470
00471
00472
00473
00474 double kmatrix::operator()(unsigned int r, unsigned int c) const
00475 {
00476 assert( 0 <= r < size1() );
00477 assert( 0 <= c < size2() );
00478
00479
00480 FOREACH(kmatrix_entry, di, data) {
00481 if (di->r == r && di->c == c) {
00482 return di->value;
00483 }
00484 }
00485 return 0.0;
00486 }
00487
00488 void kmatrix::clear(void)
00489 {
00490 resize(0,0,0);
00491 }
00492
00493 void kmatrix::resize(unsigned int _size1, unsigned int _size2, double value)
00494 {
00495 assert( 0 == value );
00496 size1_ = _size1;
00497 size2_ = _size2;
00498 data.clear();
00499 }
00500
00501 void kmatrix::push_back(unsigned int r, unsigned int c, double value)
00502 {
00503 data.push_back( kmatrix_entry(r,c,value) );
00504 }
00505
00506 struct ColumnMajorCompare {
00507 bool operator()(const kmatrix_entry& lhs, const kmatrix_entry& rhs) {
00508 return (lhs.c < rhs.c) || ((lhs.c == rhs.c) && (lhs.r < rhs.r));
00509 }
00510 };
00511
00512 bool rc_equal(const kmatrix_entry& lhs, const kmatrix_entry& rhs)
00513 {
00514 return (lhs.r == rhs.r) && (lhs.c == rhs.c);
00515 }
00516
00517 void kmatrix::canonicalize(void)
00518 {
00519 std::vector< kmatrix_entry > d;
00520
00521
00522 std::stable_sort( data.begin(), data.end(), ColumnMajorCompare() );
00523
00524
00525
00526
00527 FOR ( i, data.size() ) {
00528 if (!d.empty() && rc_equal( d.back(), data[i] )) {
00529 d.back() = data[i];
00530 } else {
00531 d.push_back( data[i] );
00532 }
00533 }
00534 data.swap( d );
00535 }
00536
00537 void kmatrix::read(std::istream& in)
00538 {
00539 int rows, cols;
00540 int num_entries;
00541 int r, c;
00542 double value;
00543
00544 in >> rows >> cols;
00545 resize( rows, cols );
00546
00547 in >> num_entries;
00548 FOR (i, num_entries) {
00549 in >> r >> c >> value;
00550 push_back( r, c, value );
00551 }
00552 }
00553
00554
00555 int argmax_elt(const DenseVector& v)
00556 {
00557 assert(v.size() > 0);
00558 double maxval = v(0);
00559 int max_ind = 0;
00560 for (unsigned int i=1; i < v.size(); i++) {
00561 if (v(i) > maxval) {
00562 max_ind = i;
00563 maxval = v(i);
00564 }
00565 }
00566 return max_ind;
00567 }
00568
00569 int argmax_elt(const SparseVector& v)
00570 {
00571 assert(v.size() > 0);
00572 double maxval = v(0);
00573 int max_ind = 0;
00574
00575 FOR_CV(v)
00576 {
00577 double val = CV_VAL(v);
00578 if (val > maxval)
00579 {
00580
00581 max_ind = CV_INDEX(v);
00582 maxval = val;
00583 }
00584 }
00585 if (maxval >= 0 || v.filled() == v.size())
00586 {
00587
00588 return max_ind;
00589 }
00590 else
00591 {
00592
00593
00594 int ind, last_ind = -1;
00595 FOR_CV(v)
00596 {
00597 ind = CV_INDEX(v);
00598 if (ind - last_ind > 1)
00599 {
00600 return ind-1;
00601 }
00602 last_ind = ind;
00603 }
00604 return ind+1;
00605 }
00606 }
00607
00608 void max_assign(DenseVector& result, const DenseVector& x)
00609 {
00610 assert( result.size() == x.size() );
00611
00612 vector<double>::const_iterator xi = x.data.begin();
00613
00614 double xval;
00615
00616 FOREACH_NOCONST(double, ri, result.data) {
00617 xval = *xi;
00618 if (xval > (*ri)) (*ri) = xval;
00619 xi++;
00620 }
00621 }
00622 }
00623
00624