https://github.com/ITensor/ITensor
Raw File
Tip revision: 6b54fa39438c296f80049dc937ca966746eded68 authored by Miles Stoudenmire on 11 April 2016, 18:02:29 UTC
Updated localop.h diag method to correctly use delta function to tie indices. Fixes #96 - thanks to Xiongjie Yu for reporting it.
Tip revision: 6b54fa3
iqtensor.ih
//
// Distributed under the ITensor Library License, Version 1.2
//    (See accompanying LICENSE file.)
//
#ifndef __ITENSOR_IQTENSOR_IH
#define __ITENSOR_IQTENSOR_IH

namespace itensor {

template<>
IQTensor::
ITensorT(Complex val);

//template<> 
//template <typename... IQIVals>
//IQTensor::
//ITensorT(IQIndexVal const& iv1,
//         IQIVals const&... rest)
//  : scale_(1.)
//    { 
//    const size_t size = 1+sizeof...(rest);
//    auto ivs = std::array<IQIndexVal,size>{{iv1,rest...}};
//    std::array<IQIndex,size> inds;
//    for(size_t j = 0; j < size; ++j) inds[j] = ivs[j].index;
//    is_ = IQIndexSet(inds);
//    QN div;
//    for(auto& iv : ivs) div += iv.qn()*iv.index.dir();
//    store_ = newITData<QDenseReal>(is_,div);
//    set(iv1,rest...,1.);
//    }


//template<>
//template<typename... IQIndexVals>
//void IQTensor::
//set(Cplx val, const IQIndexVals&... ivs)
//    {
//    static constexpr auto size = sizeof...(ivs);
//    std::array<IQIndexVal,size> vals{{ static_cast<IQIndexVal>(ivs)...}};
//    //If this IQTensor is not allocated, compute QN flux from ivs
//    if(!store_)
//        {
//#ifdef DEBUG
//        if(!is_) Error("Setting element of default constructed IQTensor");
//#endif
//        QN div;
//        for(auto& iv : vals) div += iv.qn()*iv.index.dir();
//        if(val.imag() == 0) store_ = newITData<IQTReal>(is_,div);
//        else Error("Setting complex IQTensor element not implemented");
//        }
//    scaleTo(1.);
//    typename SetElt<Real,IQIndex>::Inds inds(size);
//    detail::permute_map(is_,vals,inds,[](const IQIndexVal& iv) { return iv.val-1; });
//    if(val.imag() == 0)
//        doTask(SetElt<Real,IQIndex>{val.real(),is_,inds},store_);
//    else
//        doTask(SetElt<Cplx,IQIndex>{val,is_,inds},store_);
//    }

inline IQTensor& 
operator*=(IQTensor& T, IQIndexVal const& iv) 
    { 
    return T *= setElt(iv); 
    } 
IQTensor inline
operator*(IQTensor T, IQIndexVal const& iv) 
    { 
    T *= iv; 
    return T; 
    }
IQTensor inline
operator*(IQIndexVal const& iv, IQTensor const& T) 
    { 
    return setElt(iv) * T;
    }

inline ITensor& 
operator*=(ITensor& T, IQIndexVal const& iv) 
    { 
    return T *= setElt(IndexVal(iv)); 
    } 

ITensor inline
operator*(ITensor T, IQIndexVal const& iv) 
    { 
    return T * IndexVal(iv);
    }

ITensor inline
operator*(IQIndexVal const& iv, ITensor const& T) 
    { 
    return IndexVal(iv) * T;
    }

ITensor inline
operator*(IQTensor const& T, ITensor const& t) 
    { 
    auto TT = toITensor(T);
    TT *= t; 
    return TT; 
    }

ITensor inline
operator*(const ITensor& t, const IQTensor& T) 
    { 
    return operator*(T,t);
    }

ITensor inline
operator*(IQTensor const& T, IndexVal const& iv)
    { 
    return toITensor(T)*iv; 
    }

ITensor inline
operator*(IndexVal const& iv, IQTensor const& T) 
    { 
    return setElt(iv) * toITensor(T); 
    }

template<typename... Inds>
IQTensor
combiner(IQIndex const& i1, 
         Inds const&... inds)
    {
    return combiner(std::vector<IQIndex>{i1,inds...});
    }

template<typename... Inds>
IQTensor
delta(IQIndex const& i1,
      Inds const&... inds)
    {
    auto is = IQIndexSet(i1,inds...);
    auto dat = QDiagReal(is,1.);
    return IQTensor(std::move(is),std::move(dat));
    }

template<typename... Inds>
IQTensor
randomTensor(IQIndex const& i1, Inds&&... inds)
    {
    static_assert(stdx::false_regardless_of<Inds...>::value,"Must provide a QN or IQIndexVals to IQIndex version of randomTensor");
    return IQTensor{};
    }

template<typename... IQIndVals>
IQTensor
randomTensor(IQIndexVal const& iv1, 
             IQIndVals&&... ivs)
    {
    auto T = setElt(iv1,std::forward<IQIndVals>(ivs)...);
    try {
        return random(T);
        }
    catch(ITError const& e)
        {
        Error("Cannot randomize IQTensor, possibly incompatible flux");
        }
    return T;
    }

template<typename... Inds>
IQTensor
randomTensor(QN const& q, IQIndex const& i1, Inds &&... inds)
    {
    auto is = IQIndexSet{i1,std::forward<Inds>(inds)...};
    auto dat = QDenseReal{is,q};
    auto T = IQTensor(std::move(is),std::move(dat));
    try {
        return random(T);
        }
    catch(ITError const& e)
        {
        Error("Cannot randomize IQTensor, possibly incompatible flux");
        }
    return T;
    }

template<typename... VArgs>
IQTensor
randomTensorC(QN const& q, VArgs&&... vargs)
    {
    auto T = randomTensor(q,std::forward<VArgs>(vargs)...);
    return T+1_i*random(T);
    }

template<typename... Inds>
IQTensor
mixedIQTensor(IQIndex const& i1, 
              Inds const&... inds)
    {
    auto is = IQIndexSet(i1,inds...);
    auto size = area(is);
    return IQTensor(std::move(is),QMixed<Real>(size));
    }

} //namespace itensor

#endif
back to top