| 196 | } |
| 197 | |
| 198 | af_err af_iterative_deconv(af_array* out, const af_array in, const af_array ker, |
| 199 | const unsigned iterations, const float relax_factor, |
| 200 | const af_iterative_deconv_algo algo) { |
| 201 | try { |
| 202 | const ArrayInfo& inputInfo = getInfo(in); |
| 203 | const dim4& inputDims = inputInfo.dims(); |
| 204 | const ArrayInfo& kernelInfo = getInfo(ker); |
| 205 | const dim4& kernelDims = kernelInfo.dims(); |
| 206 | |
| 207 | DIM_ASSERT(2, (inputDims.ndims() == 2)); |
| 208 | DIM_ASSERT(3, (kernelDims.ndims() == 2)); |
| 209 | ARG_ASSERT(4, (iterations > 0)); |
| 210 | ARG_ASSERT(5, std::isfinite(relax_factor)); |
| 211 | ARG_ASSERT(5, (relax_factor > 0)); |
| 212 | ARG_ASSERT(6, (algo == AF_ITERATIVE_DECONV_DEFAULT || |
| 213 | algo == AF_ITERATIVE_DECONV_LANDWEBER || |
| 214 | algo == AF_ITERATIVE_DECONV_RICHARDSONLUCY)); |
| 215 | af_array res = 0; |
| 216 | unsigned iters = iterations; |
| 217 | float rfac = relax_factor; |
| 218 | |
| 219 | af_dtype inputType = inputInfo.getType(); |
| 220 | switch (inputType) { |
| 221 | case f32: |
| 222 | res = iterDeconv<float>(in, ker, iters, rfac, algo); |
| 223 | break; |
| 224 | case s16: |
| 225 | res = iterDeconv<short>(in, ker, iters, rfac, algo); |
| 226 | break; |
| 227 | case u16: |
| 228 | res = iterDeconv<ushort>(in, ker, iters, rfac, algo); |
| 229 | break; |
| 230 | case s8: res = iterDeconv<schar>(in, ker, iters, rfac, algo); break; |
| 231 | case u8: res = iterDeconv<uchar>(in, ker, iters, rfac, algo); break; |
| 232 | default: TYPE_ERROR(1, inputType); |
| 233 | } |
| 234 | std::swap(res, *out); |
| 235 | } |
| 236 | CATCHALL; |
| 237 | return AF_SUCCESS; |
| 238 | } |
| 239 | |
| 240 | template<typename CT> |
| 241 | Array<CT> denominator(const Array<CT>& I, const Array<CT>& P, const float gamma, |