#ifndef __COSMOTOOL_FOURIER_HEALPIX_DETAILS_ALM_HPP #define __COSMOTOOL_FOURIER_HEALPIX_DETAILS_ALM_HPP namespace CosmoTool { template class HealpixFourierALM: public FourierMap > { private: std::complex *alms; long m_size; long Lmax_, Mmax_, TVal_; Eigen::aligned_allocator > alloc; public: typedef unsigned long LType; LType Lmax() const { return Lmax_; } LType Mmax() const { return Mmax_; } LType Num_Alms() const { return ((Mmax_+1)*(Mmax_+2))/2 + (Mmax_+1)*(Lmax_-Mmax_); } LType index_l0(LType m) const { return ((m*(TVal_-m))/2); } LType index(LType l, LType m) const { return index_l0(m) + l; } HealpixFourierALM(LType lmax, LType mmax) : Lmax_(lmax), Mmax_(mmax), TVal_(2*lmax+1) { m_size = Num_Alms(); alms = alloc.allocate(m_size); } virtual ~HealpixFourierALM() { alloc.deallocate(alms, m_size); } virtual const std::complex* data() const { return alms; } virtual std::complex * data() { return alms;} virtual long size() const { return m_size; } virtual FourierMap > *mimick() const { return new HealpixFourierALM(Lmax_, Mmax_); } virtual std::complex dot_product(const FourierMap >& other) const throw(std::bad_cast) { const HealpixFourierALM& mfm = dynamic_cast&>(other); typedef typename FourierMap >::MapType MapType; std::complex S; if (m_size != mfm.m_size) throw std::bad_cast(); MapType m1(alms, m_size); MapType m2(mfm.alms, mfm.m_size); S = (m1.block(0,0,1,Lmax_+1).conjugate() * m2.block(0,0,1,Lmax_+1)).sum(); S += std::complex(2,0)*(m1.block(0,1+Lmax_,1,m_size-1-Lmax_).conjugate() * m2.block(0,1+Lmax_,1,m_size-1-Lmax_)).sum(); return S; } }; }; #endif