tensor.h

Go to the documentation of this file.
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 SourceForge.net Logo, O2scl Sourceforge Project Page