Changeset 2d06beb in sasview for pr_inversion/invertor.py


Ignore:
Timestamp:
May 5, 2008 2:03:39 PM (16 years ago)
Author:
Mathieu Doucet <doucetm@…>
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:
b43a009
Parents:
150c04a
Message:

Use simple least-square fit

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pr_inversion/invertor.py

    reca05c8 r2d06beb  
    55     
    66    ## Chisqr of the last computation 
    7     chisqr = 0 
     7    chi2  = 0 
     8    ## Time elapsed for last computation 
     9    elapsed = 0 
    810     
    911    def __init__(self): 
     
    5860        return None 
    5961     
     62    def clone(self): 
     63        """ 
     64            Return a clone of this instance 
     65        """ 
     66        invertor = Invertor() 
     67        invertor.chi2    = self.chi2  
     68        invertor.elapsed = self.elapsed  
     69        invertor.alpha   = self.alpha 
     70        invertor.d_max   = self.d_max 
     71         
     72        invertor.x = self.x 
     73        invertor.y = self.y 
     74        invertor.err = self.err 
     75         
     76        return invertor 
     77     
    6078    def invert(self, nfunc=5): 
    6179        """ 
     
    6381        """ 
    6482        from scipy import optimize 
     83        import time 
    6584         
    6685        # First, check that the current data is valid 
     
    6988         
    7089        p = numpy.ones(nfunc) 
     90        t_0 = time.time() 
    7191        out, cov_x, info, mesg, success = optimize.leastsq(self.residuals, p, full_output=1, warning=True) 
    7292         
     
    7898         
    7999        self.chi2 = chisqr 
     100 
     101        # Store computation time 
     102        self.elapsed = time.time() - t_0 
    80103         
    81104        return out, cov_x 
     
    92115         
    93116        p = numpy.ones(nfunc) 
     117        t_0 = time.time() 
    94118        out, cov_x, info, mesg, success = optimize.leastsq(self.pr_residuals, p, full_output=1, warning=True) 
    95119         
     
    102126        self.chisqr = chisqr 
    103127         
     128        # Store computation time 
     129        self.elapsed = time.time() - t_0 
     130 
    104131        return out, cov_x 
    105132     
     
    117144 
    118145        return self.get_pr_err(c, c_err, r) 
     146        
     147    def lstsq(self, nfunc=5): 
     148        import math 
     149        from scipy.linalg.basic import lstsq 
     150         
     151        # a -- An M x N matrix. 
     152        # b -- An M x nrhs matrix or M vector. 
     153        npts = len(self.x) 
     154        nq   = 20 
     155        sqrt_alpha = math.sqrt(self.alpha) 
     156         
     157        a = numpy.zeros([npts+nq, nfunc]) 
     158        b = numpy.zeros(npts+nq) 
     159        err = numpy.zeros(nfunc) 
     160         
     161        for j in range(nfunc): 
     162            for i in range(npts): 
     163                a[i][j] = self.basefunc_ft(self.d_max, j+1, self.x[i])/self.err[i] 
     164            for i_q in range(nq): 
     165                r = self.d_max/nq*i_q 
     166                #a[i_q+npts][j] = sqrt_alpha * 1.0/nq*self.d_max*2.0*math.fabs(math.sin(math.pi*(j+1)*r/self.d_max) + math.pi*(j+1)*r/self.d_max * math.cos(math.pi*(j+1)*r/self.d_max))      
     167                a[i_q+npts][j] = sqrt_alpha * 1.0/nq*self.d_max*2.0*(2.0*math.pi*(j+1)/self.d_max*math.cos(math.pi*(j+1)*r/self.d_max) + math.pi**2*(j+1)**2*r/self.d_max**2 * math.sin(math.pi*(j+1)*r/self.d_max))      
     168         
     169        for i in range(npts): 
     170            b[i] = self.y[i]/self.err[i] 
     171             
     172        c, chi2, rank, n = lstsq(a, b) 
     173        self.chi2 = chi2 
     174                 
     175        at = numpy.transpose(a) 
     176        inv_cov = numpy.zeros([nfunc,nfunc]) 
     177        for i in range(nfunc): 
     178            for j in range(nfunc): 
     179                inv_cov[i][j] = 0.0 
     180                for k in range(npts): 
     181                    inv_cov[i][j] = at[i][k]*a[k][j] 
     182                     
     183        # Compute the reg term size for the output 
     184        sum_sig = 0.0 
     185        sum_reg = 0.0 
     186        for j in range(nfunc): 
     187            for i in range(npts): 
     188                sum_sig += (a[i][j])**2 
     189            for i in range(nq): 
     190                sum_reg += (a[i_q+npts][j])**2 
     191                     
     192        new_alpha = sum_sig/(sum_reg/self.alpha) 
     193        print "Suggested alpha =", 0.1*new_alpha 
     194         
     195        try: 
     196            err = math.fabs(chi2/(npts-nfunc))* inv_cov 
     197        except: 
     198            print "Error estimating uncertainties" 
     199             
     200         
     201        return c, err 
     202         
     203    def svd(self, nfunc=5): 
     204        import math, time 
     205        # Ac - b = 0 
     206         
     207        A = numpy.zeros([nfunc, nfunc]) 
     208        y = numpy.zeros(nfunc) 
     209         
     210        t_0 = time.time() 
     211        for i in range(nfunc): 
     212            # A 
     213            for j in range(nfunc): 
     214                A[i][j] = 0.0 
     215                for k in range(len(self.x)): 
     216                    err = self.err[k] 
     217                    A[i][j] += 1.0/err/err*self.basefunc_ft(self.d_max, j+1, self.x[k]) \ 
     218                            *self.basefunc_ft(self.d_max, i+1, self.x[k]); 
     219                #print A[i][j] 
     220                #A[i][j] -= self.alpha*(math.cos(math.pi*(i+j)) - math.cos(math.pi*(i-j))); 
     221                if i==j: 
     222                    A[i][j] += -1.0*self.alpha 
     223                elif i-j==1 or i-j==-1: 
     224                    A[i][j] += 1.0*self.alpha 
     225                #print "   ",A[i][j] 
     226            # y 
     227            y[i] = 0.0 
     228            for k in range(len(self.x)): 
     229                y[i] = self.y[k]/self.err[k]/self.err[k]*self.basefunc_ft(self.d_max, i+1, self.x[k]) 
     230             
     231        print time.time()-t_0, 'secs' 
     232         
     233        # use numpy.pinv(A) 
     234        #inv_A = numpy.linalg.inv(A) 
     235        #c = y*inv_A 
     236        print y 
     237        c = numpy.linalg.solve(A, y) 
     238         
     239         
     240        print c 
     241         
     242        err = numpy.zeros(len(c)) 
     243        return c, err 
     244         
     245         
     246         
    119247         
    120248     
Note: See TracChangeset for help on using the changeset viewer.