tensor: permutation of indices inside a symmetry group
This commit is contained in:
2
mat.cc
2
mat.cc
@@ -2137,6 +2137,8 @@ NRMat< std::complex<double> >::operator*(const NRSMat< std::complex<double> > &r
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NRMat<T>& NRMat<T>::conjugateme() {
|
NRMat<T>& NRMat<T>::conjugateme() {
|
||||||
|
if(!LA_traits<T>::is_complex()) return *this;
|
||||||
|
copyonwrite();
|
||||||
#ifdef CUDALA
|
#ifdef CUDALA
|
||||||
if(location != cpu) laerror("general conjugation only on CPU");
|
if(location != cpu) laerror("general conjugation only on CPU");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
3
smat.cc
3
smat.cc
@@ -872,6 +872,9 @@ NRSMat<std::complex<double> > NRSMat<std::complex<double> >::inverse() {return
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NRSMat<T>& NRSMat<T>::conjugateme() {
|
NRSMat<T>& NRSMat<T>::conjugateme() {
|
||||||
|
if(!LA_traits<T>::is_complex()) return *this;
|
||||||
|
copyonwrite();
|
||||||
|
|
||||||
#ifdef CUDALA
|
#ifdef CUDALA
|
||||||
if(location != cpu) laerror("general conjugation only on CPU");
|
if(location != cpu) laerror("general conjugation only on CPU");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
38
tensor.cc
38
tensor.cc
@@ -142,8 +142,8 @@ switch(I.size()) //a few special cases for efficiency
|
|||||||
NRVec<LA_index> II(I);
|
NRVec<LA_index> II(I);
|
||||||
II.copyonwrite();
|
II.copyonwrite();
|
||||||
if(g.offset!=0) II -= g.offset;
|
if(g.offset!=0) II -= g.offset;
|
||||||
int parity=netsort(II.size(),&II[0]);
|
int nswaps=netsort(II.size(),&II[0]);
|
||||||
*sign= (parity&1) ? g.symmetry : 1;
|
*sign= (nswaps&1) ? g.symmetry : 1;
|
||||||
if(g.symmetry == -1) //antisymmetric - do not store zero diagonal
|
if(g.symmetry == -1) //antisymmetric - do not store zero diagonal
|
||||||
{
|
{
|
||||||
for(int i=0; i<I.size()-1; ++i)
|
for(int i=0; i<I.size()-1; ++i)
|
||||||
@@ -2165,6 +2165,40 @@ apply_permutation_algebra(tmp,pb,true,(T)1,beta);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Tensor<T>::permute_inside_group(int g, const NRPerm<int> &p, bool inverse)
|
||||||
|
{
|
||||||
|
if(g<0||g>=shape.size()) laerror("group out of range");
|
||||||
|
if(shape[g].symmetry==0) laerror("permutation possible only inside symmetric index groups");
|
||||||
|
if(shape[g].number!=p.size()) laerror("permutation size mismatch to index number");
|
||||||
|
if(!p.is_valid()) laerror("invalid permutation in permute_inside_group");
|
||||||
|
int par=p.parity();
|
||||||
|
if(par<0)
|
||||||
|
{
|
||||||
|
switch(shape[g].symmetry)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
data.negateme();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
data.conjugateme();
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
data.negateconjugateme();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(is_named())
|
||||||
|
{
|
||||||
|
int ii=0;
|
||||||
|
for(int i=0; i<g; ++i) ii+= shape[i].number;
|
||||||
|
NRVec<INDEXNAME> tmp=(names.subvector(ii,ii+p.size()-1)).permuted(p,inverse);
|
||||||
|
for(int i=0; i<p.size(); ++i) names[ii+i]=tmp[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template class Tensor<double>;
|
template class Tensor<double>;
|
||||||
|
|||||||
2
tensor.h
2
tensor.h
@@ -384,6 +384,7 @@ public:
|
|||||||
void split_index_group(int group); //formal in-place split of a non-symmetric index group WITHOUT the need for data reorganization or names rearrangement
|
void split_index_group(int group); //formal in-place split of a non-symmetric index group WITHOUT the need for data reorganization or names rearrangement
|
||||||
void split_index_group1(int group); //formal in-place split of the leftmost index in a non-symmetric index group WITHOUT the need for data reorganization or names rearrangement
|
void split_index_group1(int group); //formal in-place split of the leftmost index in a non-symmetric index group WITHOUT the need for data reorganization or names rearrangement
|
||||||
void merge_adjacent_index_groups(int groupfrom, int groupto); //formal merge of non-symmetric index groups WITHOUT the need for data reorganization or names rearrangement
|
void merge_adjacent_index_groups(int groupfrom, int groupto); //formal merge of non-symmetric index groups WITHOUT the need for data reorganization or names rearrangement
|
||||||
|
void permute_inside_group(int group, const NRPerm<int> &p, bool inverse=false); //permute indices inside a symmetric index group only
|
||||||
|
|
||||||
Tensor merge_index_groups(const NRVec<int> &groups) const;
|
Tensor merge_index_groups(const NRVec<int> &groups) const;
|
||||||
Tensor flatten(int group= -1) const; //split and uncompress a given group or all of them, leaving flat index order the same
|
Tensor flatten(int group= -1) const; //split and uncompress a given group or all of them, leaving flat index order the same
|
||||||
@@ -653,7 +654,6 @@ NRMat<T> mat(t.data,range*(range-1)/2,range*(range-1)/2);
|
|||||||
f=fourindex_dense<antisymtwoelectronrealdirac,T,I>(range,NRSMat<T>(mat)); //symmetrize mat
|
f=fourindex_dense<antisymtwoelectronrealdirac,T,I>(range,NRSMat<T>(mat)); //symmetrize mat
|
||||||
}
|
}
|
||||||
|
|
||||||
//@@@formal permutation of names inside a sym/antisy group (with possible sign change)
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
114
vec.cc
114
vec.cc
@@ -869,6 +869,7 @@ return -1;
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NRVec<T>& NRVec<T>::conjugateme() {
|
NRVec<T>& NRVec<T>::conjugateme() {
|
||||||
|
if(!LA_traits<T>::is_complex()) return *this;
|
||||||
copyonwrite();
|
copyonwrite();
|
||||||
#ifdef CUDALA
|
#ifdef CUDALA
|
||||||
if(location != cpu) laerror("general conjugation only on CPU");
|
if(location != cpu) laerror("general conjugation only on CPU");
|
||||||
@@ -877,6 +878,29 @@ copyonwrite();
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
NRVec<T>& NRVec<T>::negateconjugateme() {
|
||||||
|
if(!LA_traits<T>::is_complex()) negateme();
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location != cpu) laerror("general conjugation only on CPU");
|
||||||
|
#endif
|
||||||
|
for(int i=0; i<nn; ++i) v[i] = -LA_traits<T>::conjugate(v[i]);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
NRVec<T>& NRVec<T>::negateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location != cpu) laerror("general conjugation only on CPU");
|
||||||
|
#endif
|
||||||
|
for(int i=0; i<nn; ++i) v[i] = -v[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* conjugate this complex vector
|
* conjugate this complex vector
|
||||||
@@ -912,6 +936,96 @@ NRVec<std::complex<float> >& NRVec<std::complex<float> >::conjugateme() {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NRVec<std::complex<double> >& NRVec<std::complex<double> >::negateconjugateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location == cpu){
|
||||||
|
#endif
|
||||||
|
cblas_dscal((size_t)nn, -1.0, ((double *)v) , 2);
|
||||||
|
#ifdef CUDALA
|
||||||
|
}else{
|
||||||
|
cublasDscal((size_t)nn, -1.0, ((double *)v) , 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NRVec<std::complex<float> >& NRVec<std::complex<float> >::negateconjugateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location == cpu){
|
||||||
|
#endif
|
||||||
|
cblas_sscal((size_t)nn, -1.0, ((float *)v) , 2);
|
||||||
|
#ifdef CUDALA
|
||||||
|
}else{
|
||||||
|
cublasSscal((size_t)nn, -1.0, ((float *)v) , 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NRVec<std::complex<double> >& NRVec<std::complex<double> >::negateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location == cpu){
|
||||||
|
#endif
|
||||||
|
cblas_dscal((size_t)nn*2, -1.0, ((double *)v) , 1);
|
||||||
|
#ifdef CUDALA
|
||||||
|
}else{
|
||||||
|
cublasDscal((size_t)nn*2, -1.0, ((double *)v) , 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NRVec<std::complex<float> >& NRVec<std::complex<float> >::negateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location == cpu){
|
||||||
|
#endif
|
||||||
|
cblas_sscal((size_t)nn*2, -1.0, ((float *)v) , 1);
|
||||||
|
#ifdef CUDALA
|
||||||
|
}else{
|
||||||
|
cublasSscal((size_t)nn*2, -1.0, ((float *)v) , 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NRVec<double>& NRVec<double>::negateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location == cpu){
|
||||||
|
#endif
|
||||||
|
cblas_dscal((size_t)nn, -1.0, v , 1);
|
||||||
|
#ifdef CUDALA
|
||||||
|
}else{
|
||||||
|
cublasDscal((size_t)nn, -1.0, v , 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NRVec<float>& NRVec<float>::negateme() {
|
||||||
|
copyonwrite();
|
||||||
|
#ifdef CUDALA
|
||||||
|
if(location == cpu){
|
||||||
|
#endif
|
||||||
|
cblas_sscal((size_t)nn, -1.0, v , 1);
|
||||||
|
#ifdef CUDALA
|
||||||
|
}else{
|
||||||
|
cublasSscal((size_t)nn, -1.0, v , 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************//**
|
/***************************************************************************//**
|
||||||
* sum up the elements of current vector of general type <code>T</code>
|
* sum up the elements of current vector of general type <code>T</code>
|
||||||
|
|||||||
3
vec.h
3
vec.h
@@ -303,6 +303,9 @@ public:
|
|||||||
NRVec& conjugateme();
|
NRVec& conjugateme();
|
||||||
inline NRVec conjugate() const {NRVec r(*this); r.conjugateme(); return r;};
|
inline NRVec conjugate() const {NRVec r(*this); r.conjugateme(); return r;};
|
||||||
|
|
||||||
|
NRVec& negateconjugateme();
|
||||||
|
NRVec& negateme();
|
||||||
|
|
||||||
//! determine the actual value of the reference counter
|
//! determine the actual value of the reference counter
|
||||||
inline int getcount() const {return count?*count:0;}
|
inline int getcount() const {return count?*count:0;}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user