46 #ifndef _PEXSI_NUMTNS_IMPL_HPP_
47 #define _PEXSI_NUMTNS_IMPL_HPP_
52 template <
class F> NumTns<F>::NumTns(Int m, Int n, Int p): m_(m), n_(n), p_(p), owndata_(true) {
53 if(
m_>0 &&
n_>0 &&
p_>0) {
data_ =
new F[
m_*
n_*
p_];
if(
data_ == NULL )
throw std::runtime_error(
"Cannot allocate memory."); }
else data_=NULL;
56 template <
class F> NumTns<F>::NumTns(Int m, Int n, Int p,
bool owndata, F* data): m_(m), n_(n), p_(p), owndata_(owndata) {
58 if(
m_>0 &&
n_>0 &&
p_>0) {
data_ =
new F[
m_*
n_*
p_];
if(
data_ == NULL )
throw std::runtime_error(
"Cannot allocate memory."); }
else data_=NULL;
65 template <
class F> NumTns<F>::NumTns(
const NumTns<F>& C): m_(C.m_), n_(C.n_), p_(C.p_), owndata_(C.owndata_) {
67 if(
m_>0 &&
n_>0 &&
p_>0) {
data_ =
new F[
m_*
n_*
p_];
if(
data_ == NULL )
throw std::runtime_error(
"Cannot allocate memory."); }
else data_=NULL;
74 template <
class F> NumTns<F>::~NumTns() {
76 if(m_>0 && n_>0 && p_>0) {
delete[] data_; data_ = NULL; }
80 template <
class F> NumTns<F>& NumTns<F>::operator=(
const NumTns<F>& C) {
82 if(m_>0 && n_>0 && p_>0) {
delete[] data_; data_ = NULL; }
84 m_ = C.m_; n_=C.n_; p_=C.p_; owndata_=C.owndata_;
86 if(m_>0 && n_>0 && p_>0) { data_ =
new F[m_*n_*p_];
if( data_ == NULL )
throw std::runtime_error(
"Cannot allocate memory."); }
else data_=NULL;
87 if(m_>0 && n_>0 && p_>0) {
for(Int i=0; i<m_*n_*p_; i++) data_[i] = C.data_[i]; }
94 template <
class F>
void NumTns<F>::Resize(Int m, Int n, Int p) {
95 if( owndata_ ==
false ){
96 throw std::logic_error(
"Tensor being resized must own data.");
98 if(m_!=m || n_!=n || p_!=p) {
99 if(m_>0 && n_>0 && p_>0) {
delete[] data_; data_ = NULL; }
100 m_ = m; n_ = n; p_=p;
101 if(m_>0 && n_>0 && p_>0) { data_ =
new F[m_*n_*p_];
if( data_ == NULL )
throw std::runtime_error(
"Cannot allocate memory."); }
else data_=NULL;
105 template <
class F>
const F& NumTns<F>::operator()(Int i, Int j, Int k)
const {
106 if( i < 0 || i >= m_ ||
109 throw std::logic_error(
"Index is out of bound." );
111 return data_[i+j*m_+k*m_*n_];
114 template <
class F> F& NumTns<F>::operator()(Int i, Int j, Int k) {
115 if( i < 0 || i >= m_ ||
118 throw std::logic_error(
"Index is out of bound." );
120 return data_[i+j*m_+k*m_*n_];
124 template <
class F> F* NumTns<F>::MatData (Int j)
const {
125 if( j < 0 || j >= p_ ) {
126 throw std::logic_error(
"Index is out of bound." );
128 return &(data_[j*m_*n_]);
131 template <
class F> F* NumTns<F>::VecData (Int j, Int k)
const {
132 if( j < 0 || j >= n_ ||
134 throw std::logic_error(
"Index is out of bound." );
137 return &(data_[k*m_*n_+j*m_]);
143 for(Int i=0; i < T.m() * T.n() * T.p(); i++) *(ptr++) = val;
155 for(Int i=0; i < T.m() * T.n() * T.p(); i++)
156 sum += abs(ptr[i]) * abs(ptr[i]);
163 #endif // _PEXSI_NUMTNS_IMPL_HPP_
Int n_
The size of second dimension.
Definition: NumTns.hpp:70
Int m_
The size of the first dimension.
Definition: NumTns.hpp:67
Real Energy(const NumMat< F > &M)
Energy computes the L2 norm of a matrix (treated as a vector).
Definition: NumMat_impl.hpp:142
bool owndata_
Whether it owns the data.
Definition: NumTns.hpp:76
void SetValue(NumMat< F > &M, F val)
SetValue sets a numerical matrix to a constant val.
Definition: NumMat_impl.hpp:137
Numerical tensor.
Definition: NumTns.hpp:63
F * data_
The pointer for the actual data.
Definition: NumTns.hpp:79
Int p_
The size of third dimension.
Definition: NumTns.hpp:73