Line data Source code
1 : #include "WeightedL1Norm.h" 2 : #include "LinearOperator.h" 3 : 4 : namespace elsa 5 : { 6 : template <typename data_t> 7 0 : WeightedL1Norm<data_t>::WeightedL1Norm(const DataContainer<data_t>& weightingOp) 8 0 : : Functional<data_t>(weightingOp.getDataDescriptor()), _weightingOp{weightingOp} 9 : { 10 : // sanity check 11 0 : if (weightingOp.minElement() < 0) { 12 0 : throw InvalidArgumentError( 13 : "WeightedL1Norm: all weights in the w vector should be >= 0"); 14 : } 15 0 : } 16 : 17 : template <typename data_t> 18 0 : WeightedL1Norm<data_t>::WeightedL1Norm(const Residual<data_t>& residual, 19 : const DataContainer<data_t>& weightingOp) 20 0 : : Functional<data_t>(residual), _weightingOp{weightingOp} 21 : { 22 : // sanity check 23 0 : if (residual.getRangeDescriptor().getNumberOfCoefficients() 24 0 : != weightingOp.getDataDescriptor().getNumberOfCoefficients()) { 25 0 : throw InvalidArgumentError( 26 : "WeightedL1Norm: sizes of residual and weighting operator do not match"); 27 : } 28 : // sanity check 29 0 : if (weightingOp.minElement() < 0) { 30 0 : throw InvalidArgumentError( 31 : "WeightedL1Norm: all weights in the w vector should be >= 0"); 32 : } 33 0 : } 34 : 35 : template <typename data_t> 36 0 : const DataContainer<data_t>& WeightedL1Norm<data_t>::getWeightingOperator() const 37 : { 38 0 : return _weightingOp; 39 : } 40 : 41 : template <typename data_t> 42 0 : data_t WeightedL1Norm<data_t>::evaluateImpl(const DataContainer<data_t>& Rx) 43 : { 44 0 : return _weightingOp.dot(cwiseAbs(Rx)); 45 : } 46 : 47 : template <typename data_t> 48 0 : void WeightedL1Norm<data_t>::getGradientInPlaceImpl([[maybe_unused]] DataContainer<data_t>& Rx) 49 : { 50 0 : throw LogicError("WeightedL1Norm: not differentiable, so no gradient! (busted!)"); 51 : } 52 : 53 : template <typename data_t> 54 : LinearOperator<data_t> 55 0 : WeightedL1Norm<data_t>::getHessianImpl([[maybe_unused]] const DataContainer<data_t>& Rx) 56 : { 57 0 : throw LogicError("WeightedL1Norm: not differentiable, so no Hessian! (busted!)"); 58 : } 59 : 60 : template <typename data_t> 61 0 : WeightedL1Norm<data_t>* WeightedL1Norm<data_t>::cloneImpl() const 62 : { 63 0 : return new WeightedL1Norm(this->getResidual(), _weightingOp); 64 : } 65 : 66 : template <typename data_t> 67 0 : bool WeightedL1Norm<data_t>::isEqual(const Functional<data_t>& other) const 68 : { 69 0 : if (!Functional<data_t>::isEqual(other)) 70 0 : return false; 71 : 72 0 : auto otherWL1 = dynamic_cast<const WeightedL1Norm*>(&other); 73 0 : if (!otherWL1) 74 0 : return false; 75 : 76 0 : if (_weightingOp != otherWL1->_weightingOp) 77 0 : return false; 78 : 79 0 : return true; 80 : } 81 : 82 : // ------------------------------------------ 83 : // explicit template instantiation 84 : template class WeightedL1Norm<float>; 85 : template class WeightedL1Norm<double>; 86 : } // namespace elsa