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