23 #ifndef O2SCL_TENSOR_GRID_H
24 #define O2SCL_TENSOR_GRID_H
36 #include <gsl/gsl_matrix.h>
37 #include <gsl/gsl_ieee_utils.h>
39 #include <o2scl/err_hnd.h>
40 #include <o2scl/interp.h>
41 #include <o2scl/tensor.h>
42 #include <o2scl/table3d.h>
56 #ifndef DOXYGEN_NO_O2NS
96 public tensor<boost::numeric::ublas::vector<double>,
97 boost::numeric::ublas::vector<size_t> > {
103 typedef boost::numeric::ublas::range range;
104 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
105 typedef boost::numeric::ublas::vector_range<ubvector_size_t>
106 ubvector_size_t_range;
108 #ifndef DOXYGEN_INTERNAL
142 template<
class size_vec_t>
148 for(
size_t i=0;i<
rk;i++) {
150 O2SCL_ERR((((std::string)
"Requested zero size with non-zero ")+
151 "rank for index "+
szttos(i)+
" in tensor_grid::"+
152 "tensor_grid(size_t,size_vec_t)").c_str(),
164 template<
class vec_t>
169 for(
size_t i=0;i<
rk;i++) {
175 for(
size_t i=1;i<
rk;i++) {
193 template<
class vec_t,
class vec2_t>
194 void set_val(
const vec_t &grdp,
double val, vec2_t &closest) {
198 for(
size_t i=0;i<
rk;i++) {
204 for(
size_t i=1;i<
rk;i++) {
219 template<
class vec_t>
double get_val(
const vec_t &grdp) {
223 for(
size_t i=0;i<
rk;i++) {
229 for(
size_t i=1;i<
rk;i++) {
244 template<
class vec_t,
class vec2_t>
245 double get_val(
const vec_t &grdp, vec2_t &closest) {
249 for(
size_t i=0;i<
rk;i++) {
255 for(
size_t i=1;i<
rk;i++) {
277 template<
class size_vec_t>
278 void resize(
size_t rank,
const size_vec_t &dim) {
281 for(
size_t i=0;i<rank;i++) {
283 O2SCL_ERR((((std::string)
"Requested zero size with non-zero ")+
284 "rank for index "+
szttos(i)+
" in tensor_grid::"+
302 for(
size_t i=0;i<
rk;i++) {
339 template<
class vec_t>
342 O2SCL_ERR2(
"Tried to set grid for empty tensor in ",
343 "tensor_grid::set_grid_packed().",
exc_einval);
346 for(
size_t i=0;i<
rk;i++) ngrid+=
size[i];
348 for(
size_t i=0;i<ngrid;i++) {
357 template<
class vec_vec_t>
360 O2SCL_ERR2(
"Tried to set grid for empty tensor in ",
364 for(
size_t i=0;i<
rk;i++) ngrid+=
size[i];
367 for(
size_t i=0;i<
rk;i++) {
368 for(
size_t j=0;j<
size[i];j++) {
369 grid[k]=grid_vecs[i][j];
380 O2SCL_ERR(
"Grid not set in tensor_grid::get_grid().",
385 " greater than or equal to rank, "+
szttos(
rk)+
386 ", in tensor_grid::get_grid().").c_str(),
390 for(
size_t k=0;k<i;k++) istart+=
size[k];
391 return grid[istart+j];
397 O2SCL_ERR(
"Grid not set in tensor_grid::get_grid().",
402 " greater than or equal to rank, "+
szttos(
rk)+
403 ", in tensor_grid::get_grid().").c_str(),
407 for(
size_t k=0;k<i;k++) istart+=
size[k];
415 O2SCL_ERR(
"Grid not set in tensor_grid::lookup_grid().",
420 " greater than or equal to rank, "+
szttos(
rk)+
421 ", in tensor_grid::lookup_grid().").c_str(),
426 for(
size_t j=0;j<i;j++) {
430 double min=fabs(
grid[istart]-val);
431 for(
size_t j=istart;j<istart+
size[i];j++) {
432 if (fabs(
grid[j]-val)<min) {
434 min=fabs(
grid[j]-val);
450 template<
class vec_t,
class size_vec_t>
452 for(
size_t k=0;k<
rk;k++) {
467 " greater than or equal to rank, "+
szttos(
rk)+
468 ", in tensor_grid::lookup_grid_val().").c_str(),
472 O2SCL_ERR(
"Grid not set in tensor_grid::lookup_grid_val().",
476 for(
size_t j=0;j<i;j++) istart+=
size[j];
478 double min=fabs(
grid[istart]-val);
480 for(
size_t j=istart;j<istart+
size[i];j++) {
481 if (fabs(
grid[j]-val)<min) {
483 min=fabs(
grid[j]-val);
493 O2SCL_ERR(
"Grid not set in tensor_grid::lookup_grid_packed().",
499 ", in tensor_grid::lookup_grid_packed().").c_str(),
503 for(
size_t j=0;j<i;j++) istart+=
size[j];
505 double min=fabs(
grid[istart]-val);
506 for(
size_t j=istart;j<istart+
size[i];j++) {
507 if (fabs(
grid[j]-val)<min) {
509 min=fabs(
grid[j]-val);
518 O2SCL_ERR(
"Grid not set in tensor_grid::lookup_grid_packed().",
524 ", in tensor_grid::lookup_grid_packed().").c_str(),
528 for(
size_t j=0;j<i;j++) istart+=
size[j];
530 double min=fabs(
grid[istart]-val);
532 for(
size_t j=istart;j<istart+
size[i];j++) {
533 if (fabs(
grid[j]-val)<min) {
535 min=fabs(
grid[j]-val);
563 template<
class size_vec_t>
565 table3d &tab, std::string slice_name) {
567 if (ix_x>=
rk || ix_y>=
rk || ix_x==ix_y) {
568 O2SCL_ERR2(
"Either indices greater than rank or x and y ind",
569 "ices equal in tensor_grid::copy_slice_align().",
577 if (nx==0 && ny==0) {
580 std::vector<double> gx, gy;
581 for(
size_t i=0;i<
size[ix_x];i++) {
582 gx.push_back(this->
get_grid(ix_x,i));
584 for(
size_t i=0;i<size[ix_y];i++) {
585 gy.push_back(this->
get_grid(ix_y,i));
589 tab.
set_xy(
"x",nx,gx,
"y",ny,gy);
593 if (nx!=
size[ix_x] || ny!=
size[ix_y]) {
595 "tensor_grid::copy_slice_align().",
exc_einval);
603 for(
size_t i=0;i<nx;i++) {
604 for(
size_t j=0;j<ny;j++) {
607 double val=this->
get(index);
608 tab.
set(i,j,slice_name,val);
625 template<
class size_vec_t>
627 table3d &tab, std::string slice_name) {
629 if (ix_x>=
rk || ix_y>=
rk || ix_x==ix_y) {
630 O2SCL_ERR2(
"Either indices greater than rank or x and y ",
631 "indices equal in tensor_grid::copy_slice_interp().",
639 if (nx==0 && ny==0) {
645 std::vector<double> vals(
rk);
646 for(
size_t i=0;i<
rk;i++) {
647 if (i!=ix_x && i!=ix_y) vals[i]=this->
get_grid(i,index[i]);
655 for(
size_t i=0;i<nx;i++) {
656 for(
size_t j=0;j<ny;j++) {
704 return si.eval(vals[0]);
710 for(
size_t i=1;i<
rk;i++) ss*=
size[i];
713 std::vector<ubvector> yvec(ss);
714 std::vector<interp_t *> si(ss);
715 for(
size_t i=0;i<ss;i++) {
716 yvec[i].resize(
size[0]);
721 ubvector_size_t_range size_new(
size,range(1,rk));
722 tdat.
resize(rk-1,size_new);
725 ubvector_range grid_new(
grid,range(
size[0],
grid.size()));
730 for(
size_t i=0;i<
rk;i++) co[i]=0;
738 for(
size_t i=0;i<
size[0];i++) {
740 yvec[cnt][i]=
get(co);
743 si[cnt]=
new interp_t(size[0],
grid,yvec[cnt],
itype);
745 ubvector_size_t_range co2(co,range(1,rk));
746 tdat.
set(co2,si[cnt]->eval(vals[0]));
752 for(
int j=((
int)rk)-1;j>0;j--) {
753 if (co[j]>=size[j]) {
760 if (cnt==ss) done=
true;
768 for(
size_t i=0;i<ss;i++) {
791 std::vector<size_t> loc(
rk);
792 std::vector<double> gnew;
793 for(
size_t i=0;i<
rk;i++) {
794 std::vector<double> grid_unpacked(
size[i]);
795 for(
size_t j=0;j<
size[i];j++) {
796 grid_unpacked[j]=
grid[j+rgs];
799 loc[i]=sv.
find(v[i]);
800 gnew.push_back(grid_unpacked[loc[i]]);
801 gnew.push_back(grid_unpacked[loc[i]+1]);
807 std::vector<size_t> snew(rk);
808 for(
size_t i=0;i<
rk;i++) {
816 std::vector<size_t> index_new(rk), index_old(rk);
818 for(
size_t j=0;j<
rk;j++) index_old[j]=index_new[j]+loc[j];
819 tnew.
set(index_new,
get(index_old));
841 double frac=(v[last]-
get_grid(last,0))/
851 std::vector<size_t> index(
rk);
854 double val_lo=
get(index);
856 double val_hi=
get(index);
857 tnew.
set(index,val_lo+frac*(val_hi-val_lo));
887 this->
size.resize(1);
889 this->
data.resize(sz);
897 double &
get(
size_t ix1) {
903 const double &
get(
size_t ix1)
const {
909 void set(
size_t ix1,
double val) {
938 this->
size.resize(2);
942 this->
data.resize(tot);
950 double &
get(
size_t ix1,
size_t ix2) {
951 size_t sz[2]={ix1,ix2};
956 const double &
get(
size_t ix1,
size_t ix2)
const {
957 size_t sz[2]={ix1,ix2};
962 void set(
size_t ix1,
size_t ix2,
double val) {
963 size_t sz[2]={ix1,ix2};
993 this->
size.resize(3);
997 size_t tot=sz*sz2*sz3;
998 this->
data.resize(tot);
1006 double &
get(
size_t ix1,
size_t ix2,
size_t ix3) {
1007 size_t sz[3]={ix1,ix2,ix3};
1012 const double &
get(
size_t ix1,
size_t ix2,
size_t ix3)
const {
1013 size_t sz[3]={ix1,ix2,ix3};
1018 void set(
size_t ix1,
size_t ix2,
size_t ix3,
double val) {
1019 size_t sz[3]={ix1,ix2, ix3};
1025 double interp(
double x,
double y,
double z) {
1026 double arr[3]={x,y,z};
1032 double arr[3]={x,y,z};
1050 this->
size.resize(4);
1055 size_t tot=sz*sz2*sz3*sz4;
1056 this->
data.resize(tot);
1064 double &
get(
size_t ix1,
size_t ix2,
size_t ix3,
size_t ix4) {
1065 size_t sz[4]={ix1,ix2,ix3,ix4};
1070 const double &
get(
size_t ix1,
size_t ix2,
size_t ix3,
1072 size_t sz[4]={ix1,ix2,ix3,ix4};
1077 void set(
size_t ix1,
size_t ix2,
size_t ix3,
size_t ix4,
1079 size_t sz[4]={ix1,ix2,ix3,ix4};
1085 double interp(
double x,
double y,
double z,
double a) {
1086 double arr[4]={x,y,z,a};
1092 double arr[4]={x,y,z,a};
1097 #ifndef DOXYGEN_NO_O2NS
tensor_grid1(size_t sz)
Create a rank 2 tensor of size (sz,sz2,sz3)
ubvector grid
A rank-sized set of arrays for the grid points.
bool is_grid_set() const
Return true if the grid has been set.
Interpolation class for pre-specified vector.
Tensor class with arbitrary dimensions with a grid.
void hdf_output(hdf_file &hf, o2scl::tensor_grid &t, std::string name)
Output a o2scl::tensor_grid object to a hdf_file.
tensor_grid4()
Create an empty tensor.
double get_val(const vec_t &grdp, vec2_t &closest)
Get the element closest to grid point grdp to value val.
Rank 1 tensor with a grid.
bool is_slice(std::string name, size_t &ix) const
Return true if slice is already present.
double interp_linear(double x, double y, double z, double a)
Interpolate (x,y,z,a) and return the results.
double get_val(const vec_t &grdp)
Get the element closest to grid point grdp.
void copy_slice_align(size_t ix_x, size_t ix_y, size_vec_t &index, table3d &tab, std::string slice_name)
Create a slice in a table3d object with an aligned grid.
tensor_grid3(size_t sz, size_t sz2, size_t sz3)
Create a rank 3 tensor of size (sz,sz2,sz3)
size_t lookup_grid_val(size_t i, const double &val, double &val2)
Lookup index for grid closest to val, returning the grid point.
boost::numeric::ublas::vector< double > data
The data.
double get_grid(size_t i, size_t j) const
Lookup jth value on the ith grid.
double get_grid_x(size_t ix)
Get x grid point at index ix.
tensor_grid(size_t rank, const size_vec_t &dim)
Create a tensor of rank rank with sizes given in dim.
invalid argument supplied by user
tensor_grid2(size_t sz, size_t sz2)
Create a rank 2 tensor of size (sz,sz2)
size_t lookup_grid_packed(size_t i, double val)
Lookup index for grid closest to val.
tensor_grid4(size_t sz, size_t sz2, size_t sz3, size_t sz4)
Create a rank 4 tensor of size (sz,sz2,sz3,sz4)
Rank 2 tensor with a grid.
void set(size_t ix1, size_t ix2, size_t ix3, size_t ix4, double val)
Set the element indexed by (ix1,ix2,ix3,ix4) to value val.
double interp_linear(double x, double y, double z)
Interpolate (x,y,z) and return the results.
void set_val(const vec_t &grdp, double val, vec2_t &closest)
Set the element closest to grid point grdp to value val.
void set_grid(size_t i, size_t j, double val)
Set the jth value on the ith grid.
tensor_grid1()
Create an empty tensor.
Rank 3 tensor with a grid.
void lookup_grid_vec(const vec_t &vals, size_vec_t &indices) const
Lookup indices for grid closest point to vals.
double interp_linear(vec2_t &v)
Perform a linear interpolation of v into the function implied by the tensor and grid.
tensor_grid()
Create an empty tensor with zero rank.
tensor_grid3()
Create an empty tensor.
double interp_linear(double x)
Interpolate x and return the results.
void set(const size_vec_t &index, double val)
Set the element indexed by index to value val.
double interp(double x, double y, double z, double a)
Interpolate (x,y,z,a) and return the results.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
void set_grid(const vec_vec_t &grid_vecs)
Set grid from a vector of vectors of grid points.
double interp_linear_power_two(vec2_t &v)
Perform linear interpolation assuming that all indices can take only two values.
size_t itype
Interpolation type.
void set_val(const vec_t &grdp, double val)
Set the element closest to grid point grdp to value val.
Rank 4 tensor with a grid.
void get_size(size_t &nx, size_t &ny) const
Get the size of the slices.
double & get(const size_vec_t &index)
Get the element indexed by index.
double interp(double x, double y)
Interpolate (x,y) and return the results.
size_t find(const double x0) const
Search an increasing or decreasing vector for the interval containing x0
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
size_t lookup_grid(size_t i, double val)
Lookup index for grid closest to val.
void set(size_t ix1, double val)
Set the element indexed by (ix1) to value val.
ubvector & get_data()
Return a reference to the data (for HDF I/O)
void unpack_indices(size_t ix, size_vec_t &index)
Unpack the single vector index into indices.
bool grid_set
If true, the grid has been set by the user.
void resize(size_t rank, const size_vec_t &dim)
Resize the tensor to rank rank with sizes given in dim.
void set(size_t ix1, size_t ix2, size_t ix3, double val)
Set the element indexed by (ix1,ix2,ix3) to value val.
double get_grid_y(size_t iy)
Get y grid point at index iy.
void set(size_t ix, size_t iy, std::string name, double val)
Set element in slice name at location ix,iy to value val.
void set_grid_packed(const vec_t &grid_vec)
Set the grid.
double interp(double x, double y, double z)
Interpolate (x,y,z) and return the results.
Searching class for monotonic data with caching.
A data structure containing many slices of two-dimensional data points defined on a grid...
double interp(double x)
Interpolate x and return the results.
void set_interp_type(size_t interp_type)
Set interpolation type.
Store data in an O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl...
void new_slice(std::string name)
Add a new slice.
size_t total_size() const
Returns the size of the tensor (the product of the sizes over every index)
size_t lookup_grid_packed_val(size_t i, double val, double &val2)
Lookup index for grid closest to val.
tensor_grid2()
Create an empty tensor.
double interp_linear(double x, double y)
Interpolate (x,y) and return the results.
double interpolate(double *vals)
Interpolate values vals into the tensor, returning the result.
void set_xy(std::string x_name, size_t nx, const vec_t &x, std::string y_name, size_t ny, const vec2_t &y)
Initialize the x-y grid.
std::string szttos(size_t x)
Convert a size_t to a string.
boost::numeric::ublas::vector< size_t > size
A rank-sized vector of the sizes of each dimension.
void hdf_input(hdf_file &hf, o2scl::table< vec_t > &t, std::string name)
Input a o2scl::table object from a hdf_file.
void set(size_t ix1, size_t ix2, double val)
Set the element indexed by (ix1,ix2) to value val.
void copy_slice_interp(size_t ix_x, size_t ix_y, size_vec_t &index, table3d &tab, std::string slice_name)
Copy to a slice in a table3d object using interpolation.
Tensor class with arbitrary dimensions.