00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_TENSOR_H 00024 #define O2SCL_TENSOR_H 00025 00026 /** \file tensor.h 00027 \brief File for definitions of tensors 00028 */ 00029 00030 #include <iostream> 00031 #include <cstdlib> 00032 #include <string> 00033 #include <fstream> 00034 #include <sstream> 00035 00036 #include <gsl/gsl_matrix.h> 00037 #include <gsl/gsl_ieee_utils.h> 00038 00039 #include <o2scl/err_hnd.h> 00040 #include <o2scl/uvector_tlate.h> 00041 #include <o2scl/umatrix_tlate.h> 00042 #include <o2scl/smart_interp.h> 00043 00044 #ifndef DOXYGENP 00045 namespace o2scl { 00046 #endif 00047 00048 /** 00049 \brief Tensor class with arbitrary dimensions 00050 00051 Still somewhat experimental 00052 */ 00053 class tensor { 00054 00055 protected: 00056 00057 /// Desc 00058 double *data; 00059 00060 /// Desc 00061 size_t *size; 00062 00063 /// Desc 00064 size_t rk; 00065 00066 /// Desc 00067 double **grd; 00068 00069 /// Desc 00070 bool grid_set; 00071 00072 public: 00073 00074 /// Create an empty tensor 00075 tensor() { 00076 rk=0; 00077 data=0; 00078 grd=0; 00079 size=0; 00080 grid_set=false; 00081 } 00082 00083 /// Desc 00084 tensor(size_t rank, size_t *dim) { 00085 rk=rank; 00086 size=new size_t[rk]; 00087 grd=new double *[rk]; 00088 size_t tot=1; 00089 for(size_t i=0;i<rk;i++) { 00090 size[i]=dim[i]; 00091 grd[i]=new double[size[i]]; 00092 tot*=size[i]; 00093 } 00094 data=new double[tot]; 00095 grid_set=false; 00096 } 00097 00098 virtual ~tensor() { 00099 if (rk>0) { 00100 for(size_t i=0;i<rk;i++) delete[] grd[i]; 00101 delete[] size; 00102 delete[] grd; 00103 delete[] data; 00104 } 00105 } 00106 00107 /// Desc 00108 virtual int set(size_t *index, double val) { 00109 size_t ix=index[0]; 00110 for(size_t i=1;i<rk;i++) { 00111 ix*=size[i]; 00112 ix+=index[i]; 00113 } 00114 data[ix]=val; 00115 return 0; 00116 } 00117 00118 /// Desc 00119 virtual int set_grid(double **val) { 00120 for(size_t i=0;i<rk;i++) { 00121 for(size_t j=0;j<size[i];j++) { 00122 grd[i][j]=val[i][j]; 00123 } 00124 } 00125 return 0; 00126 } 00127 00128 /// Desc 00129 virtual double get(size_t *index) { 00130 size_t ix=index[0]; 00131 for(size_t i=1;i<rk;i++) { 00132 ix*=size[i]; 00133 ix+=index[i]; 00134 } 00135 return data[ix]; 00136 } 00137 00138 /// Desc 00139 virtual int get_rank() { return rk; } 00140 00141 /// Desc 00142 virtual int tensor_allocate(size_t rank, size_t *dim) { 00143 rk=rank; 00144 size=new size_t[rk]; 00145 grd=new double *[rk]; 00146 size_t tot=1; 00147 for(size_t i=0;i<rk;i++) { 00148 size[i]=dim[i]; 00149 grd[i]=new double[size[i]]; 00150 tot*=size[i]; 00151 } 00152 data=new double[tot]; 00153 return 0; 00154 } 00155 00156 /// Desc 00157 virtual int tensor_free() { 00158 if (rk>0) { 00159 for(size_t i=0;i<rk;i++) delete[] grd[i]; 00160 delete[] size; 00161 delete[] grd; 00162 delete[] data; 00163 rk=0; 00164 } 00165 return 0; 00166 } 00167 00168 /// Desc 00169 virtual size_t get_size(size_t i) { return size[i]; }; 00170 00171 /// Desc 00172 virtual size_t total_size() { 00173 size_t tot=1; 00174 for(size_t i=0;i<rk;i++) tot*=size[i]; 00175 return tot; 00176 } 00177 00178 /// Desc 00179 virtual double interpolate(double *vals) { 00180 00181 if (rk==1) { 00182 00183 sma_interp_vec<double *> si(size[0],grd[0],data); 00184 return si.interp(vals[0]); 00185 00186 } else { 00187 00188 // Get total number of interpolations at this level 00189 size_t ss=1; 00190 for(size_t i=1;i<rk;i++) ss*=size[i]; 00191 00192 // Create space for y vectors and interpolators 00193 double **yvec=new double *[ss]; 00194 sma_interp_vec<double *> **si=new sma_interp_vec<double *> *[ss]; 00195 for(size_t i=0;i<ss;i++) yvec[i]=new double[size[0]]; 00196 00197 // Create space for interpolation results 00198 tensor tdat; 00199 tdat.tensor_allocate(rk-1,size+1); 00200 00201 // Set grid for temporary 00202 tdat.set_grid(grd+1); 00203 00204 // Create starting coordinate and counter 00205 size_t *co=new size_t[rk]; 00206 for(size_t i=0;i<rk;i++) co[i]=0; 00207 size_t cnt=0; 00208 00209 // Loop over every interpolation 00210 bool done=false; 00211 while(done==false) { 00212 00213 // Fill yvector with the appropriate data 00214 for(size_t i=0;i<size[0];i++) { 00215 co[0]=i; 00216 yvec[cnt][i]=get(co); 00217 } 00218 00219 // Perform interpolation 00220 si[cnt]=new sma_interp_vec<double *>(size[0],grd[0],yvec[cnt]); 00221 tdat.set(co+1,si[cnt]->interp(vals[0])); 00222 00223 // Go to next interpolation 00224 cnt++; 00225 co[rk-1]++; 00226 // carry if necessary 00227 for(int j=rk-1;j>0;j--) { 00228 if (co[j]>=size[j]) { 00229 co[j]=0; 00230 co[j-1]++; 00231 } 00232 } 00233 00234 // Test if done 00235 if (cnt==ss) done=true; 00236 00237 // End of while loop 00238 } 00239 00240 // Now call the next level of interpolation 00241 double res=tdat.interpolate(vals+1); 00242 00243 tdat.tensor_free(); 00244 for(size_t i=0;i<ss;i++) delete[] yvec[i]; 00245 delete[] co; 00246 delete[] si; 00247 delete[] yvec; 00248 00249 return res; 00250 } 00251 } 00252 }; 00253 00254 /** 00255 \brief Rank 1 tensor 00256 00257 Still somewhat experimental 00258 */ 00259 class tensor1 : public tensor { 00260 00261 /// Create an empty tensor 00262 tensor1() : tensor() {} 00263 00264 /// Desc 00265 tensor1(size_t sz) : tensor(1,&sz) {} 00266 00267 /// Desc 00268 virtual double get(size_t *index) { return tensor::get(index); } 00269 00270 /// Desc 00271 virtual int set(size_t *index, double val) 00272 { return tensor::set(index,val); } 00273 00274 /// Desc 00275 virtual double get(size_t ix) { return tensor::get(&ix); } 00276 00277 /// Desc 00278 virtual int set(size_t index, double val) 00279 { return tensor::set(&index,val); } 00280 00281 /// Desc 00282 virtual double &operator[](size_t ix) { return data[ix]; } 00283 00284 /// Desc 00285 virtual double &operator()(size_t ix) { return data[ix]; } 00286 }; 00287 00288 /** 00289 \brief Rank 2 tensor 00290 00291 Still somewhat experimental 00292 */ 00293 class tensor2 : public tensor { 00294 00295 /// Create an empty tensor 00296 tensor2() : tensor() {} 00297 00298 /// Desc 00299 tensor2(size_t sz, size_t sz2) : tensor() { 00300 rk=2; 00301 size=new size_t[2]; 00302 grd=new double *[2]; 00303 size[0]=sz; 00304 size[1]=sz2; 00305 grd[0]=new double[sz]; 00306 grd[1]=new double[sz2]; 00307 size_t tot=sz*sz2; 00308 data=new double[tot]; 00309 grid_set=false; 00310 } 00311 00312 /// Desc 00313 virtual double get(size_t *index) { return tensor::get(index); } 00314 00315 /// Desc 00316 virtual int set(size_t *index, double val) 00317 { return tensor::set(index,val); } 00318 00319 /// Desc 00320 virtual double get(size_t ix1, size_t ix2) { 00321 size_t sz[2]={ix1,ix2}; 00322 return tensor::get(sz); 00323 } 00324 00325 /// Desc 00326 virtual int set(size_t ix1, size_t ix2, double val) { 00327 size_t sz[2]={ix1,ix2}; 00328 return tensor::set(sz,val); 00329 } 00330 00331 // Desc 00332 //virtual double *operator[](size_t ix) { return data[ix]; } 00333 00334 /// Desc 00335 virtual double &operator()(size_t ix, size_t iy) 00336 { return data[ix*size[1]+iy]; } 00337 }; 00338 00339 /** 00340 \brief Rank 3 tensor 00341 00342 Still somewhat experimental 00343 */ 00344 class tensor3 : public tensor { 00345 00346 /// Create an empty tensor 00347 tensor3() : tensor() {} 00348 00349 /// Desc 00350 tensor3(size_t sz, size_t sz2, size_t sz3) : tensor() { 00351 rk=3; 00352 size=new size_t[3]; 00353 grd=new double *[3]; 00354 size[0]=sz; 00355 size[1]=sz2; 00356 size[2]=sz3; 00357 grd[0]=new double[sz]; 00358 grd[1]=new double[sz2]; 00359 grd[2]=new double[sz3]; 00360 size_t tot=sz*sz2*sz3; 00361 data=new double[tot]; 00362 grid_set=false; 00363 } 00364 00365 /// Desc 00366 virtual double get(size_t *index) { return tensor::get(index); } 00367 00368 /// Desc 00369 virtual int set(size_t *index, double val) 00370 { return tensor::set(index,val); } 00371 00372 /// Desc 00373 virtual double get(size_t ix1, size_t ix2, size_t ix3) { 00374 size_t sz[3]={ix1,ix2,ix3}; 00375 return tensor::get(sz); 00376 } 00377 00378 /// Desc 00379 virtual int set(size_t ix1, size_t ix2, size_t ix3, double val) { 00380 size_t sz[3]={ix1,ix2, ix3}; 00381 return tensor::set(sz,val); 00382 } 00383 }; 00384 00385 /** 00386 \brief Rank 4 tensor 00387 00388 Still somewhat experimental 00389 */ 00390 class tensor4 : public tensor { 00391 00392 /// Create an empty tensor 00393 tensor4() : tensor() {} 00394 00395 /// Desc 00396 tensor4(size_t sz, size_t sz2, size_t sz3, size_t sz4) : tensor() { 00397 rk=4; 00398 size=new size_t[4]; 00399 grd=new double *[4]; 00400 size[0]=sz; 00401 size[1]=sz2; 00402 size[2]=sz3; 00403 size[3]=sz4; 00404 grd[0]=new double[sz]; 00405 grd[1]=new double[sz2]; 00406 grd[2]=new double[sz3]; 00407 grd[3]=new double[sz4]; 00408 size_t tot=sz*sz2*sz3*sz4; 00409 data=new double[tot]; 00410 grid_set=false; 00411 } 00412 00413 /// Desc 00414 virtual double get(size_t *index) { return tensor::get(index); } 00415 00416 /// Desc 00417 virtual int set(size_t *index, double val) 00418 { return tensor::set(index,val); } 00419 00420 /// Desc 00421 virtual double get(size_t ix1, size_t ix2, size_t ix3, size_t ix4) { 00422 size_t sz[4]={ix1,ix2,ix3,ix4}; 00423 return tensor::get(sz); 00424 } 00425 00426 /// Desc 00427 virtual int set(size_t ix1, size_t ix2, size_t ix3, size_t ix4, 00428 double val) { 00429 size_t sz[4]={ix1,ix2,ix3,ix4}; 00430 return tensor::set(sz,val); 00431 } 00432 }; 00433 00434 /** 00435 \brief Tensor class for rank 1 tensors with an operator[] 00436 00437 Still somewhat experimental 00438 */ 00439 class tensor_br1 { 00440 00441 protected: 00442 00443 /// Desc 00444 double *data; 00445 00446 /// Desc 00447 size_t size; 00448 00449 /// Desc 00450 double *g; 00451 00452 /// Desc 00453 bool grid_set; 00454 00455 public: 00456 00457 virtual ~tensor_br1() { 00458 if (size!=0) tensor_free(); 00459 } 00460 00461 /// Create an empty tensor 00462 tensor_br1() { 00463 size=0; 00464 grid_set=false; 00465 } 00466 00467 /// Desc 00468 tensor_br1(size_t rank, size_t *dim, size_t ix=0) { 00469 size=dim[ix]; 00470 data=new double[dim[ix]]; 00471 g=new double[dim[ix]]; 00472 grid_set=false; 00473 } 00474 00475 /// Desc 00476 double &operator[](size_t i) { 00477 return data[i]; 00478 } 00479 00480 /// Desc 00481 virtual int set(size_t *index, double val, size_t ix=0) { 00482 if (index[ix]<size) { 00483 data[index[ix]]=val; 00484 } 00485 return 0; 00486 } 00487 00488 /// Desc 00489 virtual int set_grid(double **val, size_t ix=0) { 00490 for(size_t i=0;i<size;i++) { 00491 g[i]=val[ix][i]; 00492 } 00493 grid_set=true; 00494 return 0; 00495 } 00496 00497 /// Desc 00498 virtual double get(size_t *index, size_t ix=0) { 00499 if (index[ix]<size) { 00500 return data[index[ix]]; 00501 } 00502 return 0.0; 00503 } 00504 00505 /// Desc 00506 virtual int get_size(size_t i) { return size; }; 00507 00508 /// Desc 00509 virtual int get_rank() { return 1; } 00510 00511 /// Desc 00512 virtual int tensor_allocate(size_t rank, size_t *dim, size_t ix=0) { 00513 if (size!=0) tensor_free(); 00514 size=dim[ix]; 00515 data=new double[dim[ix]]; 00516 g=new double[dim[ix]]; 00517 grid_set=false; 00518 return 0; 00519 }; 00520 00521 /// Desc 00522 virtual int tensor_free() { 00523 delete[] g; 00524 delete[] data; 00525 size=0; 00526 grid_set=false; 00527 return 0; 00528 } 00529 00530 /// Desc 00531 virtual int total_size() { 00532 return size; 00533 } 00534 00535 /// Desc 00536 virtual double interpolate(double **grid, 00537 double *vals, size_t *dim, size_t ix=0) { 00538 sma_interp_vec<double *> si(size,g,data); 00539 return si.interp(vals[ix]); 00540 } 00541 00542 }; 00543 00544 /** 00545 \brief Tensor class with arbitrary dimensions and an operator[] 00546 00547 Still somewhat experimental 00548 */ 00549 template<class parent_t> class tensor_br { 00550 00551 protected: 00552 00553 /// Desc 00554 parent_t **data; 00555 00556 /// Desc 00557 size_t size; 00558 00559 /// Desc 00560 size_t rk; 00561 00562 /// Desc 00563 double *g; 00564 00565 /// Desc 00566 bool grid_set; 00567 00568 public: 00569 00570 /// Create an empty tensor 00571 tensor_br() { 00572 size=0; 00573 } 00574 00575 /// Desc 00576 tensor_br(size_t rank, size_t *dim, size_t ix=0) { 00577 size=dim[ix]; 00578 rk=rank; 00579 data=new parent_t *[dim[ix]]; 00580 for(size_t i=0;i<dim[ix];i++) { 00581 data[i]=new parent_t; 00582 data[i]->tensor_allocate(rank,dim,ix+1); 00583 } 00584 g=new double[dim[ix]]; 00585 } 00586 00587 virtual ~tensor_br() { 00588 if (size!=0) tensor_free(); 00589 } 00590 00591 /// Desc 00592 parent_t &operator[](size_t i) { 00593 return *data[i]; 00594 } 00595 00596 /// Desc 00597 virtual int set(size_t *index, double val, size_t ix=0) { 00598 if (index[ix]<size) { 00599 data[index[ix]]->set(index,val,ix+1); 00600 } 00601 return 0; 00602 } 00603 00604 /// Desc 00605 virtual int set_grid(double **val, size_t ix=0) { 00606 for(size_t i=0;i<size;i++) { 00607 g[i]=val[ix][i]; 00608 data[i]->set_grid(val,ix+1); 00609 } 00610 return 0; 00611 } 00612 00613 /// Desc 00614 virtual double get(size_t *index, size_t ix=0) { 00615 if (index[ix]<size) { 00616 return data[index[ix]]->get(index,ix+1); 00617 } 00618 return 0.0; 00619 } 00620 00621 /// Desc 00622 virtual int get_rank() { return rk; } 00623 00624 /// Desc 00625 virtual int tensor_allocate(size_t rank, size_t *dim, size_t ix=0) { 00626 if (size!=0) tensor_free(); 00627 size=dim[ix]; 00628 rk=rank; 00629 data=new parent_t *[dim[ix]]; 00630 for(size_t i=0;i<dim[ix];i++) { 00631 data[i]=new parent_t; 00632 data[i]->tensor_allocate(rank,dim,ix+1); 00633 } 00634 g=new double[dim[ix]]; 00635 return 0; 00636 } 00637 00638 /// Desc 00639 virtual int tensor_free() { 00640 delete[] g; 00641 for(size_t i=0;i<size;i++) { 00642 data[i]->tensor_free(); 00643 delete data[i]; 00644 } 00645 delete[] data; 00646 size=0; 00647 return 0; 00648 } 00649 00650 /// Desc 00651 virtual int get_size(size_t i) { 00652 if (i==0) return size; 00653 else if (i>=rk) return 0; 00654 else return data[0]->get_size(i-1); 00655 } 00656 00657 /// Desc 00658 virtual int total_size() { 00659 return data[0]->total_size()*size; 00660 } 00661 00662 /// Desc 00663 virtual double interpolate(double **grid, 00664 double *vals, size_t *dim, size_t ix=0) { 00665 00666 // Get total number of interpolations at this level 00667 size_t ss=data[0]->total_size(); 00668 00669 // Create space for y vectors and interpolators 00670 double **yvec=new double *[ss]; 00671 sma_interp_vec<double *> **si=new sma_interp_vec<double *> *[ss]; 00672 for(size_t i=0;i<ss;i++) yvec[i]=new double[size]; 00673 00674 // Create space for interpolation results 00675 parent_t tdat; 00676 tdat.tensor_allocate(rk,dim,ix+1); 00677 00678 // Set grid for temporary 00679 tdat.set_grid(grid,ix+1); 00680 00681 // Create starting coordinate and counter 00682 size_t *co=new size_t[rk]; 00683 for(size_t i=0;i<rk;i++) co[i]=0; 00684 size_t cnt=0; 00685 00686 // Loop over every interpolation 00687 bool done=false; 00688 while(done==false) { 00689 00690 // Fill yvector with the appropriate data 00691 for(size_t i=0;i<size;i++) { 00692 yvec[cnt][i]=data[i]->get(co,ix+1); 00693 } 00694 00695 // Perform interpolation 00696 si[cnt]=new sma_interp_vec<double *>(size,g,yvec[cnt]); 00697 tdat.set(co,si[cnt]->interp(vals[ix]),ix+1); 00698 00699 // Go to next interpolation 00700 cnt++; 00701 co[rk-1]++; 00702 // carry if necessary 00703 for(int j=rk-1;j>0;j--) { 00704 if (co[j]>=dim[j]) { 00705 co[j]=0; 00706 co[j-1]++; 00707 } 00708 } 00709 00710 // Test if done 00711 if (cnt==ss) done=true; 00712 00713 // End of while loop 00714 } 00715 00716 // Now call the next level of interpolation 00717 double res=tdat.interpolate(grid,vals,dim,ix+1); 00718 00719 tdat.tensor_free(); 00720 for(size_t i=0;i<ss;i++) delete[] yvec[i]; 00721 delete[] co; 00722 delete[] si; 00723 delete[] yvec; 00724 00725 return res; 00726 } 00727 }; 00728 00729 #ifndef DOXYGENP 00730 } 00731 #endif 00732 00733 #endif 00734 00735 00736
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page