LVector LTransform::operator*(const LVector rhs) const { if (_orderIn != rhs.getOrder()) FormatAndThrow<>() << "Order mismatch between LTransform [" << _orderIn << "] and LVector [" << rhs.getOrder() << "]"; boost::shared_ptr<tmv::Vector<double> > out(new tmv::Vector<double>(sizeOut())); *out = (*_m) * rhs.rVector(); return LVector(_orderOut, out); }
void ShapeletFitImage(double sigma, LVector& bvec, const BaseImage<T>& image, double image_scale, const Position<double>& center) { // TODO: It would be nice to be able to fit this with an arbitrary WCS to fit in // sky coordinates. For now, just use the image_scale. dbg<<"Start ShapeletFitImage:\n"; xdbg<<"sigma = "<<sigma<<std::endl; xdbg<<"bvec = "<<bvec<<std::endl; xdbg<<"center = "<<center<<std::endl; double scale = image_scale / sigma; xdbg<<"scale = "<<scale<<std::endl; const int nx = image.getXMax() - image.getXMin() + 1; const int ny = image.getYMax() - image.getYMin() + 1; xdbg<<"nx,ny = "<<nx<<','<<ny<<std::endl; const int npts = nx * ny; xdbg<<"npts = "<<npts<<std::endl; tmv::Vector<double> x(npts); tmv::Vector<double> y(npts); tmv::Vector<double> I(npts); int i=0; for (int ix = image.getXMin(); ix <= image.getXMax(); ++ix) { for (int iy = image.getYMin(); iy <= image.getYMax(); ++iy,++i) { x[i] = (ix - center.x) * scale; y[i] = (iy - center.y) * scale; I[i] = image(ix,iy); } } xxdbg<<"x = "<<x<<std::endl; xxdbg<<"y = "<<y<<std::endl; xxdbg<<"I = "<<I<<std::endl; tmv::Matrix<double> psi(npts,bvec.size()); LVector::basis(x.view(),y.view(),psi.view(),bvec.getOrder(),sigma); // I = psi * b // TMV solves this by writing b = I/psi. // We use QRP in case the psi matrix is close to singular (although it shouldn't be). psi.divideUsing(tmv::QRP); bvec.rVector() = I/psi; xdbg<<"Done FitImage: bvec = "<<bvec<<std::endl; }