aimsalgo 6.0.0
Neuroimaging image processing
wlms-estimator.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34
35#ifndef AIMS_ESTIMATION_WLMS_ESTIMATOR_H
36#define AIMS_ESTIMATION_WLMS_ESTIMATOR_H
37
38#include <cstdlib>
42
43//
44// Weighted Linear Mean Squared M-estimator
45//
46template < int D >
47class WLMSEstimator : public MEstimator< D >
48{
49 public:
50 WLMSEstimator( MEstimatorFunc& mfunc, float error,
51 bool verbose = false )
52 : MEstimator<D>(), _mfunc( mfunc ), _error( error ),
53 _verbose( verbose) { }
54 virtual ~WLMSEstimator() { }
55
56 void doit(
58 const carto::rc_ptr<carto::Volume< float > >& y, float& a,
60
61 protected:
63 float _error;
65
66 float sigma(
68 const carto::rc_ptr<carto::Volume< float > >& y, float a,
71
72 void step(
74 const carto::rc_ptr<carto::Volume< float > >& y, float& a,
76 const carto::rc_ptr<carto::Volume<float> >& error );
77};
78
79
80template < int D > inline
83 const carto::rc_ptr<carto::Volume< float > >& y, float a,
86{
87 int N = y->getSizeX(), n, k;
88 for ( n = 0; n < N; n++ )
89 {
90 error->at( n ) = y->at( n ) - a;
91 for ( k = 0; k < D; k++ )
92 error->at( n ) -= b.item( k ) * x->at( n ).item( k );
93 error->at( n ) = fabs( error->at( n ) );
94 }
95
96 carto::Volume<float> errorbis( &(*error) );
97 carto::sort( errorbis );
98
99 return 1.4826 * errorbis( N / 2 );
100}
101
102
103template < int D >
104inline
105void
107 const carto::rc_ptr<carto::Volume< float > >& y, float& a,
109 const carto::rc_ptr<carto::Volume<float> >& error )
110{
111 int N = y->getSizeX();
112 carto::VolumeRef<float> mat( D + 1, D + 1, 1, 1,
113 carto::AllocatorContext::fast() );
114 carto::VolumeRef<float> vec( D + 1, 1, 1, 1,
115 carto::AllocatorContext::fast() );
116 carto::VolumeRef<float> weight( N, 1, 1, 1,
117 carto::AllocatorContext::fast() );
118
119 mat = 0.0;
120 vec = 0.0;
121 weight = 0.0;
122
123 int k, n;
124
125 for ( n = 0; n < N; n++ )
126 {
127 weight( n ) = _mfunc.weight( error->at( n ) );
128 mat( 0, 0 ) += weight( n );
129 }
130
131 for ( k = 1; k <= D; k++ )
132 {
133 for ( n = 0; n < N; n++ )
134 mat( k, 0 ) += weight( n ) * x->at( n ).item( k - 1 );
135 mat( 0, k ) = mat( k, 0 );
136 }
137
138 int k1, k2;
139 for ( k1 = 1; k1 <= D; k1++ )
140 for ( k2 = 1; k2 <= k1; k2++ )
141 {
142 for ( n = 0; n < N; n++ )
143 mat( k1, k2 ) += weight( n ) *
144 x->at( n ).item( k1 - 1 ) * x->at( n ).item( k2 - 1 );
145 mat( k2, k1 ) = mat( k1, k2 );
146 }
147
148
149 for ( n = 0; n < N; n++ )
150 {
151 vec( 0 ) += weight( n ) * y->at( n );
152 for ( k = 1; k <= D; k++ )
153 vec( k ) += weight( n ) * y->at( n ) * x->at( n ).item( k - 1 );
154 }
155
157 a = res( 0 );
158 for ( k = 1; k <= D; k++ )
159 b.item( k - 1 ) = res( k );
160}
161
162
163template < int D > inline
165 const carto::rc_ptr<carto::Volume< float > >& y, float& a,
167{
168 ASSERT( x->getSizeY() == 1 && x->getSizeZ() == 1 && x->getSizeT() == 1 );
169 ASSERT( y->getSizeY() == 1 && y->getSizeZ() == 1 && y->getSizeT() == 1 );
170 ASSERT( x->getSizeX() == y->getSizeX() );
171
172 float obja, objb;
173 float old_a;
175
176 // estimate starting value with LMS fit
177 LMSEstimator<D> lms;
178 lms.doit( x, y, a, b );
179
180 carto::VolumeRef<float> error( x->getSizeX() );
181 int count = 0;
182 // perform iteration of robust estimation until convergence
183 do
184 {
185 ASSERT( count != 100 ); // maximum iteration
186 old_a = a;
187 old_b = b;
188 _mfunc.setSigma( sigma( x, y, old_a,old_b, error ) );
189 step( x, y, a, b, error );
190 obja = fabs( a - old_a ) / ( fabs( a ) + fabs( old_a ) );
191 objb = norm( b - old_b ) / ( norm( b ) + norm( old_b ) );
192 if ( _verbose )
193 std::cout
194 << "Obja : " << obja << " "
195 << "Objb : " << objb << " "
196 << "a : " << a << " "
197 << "b : " << b << std::endl;
198 count++;
199 }
200 while ( obja > _error || objb > _error );
201}
202
203
204#endif
#define ASSERT(EX)
const T & item(int d) const
void doit(const carto::rc_ptr< carto::Volume< AimsVector< float, D > > > &x, const carto::rc_ptr< carto::Volume< float > > &y, float &a, AimsVector< float, D > &b)
virtual ~WLMSEstimator()
float sigma(const carto::rc_ptr< carto::Volume< AimsVector< float, D > > > &x, const carto::rc_ptr< carto::Volume< float > > &y, float a, const AimsVector< float, D > &b, carto::rc_ptr< carto::Volume< float > > &error)
WLMSEstimator(MEstimatorFunc &mfunc, float error, bool verbose=false)
void doit(const carto::rc_ptr< carto::Volume< AimsVector< float, D > > > &x, const carto::rc_ptr< carto::Volume< float > > &y, float &a, AimsVector< float, D > &b)
void step(const carto::rc_ptr< carto::Volume< AimsVector< float, D > > > &x, const carto::rc_ptr< carto::Volume< float > > &y, float &a, AimsVector< float, D > &b, const carto::rc_ptr< carto::Volume< float > > &error)
MEstimatorFunc & _mfunc
const T & at(long x, long y=0, long z=0, long t=0) const
carto::VolumeRef< float > AimsLinearResolutionLU(const carto::VolumeRef< float > &matrix, const carto::VolumeRef< float > &b)
AIMSDATA_API float norm(const Tensor &thing)