31 namespace pexExcept = lsst::pex::exceptions;
33 namespace afwMath = lsst::afw::math;
38 _kernelColFunctionPtr(),
39 _kernelRowFunctionPtr(),
40 _localColList(0), _localRowList(0),
41 _kernelX(0), _kernelY(0),
42 _kernelRowCache(0), _kernelColCache(0)
54 Kernel(width, height, kernelColFunction.getNParameters() + kernelRowFunction.getNParameters(),
56 _kernelColFunctionPtr(kernelColFunction.clone()),
57 _kernelRowFunctionPtr(kernelRowFunction.clone()),
58 _localColList(width), _localRowList(height),
59 _kernelX(width), _kernelY(height),
60 _kernelRowCache(0), _kernelColCache(0)
70 std::vector<Kernel::SpatialFunctionPtr>
const& spatialFunctionList
72 Kernel(width, height, spatialFunctionList),
73 _kernelColFunctionPtr(kernelColFunction.clone()),
74 _kernelRowFunctionPtr(kernelRowFunction.clone()),
75 _localColList(width), _localRowList(height),
76 _kernelX(width), _kernelY(height),
77 _kernelRowCache(0), _kernelColCache(0)
80 != spatialFunctionList.size()) {
81 std::ostringstream os;
82 os <<
"kernelColFunction.getNParameters() + kernelRowFunction.getNParameters() = "
84 <<
" != " << spatialFunctionList.size() <<
" = " <<
"spatialFunctionList.size()";
85 throw LSST_EXCEPT(pexExcept::InvalidParameterError, os.str());
93 if (this->isSpatiallyVarying()) {
95 *(this->_kernelColFunctionPtr), *(this->_kernelRowFunctionPtr), this->_spatialFunctionList));
98 *(this->_kernelColFunctionPtr), *(this->_kernelRowFunctionPtr)));
100 retPtr->setCtr(this->getCtr());
101 retPtr->computeCache(this->getCacheSize());
106 std::vector<Pixel> &colList,
107 std::vector<Pixel> &rowList,
112 if (static_cast<int>(colList.size()) != this->getWidth()
113 ||
static_cast<int>(rowList.size()) != this->getHeight()) {
114 std::ostringstream os;
115 os <<
"colList.size(), rowList.size() = ("
116 << colList.size() <<
", " << rowList.size()
117 <<
") != ("<< this->getWidth() <<
", " << this->getHeight()
118 <<
") = " <<
"kernel dimensions";
119 throw LSST_EXCEPT(pexExcept::InvalidParameterError, os.str());
121 if (this->isSpatiallyVarying()) {
122 this->setKernelParametersFromSpatialModel(x, y);
125 return basicComputeVectors(colList, rowList, doNormalize);
130 return _kernelColFunctionPtr->clone();
135 return _kernelRowFunctionPtr->clone();
139 std::ostringstream os;
140 os << prefix <<
"SeparableKernel:" << std::endl;
141 os << prefix <<
"..x (width) function: "
142 << (_kernelColFunctionPtr ? _kernelColFunctionPtr->toString() :
"None") << std::endl;
143 os << prefix <<
"..y (rows) function: "
144 << (_kernelRowFunctionPtr ? _kernelRowFunctionPtr->toString() :
"None") << std::endl;
150 std::vector<double> allParams = _kernelColFunctionPtr->getParameters();
151 std::vector<double> yParams = _kernelRowFunctionPtr->getParameters();
152 std::copy(yParams.begin(), yParams.end(), std::back_inserter(allParams));
164 double imSum = basicComputeVectors(_localColList, _localRowList, doNormalize);
168 for (std::vector<Pixel>::iterator colIter = _localColList.begin();
169 colIter != _localColList.end(); ++colIter, ++imPtr) {
170 *imPtr = (*colIter)*_localRowList[
y];
178 unsigned int const nColParams = _kernelColFunctionPtr->getNParameters();
179 if (ind < nColParams) {
180 _kernelColFunctionPtr->setParameter(ind, value);
182 _kernelRowFunctionPtr->setParameter(ind - nColParams, value);
191 std::vector<Pixel> &colList,
192 std::vector<Pixel> &rowList,
196 if (_kernelColCache.empty()) {
197 for (
unsigned int i = 0; i != colList.size(); ++i) {
198 double colFuncValue = (*_kernelColFunctionPtr)(_kernelX[i]);
199 colList[i] = colFuncValue;
200 colSum += colFuncValue;
203 int const cacheSize = _kernelColCache.size();
205 int const indx = this->getKernelParameter(0)*
cacheSize;
207 std::vector<double> &cachedValues = _kernelColCache.at(indx);
208 for (
unsigned int i = 0; i != colList.size(); ++i) {
209 double colFuncValue = cachedValues[i];
210 colList[i] = colFuncValue;
211 colSum += colFuncValue;
216 if (_kernelRowCache.empty()) {
217 for (
unsigned int i = 0; i != rowList.size(); ++i) {
218 double rowFuncValue = (*_kernelRowFunctionPtr)(_kernelY[i]);
219 rowList[i] = rowFuncValue;
220 rowSum += rowFuncValue;
223 int const cacheSize = _kernelRowCache.size();
225 int const indx = this->getKernelParameter(1)*
cacheSize;
227 std::vector<double> &cachedValues = _kernelRowCache.at(indx);
228 for (
unsigned int i = 0; i != rowList.size(); ++i) {
229 double rowFuncValue = cachedValues[i];
230 rowList[i] = rowFuncValue;
231 rowSum += rowFuncValue;
234 if (indx == cacheSize/2) {
235 if (::fabs(rowFuncValue - (*_kernelRowFunctionPtr)(_kernelX[i])) > 1e-2) {
236 std::cout << indx <<
" " << i <<
" "
237 << rowFuncValue <<
" "
238 << (*_kernelRowFunctionPtr)(_kernelX[i])
246 double imSum = colSum * rowSum;
248 if ((colSum == 0) || (rowSum == 0)) {
249 throw LSST_EXCEPT(pexExcept::OverflowError,
"Cannot normalize; kernel sum is 0");
251 for (std::vector<Pixel>::iterator colIter = colList.begin(); colIter != colList.end(); ++colIter) {
255 for (std::vector<Pixel>::iterator rowIter = rowList.begin(); rowIter != rowList.end(); ++rowIter) {
269 std::vector<double>
const&
x,
271 std::vector<std::vector<double> > *kernelCache)
273 if (cacheSize <= 0) {
274 kernelCache->erase(kernelCache->begin(), kernelCache->end());
278 if (kernelCache[0].size() != x.size()) {
279 kernelCache->erase(kernelCache->begin(), kernelCache->end());
282 int const old_cacheSize = kernelCache->size();
284 if (cacheSize == old_cacheSize) {
288 if (cacheSize < old_cacheSize) {
289 kernelCache->erase(kernelCache->begin() +
cacheSize, kernelCache->end());
291 kernelCache->resize(cacheSize);
292 for (
int i = old_cacheSize; i !=
cacheSize; ++i) {
293 (*kernelCache)[i].resize(x.size());
300 func->setParameter(0, (i + 0.5)/static_cast<double>(cacheSize));
301 for (
unsigned int j = 0; j != x.size(); ++j) {
302 (*kernelCache)[i][j] = (*func)(x[j]);
313 func = getKernelColFunction();
314 _computeCache(cacheSize, _kernelY, func, &_kernelColCache);
316 func = getKernelRowFunction();
317 _computeCache(cacheSize, _kernelX, func, &_kernelRowCache);
321 return _kernelColCache.size();
virtual double doComputeImage(lsst::afw::image::Image< Pixel > &image, bool doNormalize) const
Low-level version of computeImage.
Declare the Kernel class and subclasses.
virtual int getCacheSize() const
Get the current cache size (0 if none)
double computeVectors(std::vector< Pixel > &colList, std::vector< Pixel > &rowList, bool doNormalize, double x=0.0, double y=0.0) const
Compute the column and row arrays in place, where kernel(col, row) = colList(col) * rowList(row) ...
KernelFunctionPtr getKernelRowFunction() const
Get a deep copy of the row kernel function.
Include files required for standard LSST Exception handling.
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the kernel.
SelectEigenView< T >::Type copy(Eigen::EigenBase< T > const &other)
Copy an arbitrary Eigen expression into a new EigenView.
A kernel described by a pair of functions: func(x, y) = colFunc(x) * rowFunc(y)
boost::shared_ptr< KernelFunction > KernelFunctionPtr
tbl::Key< int > cacheSize
table::Key< table::Array< Kernel::Pixel > > image
double basicComputeVectors(std::vector< Pixel > &colList, std::vector< Pixel > &rowList, bool doNormalize) const
Compute the column and row arrays in place, where kernel(col, row) = colList(col) * rowList(row) ...
void ImageT ImageT int float saturatedPixelValue int const width
KernelFunctionPtr getKernelColFunction() const
Get a deep copy of the col kernel function.
A Function taking one argument.
SeparableKernel()
Construct an empty spatially invariant SeparableKernel of size 0x0.
int getHeight() const
Return the number of rows in the image.
void ImageT ImageT int float saturatedPixelValue int const height
virtual void setKernelParameter(unsigned int ind, double value) const
Set one kernel parameter.
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the kernel.
#define LSST_EXCEPT(type,...)
virtual void computeCache(int const cacheSize)
Compute a cache of Kernel values, if desired.
unsigned int getNParameters() const
Return the number of function parameters.
x_iterator row_begin(int y) const
virtual void _setKernelXY()
virtual std::vector< double > getKernelParameters() const
Return the current kernel parameters.
Kernels are used for convolution with MaskedImages and (eventually) Images.