Changeset ffca8f2 in sasview
- Timestamp:
- May 23, 2008 3:23:05 PM (17 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- a8b6364
- Parents:
- 896abb3
- Location:
- pr_inversion
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pr_inversion/__init__.py
r896abb3 rffca8f2 24 24 # [5] S. Hansen and J. Skov Pedersen, J.Appl. Cryst (1991) 24, 541-548. 25 25 # 26 ## \subsection class Class Diagram: 27 # The following shows a partial class diagram with the main attributes and methods of the invertor. 28 # 29 # \image html architecture.png 26 30 # 27 31 # \section install_sec Installation … … 77 81 # matrix for those coefficients, respectively. 78 82 # 83 # To get P(r): 84 # \verbatim 85 # r = 10.0 86 # pr = invertor.pr(c_out, r) 87 # \endverbatim 88 # Alternatively, one can get P(r) with the error on P(r): 89 # \verbatim 90 # r = 10.0 91 # pr, dpr = invertor.pr_err(c_out, c_cov, r) 92 # \endverbatim 93 # 94 # To get the output I(q) from the set of coefficients found: 95 # \verbatim 96 # q = 0.001 97 # iq = invertor.iq(c_out, q) 98 # \endverbatim 99 # 79 100 # Examples are available as unit tests under sans.pr_inversion.test. 80 101 # -
pr_inversion/invertor.py
r896abb3 rffca8f2 35 35 Invertor class to perform P(r) inversion 36 36 37 TODO: explain the maths 38 37 The problem is solved by posing the problem as Ax = b, 38 where x is the set of coefficients we are looking for. 39 40 Npts is the number of points. 41 42 In the following i refers to the ith base function coefficient. 43 The matrix has its entries j in its first Npts rows set to 44 A[i][j] = (Fourier transformed base function for point j) 45 46 We them choose a number of r-points, n_r, to evaluate the second 47 derivative of P(r) at. This is used as our regularization term. 48 For a vector r of length n_r, the following n_r rows are set to 49 A[i+Npts][j] = (2nd derivative of P(r), d**2(P(r))/d(r)**2, evaluated at r[j]) 50 51 The vector b has its first Npts entries set to 52 b[j] = (I(q) observed for point j) 53 54 The following n_r entries are set to zero. 55 56 The result is found by using scipy.linalg.basic.lstsq to invert 57 the matrix and find the coefficients x. 39 58 40 59 Methods inherited from Cinvertor: … … 144 163 return invertor 145 164 146 def invert(self, nfunc= 5):165 def invert(self, nfunc=10, nr=20): 147 166 """ 148 167 Perform inversion to P(r) 149 """ 168 169 The problem is solved by posing the problem as Ax = b, 170 where x is the set of coefficients we are looking for. 171 172 Npts is the number of points. 173 174 In the following i refers to the ith base function coefficient. 175 The matrix has its entries j in its first Npts rows set to 176 A[i][j] = (Fourier transformed base function for point j) 177 178 We them choose a number of r-points, n_r, to evaluate the second 179 derivative of P(r) at. This is used as our regularization term. 180 For a vector r of length n_r, the following n_r rows are set to 181 A[i+Npts][j] = (2nd derivative of P(r), d**2(P(r))/d(r)**2, evaluated at r[j]) 182 183 The vector b has its first Npts entries set to 184 b[j] = (I(q) observed for point j) 185 186 The following n_r entries are set to zero. 187 188 The result is found by using scipy.linalg.basic.lstsq to invert 189 the matrix and find the coefficients x. 190 191 @param nfunc: number of base functions to use. 192 @param nr: number of r points to evaluate the 2nd derivative at for the reg. term. 193 @return: c_out, c_cov - the coefficients with covariance matrix 194 """ 195 #TODO: call the pyhton implementation for now. In the future, translate this to C. 196 return self.lstsq(nfunc, nr=nr) 197 198 def invert_optimize(self, nfunc=10, nr=20): 199 """ 200 Slower version of the P(r) inversion that uses scipy.optimize.leastsq. 201 202 This probably produce more reliable results, but is much slower. 203 The minimization function is set to sum_i[ (I_obs(q_i) - I_theo(q_i))/err**2 ] + alpha * reg_term, 204 where the reg_term is given by Svergun: it is the integral of the square of the first derivative 205 of P(r), d(P(r))/dr, integrated over the full range of r. 206 207 @param nfunc: number of base functions to use. 208 @param nr: number of r points to evaluate the 2nd derivative at for the reg. term. 209 @return: c_out, c_cov - the coefficients with covariance matrix 210 """ 211 150 212 from scipy import optimize 151 213 import time … … 175 237 def pr_fit(self, nfunc=5): 176 238 """ 177 Perform inversion to P(r) 239 This is a direct fit to a given P(r). It assumes that the y data 240 is set to some P(r) distribution that we are trying to reproduce 241 with a set of base functions. 242 243 This method is provided as a test. 178 244 """ 179 245 from scipy import optimize … … 209 275 @param r: r-value to evaluate P(r) at 210 276 @return: P(r) 211 212 277 """ 213 278 return self.get_pr_err(c, c_cov, r) … … 223 288 return True 224 289 225 def lstsq(self, nfunc=5 ):290 def lstsq(self, nfunc=5, nr=20): 226 291 #TODO: do this on the C side 227 292 # … … 230 295 # ... before passing it to C 231 296 """ 232 TODO: Document this 297 The problem is solved by posing the problem as Ax = b, 298 where x is the set of coefficients we are looking for. 299 300 Npts is the number of points. 301 302 In the following i refers to the ith base function coefficient. 303 The matrix has its entries j in its first Npts rows set to 304 A[i][j] = (Fourier transformed base function for point j) 305 306 We them choose a number of r-points, n_r, to evaluate the second 307 derivative of P(r) at. This is used as our regularization term. 308 For a vector r of length n_r, the following n_r rows are set to 309 A[i+Npts][j] = (2nd derivative of P(r), d**2(P(r))/d(r)**2, evaluated at r[j]) 310 311 The vector b has its first Npts entries set to 312 b[j] = (I(q) observed for point j) 313 314 The following n_r entries are set to zero. 315 316 The result is found by using scipy.linalg.basic.lstsq to invert 317 the matrix and find the coefficients x. 318 319 @param nfunc: number of base functions to use. 320 @param nr: number of r points to evaluate the 2nd derivative at for the reg. term. 233 321 """ 234 322 import math … … 239 327 # b -- An M x nrhs matrix or M vector. 240 328 npts = len(self.x) 241 nq = 20329 nq = nr 242 330 sqrt_alpha = math.sqrt(self.alpha) 243 331 … … 250 338 if self._accept_q(self.x[i]): 251 339 a[i][j] = self.basefunc_ft(self.d_max, j+1, self.x[i])/self.err[i] 340 341 #TODO: refactor this: i_q should really be i_r 252 342 for i_q in range(nq): 253 343 r = self.d_max/nq*i_q … … 298 388 return c, err 299 389 300 def svd(self, nfunc=5):301 import math, time302 # Ac - b = 0303 304 A = numpy.zeros([nfunc, nfunc])305 y = numpy.zeros(nfunc)306 307 t_0 = time.time()308 for i in range(nfunc):309 # A310 for j in range(nfunc):311 A[i][j] = 0.0312 for k in range(len(self.x)):313 err = self.err[k]314 A[i][j] += 1.0/err/err*self.basefunc_ft(self.d_max, j+1, self.x[k]) \315 *self.basefunc_ft(self.d_max, i+1, self.x[k]);316 #print A[i][j]317 #A[i][j] -= self.alpha*(math.cos(math.pi*(i+j)) - math.cos(math.pi*(i-j)));318 if i==j:319 A[i][j] += -1.0*self.alpha320 elif i-j==1 or i-j==-1:321 A[i][j] += 1.0*self.alpha322 #print " ",A[i][j]323 # y324 y[i] = 0.0325 for k in range(len(self.x)):326 y[i] = self.y[k]/self.err[k]/self.err[k]*self.basefunc_ft(self.d_max, i+1, self.x[k])327 328 print time.time()-t_0, 'secs'329 330 # use numpy.pinv(A)331 #inv_A = numpy.linalg.inv(A)332 #c = y*inv_A333 print y334 c = numpy.linalg.solve(A, y)335 336 337 print c338 339 err = numpy.zeros(len(c))340 return c, err341 342 390 def estimate_alpha(self, nfunc): 343 391 """ … … 392 440 393 441 peaks = pr.get_peaks(out) 394 print pr.alpha, peaks395 442 if peaks>1: 396 443 found = True -
pr_inversion/test/utest_invertor.py
r43c0a8e rffca8f2 176 176 self.invertor.err = err 177 177 # Perform inversion 178 out, cov = self.invertor.invert (10)178 out, cov = self.invertor.invert_optimize(10) 179 179 # This is a very specific case 180 180 # We should make sure it always passes … … 404 404 def test_qmin(self): 405 405 self.invertor.q_min = 1.0 406 print self.invertor.q_min407 406 self.assertEqual(self.invertor.q_min, 1.0) 408 407
Note: See TracChangeset
for help on using the changeset viewer.