Ejemplo n.º 1
0
    def get_covariances(self,hyperparams):
        """
        INPUT:
        hyperparams:  dictionary
        OUTPUT: dictionary with the fields
        K:     kernel
        Kinv:  inverse of the kernel
        L:     chol(K)
        alpha: solve(K,y)
        W:     D*Kinv * alpha*alpha^T
        """
        if self._is_cached(hyperparams):
            return self._covar_cache

        K = self.covar.K(hyperparams['covar'])
        
        if self.likelihood is not None:
            Knoise = self.likelihood.K(hyperparams['lik'],self.n)
            K += Knoise
        K[~SP.isfinite(K)] = SP.finfo(float).eps   
        K[SP.isnan(K)] = SP.finfo(float).eps  
        L = LA.cholesky(K).T# lower triangular
        alpha = LA.cho_solve((L,True),self.Y)
        Kinv = LA.cho_solve((L,True),SP.eye(L.shape[0]))
        W = self.t*Kinv - SP.dot(alpha,alpha.T)
        self._covar_cache = {}
        self._covar_cache['K'] = K
        self._covar_cache['Kinv'] = Kinv
        self._covar_cache['L'] = L
        self._covar_cache['alpha'] = alpha
        self._covar_cache['W'] = W
        self._covar_cache['hyperparams'] = copy.deepcopy(hyperparams) 
        return self._covar_cache
Ejemplo n.º 2
0
    def _update_evd(self, hyperparams, covar_id):
        keys = []
        if 'covar_%s' % covar_id in hyperparams:
            keys.append('covar_%s' % covar_id)
        if 'X_%s' % covar_id in hyperparams:
            keys.append('X_%s' % covar_id)

        if not (self._is_cached(hyperparams, keys=keys)):
            K = []
            S = []
            U = []
            i = 0
            for covar in getattr(self, 'covar_%s' % covar_id):
                temp_kernel = covar.K(hyperparams['covar_%s' % covar_id][i])
                temp_kernel = temp_kernel + SP.eye(
                    temp_kernel.shape[0], temp_kernel.shape[1]
                ) * 0.001  # Rosolving possible numerical instability
                temp_kernel[SP.isnan(temp_kernel)] = SP.finfo(SP.float32).eps
                temp_kernel[~SP.isfinite(temp_kernel)] = 1E6
                K.append(temp_kernel)
                S_temp, U_temp = LA.eigh(temp_kernel)
                S_temp[S_temp <= 0] = SP.finfo(
                    SP.float32).eps  # Rosolving possible numerical instability
                S.append(S_temp)
                U.append(U_temp)
                i += 1

            self._covar_cache['K_%s' % covar_id] = K
            self._covar_cache['U_%s' % covar_id] = U
            self._covar_cache['S_%s' % covar_id] = S
Ejemplo n.º 3
0
def objective(pars, Z, ycovar):
    """The objective function"""
    bcost = pars[0]
    t = pars[1]
    Pb = pars[2]
    Xb = pars[3]
    Yb = pars[4]
    Zb = sc.array([Xb, Yb])
    Vb1 = sc.exp(pars[5])
    Vb2 = sc.exp(pars[6])
    corr = pars[7]
    V = sc.array([[Vb1, sc.sqrt(Vb1 * Vb2) * corr],
                  [sc.sqrt(Vb1 * Vb2) * corr, Vb2]])
    v = sc.array([-sc.sin(t), sc.cos(t)])
    if Pb < 0. or Pb > 1.:
        return -sc.finfo(sc.dtype(sc.float64)).max
    if corr < -1. or corr > 1.:
        return -sc.finfo(sc.dtype(sc.float64)).max
    delta = sc.dot(v, Z.T) - bcost
    sigma2 = sc.dot(v, sc.dot(ycovar, v))

    ndata = Z.shape[0]
    detVycovar = sc.zeros(ndata)
    deltaOUT = sc.zeros(ndata)
    for ii in range(ndata):
        detVycovar[ii] = m.sqrt(linalg.det(V + ycovar[:, ii, :]))
        deltaOUT[ii] = sc.dot(
            Z[ii, :] - Zb,
            sc.dot(linalg.inv(V + ycovar[:, ii, :]), Z[ii, :] - Zb))
    return sc.sum(
        sc.log((1. - Pb) / sc.sqrt(2. * m.pi * sigma2 / sc.cos(t)**2.) *
               sc.exp(-0.5 * delta**2. / sigma2) +
               Pb / 2. / m.pi / detVycovar * sc.exp(-0.5 * deltaOUT)))
Ejemplo n.º 4
0
def objective(pars,Z,ycovar):
    """The objective function"""
    bcost= pars[0]
    t= pars[1]
    Pb= pars[2]
    Xb= pars[3]
    Yb= pars[4]
    Zb= sc.array([Xb,Yb])
    Vb1= sc.exp(pars[5])
    Vb2= sc.exp(pars[6])
    corr= pars[7]
    V= sc.array([[Vb1,sc.sqrt(Vb1*Vb2)*corr],[sc.sqrt(Vb1*Vb2)*corr,Vb2]])
    v= sc.array([-sc.sin(t),sc.cos(t)])
    if Pb < 0. or Pb > 1.:
        return -sc.finfo(sc.dtype(sc.float64)).max
    if corr < -1. or corr > 1.:
        return -sc.finfo(sc.dtype(sc.float64)).max
    delta= sc.dot(v,Z.T)-bcost
    sigma2= sc.dot(v,sc.dot(ycovar,v))

    ndata= Z.shape[0]
    detVycovar= sc.zeros(ndata)
    deltaOUT= sc.zeros(ndata)
    for ii in range(ndata):
        detVycovar[ii]= m.sqrt(linalg.det(V+ycovar[:,ii,:]))
        deltaOUT[ii]= sc.dot(Z[ii,:]-Zb,sc.dot(linalg.inv(V+ycovar[:,ii,:]),Z[ii,:]-Zb))
    return sc.sum(sc.log((1.-Pb)/sc.sqrt(2.*m.pi*sigma2)*
                         sc.exp(-0.5*delta**2./sigma2)
                         +Pb/2./m.pi/detVycovar
                         *sc.exp(-0.5*deltaOUT)))
Ejemplo n.º 5
0
def probability_of_detection(signal_to_noise, probability_of_false_alarm,
                             number_of_pulses, target_type):
    """
    Calculate the probability of detection for Swerling 0 targets.
    :param signal_to_noise: The signal to noise ratio.
    :param probability_of_false_alarm: The probability of false alarm.
    :param number_of_pulses: The number of pulses to be non-coherently integrated.
    :param target_type: The Swerling target type (0, 1, 2, 3, or 4).
    :return: The probability of detection.
    """
    # Calculate the threshold to noise
    threshold_to_noise = threshold_to_noise_ratio(probability_of_false_alarm,
                                                  number_of_pulses)

    if target_type == 'Swerling 0':
        s = 0

        for n in range(2, number_of_pulses + 1):
            s += (threshold_to_noise / (number_of_pulses * signal_to_noise)) ** (0.5 * (n - 1.0)) \
                 * iv(n-1, 2.0 * sqrt(number_of_pulses * signal_to_noise * threshold_to_noise))

        if s == float('inf'):
            s = sys.float_info.max
        return Q(sqrt(2.0 * number_of_pulses * signal_to_noise), sqrt(2.0 * threshold_to_noise), 1e-6) \
               + exp(-threshold_to_noise - number_of_pulses * signal_to_noise) * s

    elif target_type == 'Swerling 1':
        return 1.0 - gammainc(number_of_pulses - 1 + finfo(float).eps, threshold_to_noise) \
           + (1.0 + 1.0 / (number_of_pulses * signal_to_noise)) ** (number_of_pulses - 1) \
           * gammainc(number_of_pulses - 1 + finfo(float).eps, threshold_to_noise / (1.0 + 1.0 / (number_of_pulses * signal_to_noise))) \
           * exp(-threshold_to_noise / (1.0 + number_of_pulses * signal_to_noise))

    elif target_type == 'Swerling 2':
        return 1.0 - gammainc(number_of_pulses, threshold_to_noise /
                              (1.0 + signal_to_noise))

    elif target_type == 'Swerling 3':
        return (1.0 + 2.0 / (number_of_pulses * signal_to_noise)) ** (number_of_pulses - 2) * \
           (1.0 + threshold_to_noise / (1.0 + 0.5 * number_of_pulses * signal_to_noise)
            - 2.0 * (number_of_pulses - 2.0) / (number_of_pulses * signal_to_noise)) \
           * exp(-threshold_to_noise / (1.0 + 0.5 * number_of_pulses * signal_to_noise))

    elif target_type == 'Swerling 4':
        s = 0

        for k in range(number_of_pulses + 1):
            s += binom(number_of_pulses, k) * (0.5 * signal_to_noise) ** -k \
                * gammainc(2 * number_of_pulses - k, 2 * threshold_to_noise / (signal_to_noise + 2.0))

        if s == float('inf'):
            s = sys.float_info.max

        return 1.0 - (signal_to_noise /
                      (signal_to_noise + 2.0))**number_of_pulses * s
Ejemplo n.º 6
0
def edge_property_vs_depth(G,
                           property,
                           intervals,
                           eIndices=None,
                           function=None):
    """Generic function to compile and optionally process edge information of a
    vascular graph versus the cortical depth.
    INPUT: G: Vascular graph in iGraph format.
           property: Which edge property to operate on.
           intervals: Intervals of cortical depth in which the sample is split.
                      (Expected 
           eIndices: (Optional.) Indices of edges to consider. If not provided,
                     all edges are taken into account.
           function: (Optional.) Function which to perform on the compiled data
                     of each interval.
    OUTPUT: The compiled (and possibly processed) information as a list (one 
            entry per interval).
    """

    intervals[-1] = (intervals[-1][0], intervals[-1][1] + sp.finfo(float).eps)
    database = []
    for interval in intervals:
        if eIndices:
            data = G.es(eIndices, depth_ge=interval[0],
                        depth_lt=interval[1])[property]
        else:
            data = G.es(depth_ge=interval[0], depth_lt=interval[1])[property]
        if function:
            database.append(function(data))
        else:
            database.append(data)
    return database
Ejemplo n.º 7
0
def implant_srxtm_cube(Ga, Gd, origin=None, crWidth=150):
    """Implants a cubic srXTM sample in an artificial vascular network
    consisting of pial vessels, arterioles, venoles and capillaries. At the 
    site of insertion, artificial vessels are removed to make space for the 
    srXTM sample. At the border between artificial and data networks,
    connections are made between the respective loose ends.
    INPUT: Ga: VascularGraph of the artificial vasculature.
           Gd: VascularGraph of the srXTM data. The graph is expected to have
               the attributes 'av' and 'vv' that denote the indices of 
               endpoints of the large penetrating arteries and veins 
               respectively.
           origin: The two-dimensional origin in the xy plane, where the srXTM
                   sample should be inserted. This will be the network's 
                   center of mass, if not provided.
           crWidth: Width of connection region. After computing the center and
                    radius of the SRXTM sample, loose ends of the SRXTM at
                    radius - 2*crWidth are connected to loose ends of the
                    artificial network at radius + 2*crWidth.
    OUTPUT: Ga: Modified input Ga, with Gd inserted at origin.       
    """
    
    # Create Physiology object with appropriate default units:
    P = vgm.Physiology(Ga['defaultUnits'])
    eps = finfo(float).eps * 1e4


    return Ga
Ejemplo n.º 8
0
def rotation_matrix_from_cross_prod(a,b):
    """
    Returns the rotation matrix which rotates the
    vector :samp:`a` onto the the vector :samp:`b`.
    
    :type a: 3 sequence of :obj:`float`
    :param a: Vector to be rotated on to :samp:`{b}`.
    :type b: 3 sequence of :obj:`float`
    :param b: Vector.
    :rtype: :obj:`numpy.array`
    :return: 3D rotation matrix.
    """

    crs = np.cross(a,b)
    dotProd = np.dot(a,b)
    crsNorm = sp.linalg.norm(crs)
    eps = sp.sqrt(sp.finfo(a.dtype).eps)
    r = sp.eye(a.size, a.size, dtype=a.dtype)
    if (crsNorm > eps):
        theta = sp.arctan2(crsNorm, dotProd)
        r = axis_angle_to_rotation_matrix(crs, theta)
    elif (dotProd < 0):
        r = -r
    
    return r
Ejemplo n.º 9
0
def edge_property_vs_depth(G,property,intervals,eIndices=None,function=None):
    """Generic function to compile and optionally process edge information of a
    vascular graph versus the cortical depth.
    INPUT: G: Vascular graph in iGraph format.
           property: Which edge property to operate on.
           intervals: Intervals of cortical depth in which the sample is split.
                      (Expected 
           eIndices: (Optional.) Indices of edges to consider. If not provided,
                     all edges are taken into account.
           function: (Optional.) Function which to perform on the compiled data
                     of each interval.
    OUTPUT: The compiled (and possibly processed) information as a list (one 
            entry per interval).
    """
    
    intervals[-1] = (intervals[-1][0], intervals[-1][1] + sp.finfo(float).eps)
    database = []
    for interval in intervals:
        if eIndices:
            data = G.es(eIndices,depth_ge=interval[0], 
                        depth_lt=interval[1])[property]
        else:                
            data = G.es(depth_ge=interval[0], 
                        depth_lt=interval[1])[property]
        if function:
            database.append(function(data))
        else:
            database.append(data)
    return database   
Ejemplo n.º 10
0
def pre_compute_E_Beta(x, y, sig, kernel="RBF"):
    """
    Function that pre computes the kernel eigenvalues/eigenfunctions during the cross-validation
    Input:
    x,y: the sample matrix and the label
    sig: the value of the kernel parameters
    Output:
    E_: a list of eigenvalues
    Beta_: a list of corresponding eigenvectors
    """
    C = int(y.max())
    eps = sp.finfo(sp.float64).eps
    E_ = []
    Beta_ = []

    for i in range(C):
        t = sp.where(y == (i + 1))[0]
        ni = t.size
        Ki = KERNEL()
        Ki.compute_kernel(x[t, :], kernel=kernel, sig=sig)
        Ki.center_kernel()
        Ki.scale_kernel(ni)

        E, Beta = linalg.eigh(Ki.K)
        idx = E.argsort()[::-1]
        E = E[idx]
        E[E < eps] = eps
        Beta = Beta[:, idx]
        E_.append(E)
        Beta_.append(Beta)

    del E, Beta, Ki
    return E_, Beta_
Ejemplo n.º 11
0
def directivity(frequency, length, current):
    """
    The directivity of a finite length dipole antenna.
    :param frequency: The operating frequency (Hz).
    :param length: The length of the dipole (m).
    :param current: The peak current on the dipole (A).
    :return: The directivity of a small dipole antenna.
    """
    # Calculate the wave impedance
    eta = sqrt(mu_0 / epsilon_0)

    # Calculate the wave number times the length
    kl = 2.0 * pi * frequency / c * length

    # Calculate the radiation intensity factor
    factor = eta * abs(current)**2 / (8.0 * pi**2)

    # Calculate the power radiated
    power_radiated = radiated_power(frequency, length, current)

    # Calculate the maximum of the radiation intensity
    theta = linspace(finfo(float).eps, 2.0 * pi, 10000)
    u_max = max(((cos(0.5 * kl * cos(theta)) - cos(0.5 * kl)) / sin(theta))**2)

    return 4.0 * pi * factor * u_max / power_radiated
Ejemplo n.º 12
0
def rotation_matrix_from_cross_prod(a, b):
    """
    Returns the rotation matrix which rotates the
    vector :samp:`a` onto the the vector :samp:`b`.
    
    :type a: 3 sequence of :obj:`float`
    :param a: Vector to be rotated on to :samp:`{b}`.
    :type b: 3 sequence of :obj:`float`
    :param b: Vector.
    :rtype: :obj:`numpy.array`
    :return: 3D rotation matrix.
    """

    crs = np.cross(a, b)
    dotProd = np.dot(a, b)
    crsNorm = sp.linalg.norm(crs)
    eps = sp.sqrt(sp.finfo(a.dtype).eps)
    r = sp.eye(a.size, a.size, dtype=a.dtype)
    if (crsNorm > eps):
        theta = sp.arctan2(crsNorm, dotProd)
        r = axis_angle_to_rotation_matrix(crs, theta)
    elif (dotProd < 0):
        r = -r

    return r
Ejemplo n.º 13
0
def pre_compute_E_Beta(x, y, sig, kernel='RBF'):
    '''
    Function that pre computes the kernel eigenvalues/eigenfunctions during the cross-validation
    Input:
    x,y: the sample matrix and the label
    sig: the value of the kernel parameters
    Output:
    E_: a list of eigenvalues
    Beta_: a list of corresponding eigenvectors
    '''
    C = int(y.max())
    eps = sp.finfo(sp.float64).eps
    E_ = []
    Beta_ = []

    for i in range(C):
        t = sp.where(y == (i + 1))[0]
        ni = t.size
        Ki = KERNEL()
        Ki.compute_kernel(x[t, :], kernel=kernel, sig=sig)
        Ki.center_kernel()
        Ki.scale_kernel(ni)

        E, Beta = linalg.eigh(Ki.K)
        idx = E.argsort()[::-1]
        E = E[idx]
        E[E < eps] = eps
        Beta = Beta[:, idx]
        E_.append(E)
        Beta_.append(Beta)

    del E, Beta, Ki
    return E_, Beta_
Ejemplo n.º 14
0
def zexpmv(A, v, t, norm_est=1., m=5, tol=0., trace=False, A_is_Herm=False):
    assert A.dtype.type is sp.complex128
    assert v.dtype.type is sp.complex128

    #Override expokit deault precision to match scipy sparse eigs more closely.
    if tol == 0:
        tol = sp.finfo(
            sp.complex128
        ).eps * 2  #cannot take eps, as expokit changes this to sqrt(eps)!

    xn = A.shape[0]
    vf = sp.ones((xn, ), dtype=A.dtype)

    m = min(xn - 1, m)

    nwsp = max(10, xn * (m + 2) + 5 * (m + 2)**2 + ideg + 1)
    wsp = sp.zeros((nwsp, ), dtype=A.dtype)

    niwsp = max(7, m + 2)
    iwsp = sp.zeros((niwsp, ), dtype=sp.int32)

    iflag = sp.zeros((1, ), dtype=sp.int32)
    itrace = sp.array([int(trace)])

    if A_is_Herm:
        expokit.zhexpv(m, [t],
                       v,
                       vf, [tol], [norm_est],
                       wsp,
                       iwsp,
                       A.matvec,
                       itrace,
                       iflag,
                       n=[xn],
                       lwsp=[len(wsp)],
                       liwsp=[len(iwsp)])
    else:
        expokit.zgexpv(m, [t],
                       v,
                       vf, [tol], [norm_est],
                       wsp,
                       iwsp,
                       A.matvec,
                       itrace,
                       iflag,
                       n=[xn],
                       lwsp=[len(wsp)],
                       liwsp=[len(iwsp)])

    if iflag[0] == 1:
        print "Max steps reached!"
    elif iflag[0] == 2:
        print "Tolerance too high!"
    elif iflag[0] < 0:
        print "Bad arguments!"
    elif iflag[0] > 0:
        print "Unknown error!"

    return vf
Ejemplo n.º 15
0
    def train(self, x, y, mu=None, sig=None):
        # Initialization
        n = y.shape[0]
        C = int(y.max())
        eps = sp.finfo(sp.float64).eps

        if (mu is None) and (self.mu is None):
            mu = 10**(-7)
        elif self.mu is None:
            self.mu = mu

        if (sig is None) and (self.sig is None):
            self.sig = 0.5
        elif self.sig is None:
            self.sig = sig

        # Compute K and
        K = KERNEL()
        K.compute_kernel(x, sig=self.sig)
        G = KERNEL()
        G.K = self.mu * sp.eye(n)

        for i in range(C):
            t = sp.where(y == (i + 1))[0]
            self.ni.append(sp.size(t))
            self.prop.append(float(self.ni[i]) / n)

            # Compute K_k
            Ki = KERNEL()
            Ki.compute_kernel(x, z=x[t, :], sig=self.sig)
            T = (sp.eye(self.ni[i]) - sp.ones((self.ni[i], self.ni[i])))
            Ki.K = sp.dot(Ki.K, T)
            del T
            G.K += sp.dot(Ki.K, Ki.K.T) / self.ni[i]
        G.scale_kernel(C)

        # Solve the generalized eigenvalue problem
        a, A = linalg.eigh(G.K, b=K.K)
        idx = a.argsort()[::-1]
        a = a[idx]
        A = A[:, idx]

        # Remove negative eigenvalue
        t = sp.where(a > eps)[0]
        a = a[t]
        A = A[:, t]

        # Normalize the eigenvalue
        for i in range(a.size):
            A[:, i] /= sp.sqrt(sp.dot(sp.dot(A[:, i].T, K.K), A[:, i]))

        # Update model
        self.a = a.copy()
        self.A = A.copy()
        self.S = sp.dot(sp.dot(self.A, sp.diag(self.a**(-1))), self.A.T)

        # Free memory
        del G, K, a, A
Ejemplo n.º 16
0
    def train(self, x, y, mu=None, sig=None):
        # Initialization
        n = y.shape[0]
        C = int(y.max())
        eps = sp.finfo(sp.float64).eps

        if (mu is None) and (self.mu is None):
            mu = 10 ** (-7)
        elif self.mu is None:
            self.mu = mu

        if (sig is None) and (self.sig is None):
            self.sig = 0.5
        elif self.sig is None:
            self.sig = sig

        # Compute K and
        K = KERNEL()
        K.compute_kernel(x, sig=self.sig)
        G = KERNEL()
        G.K = self.mu * sp.eye(n)

        for i in range(C):
            t = sp.where(y == (i + 1))[0]
            self.ni.append(sp.size(t))
            self.prop.append(float(self.ni[i]) / n)

            # Compute K_k
            Ki = KERNEL()
            Ki.compute_kernel(x, z=x[t, :], sig=self.sig)
            T = sp.eye(self.ni[i]) - sp.ones((self.ni[i], self.ni[i]))
            Ki.K = sp.dot(Ki.K, T)
            del T
            G.K += sp.dot(Ki.K, Ki.K.T) / self.ni[i]
        G.scale_kernel(C)

        # Solve the generalized eigenvalue problem
        a, A = linalg.eigh(G.K, b=K.K)
        idx = a.argsort()[::-1]
        a = a[idx]
        A = A[:, idx]

        # Remove negative eigenvalue
        t = sp.where(a > eps)[0]
        a = a[t]
        A = A[:, t]

        # Normalize the eigenvalue
        for i in range(a.size):
            A[:, i] /= sp.sqrt(sp.dot(sp.dot(A[:, i].T, K.K), A[:, i]))

        # Update model
        self.a = a.copy()
        self.A = A.copy()
        self.S = sp.dot(sp.dot(self.A, sp.diag(self.a ** (-1))), self.A.T)

        # Free memory
        del G, K, a, A
Ejemplo n.º 17
0
    def _update_canvas(self):
        """
        Update the figure when the user changes an input value
        :return:
        """
        # Get the parameters from the form
        frequency = float(self.frequency.text())
        number_of_elements = int(self.number_of_elements.text())
        scan_angle = float(self.scan_angle.text())
        element_spacing = float(self.element_spacing.text())
        side_lobe_level = float(self.side_lobe_level.text())

        # Get the selected antenna from the form
        antenna_type = self.antenna_type.currentText()

        # Set the angular span
        theta = linspace(0.0, pi, 1000)

        # Set up the args
        kwargs = {
            'number_of_elements': number_of_elements,
            'scan_angle': radians(scan_angle),
            'element_spacing': element_spacing,
            'frequency': frequency,
            'theta': theta,
            'window_type': antenna_type,
            'side_lobe_level': side_lobe_level
        }

        # Get the array factor
        af = linear_array.array_factor(**kwargs)

        # Clear the axes for the updated plot
        self.axes1.clear()

        # Create the line plot
        self.axes1.plot(degrees(theta),
                        20.0 * log10(abs(af) + finfo(float).eps), '')

        # Set the y axis limit
        self.axes1.set_ylim(-80, 5)

        # Set the x and y axis labels
        self.axes1.set_xlabel("Theta (degrees)", size=12)
        self.axes1.set_ylabel("Array Factor (dB)", size=12)

        # Turn on the grid
        self.axes1.grid(linestyle=':', linewidth=0.5)

        # Set the plot title and labels
        self.axes1.set_title('Linear Array Antenna Pattern', size=14)

        # Set the tick label size
        self.axes1.tick_params(labelsize=12)

        # Update the canvas
        self.my_canvas.draw()
Ejemplo n.º 18
0
    def predict(self, xt, tau=None, confidenceMap=None):
        '''
        Function that predict the label for sample xt using the learned model
        Inputs:
            xt: the samples to be classified
        Outputs:
            y: the class
            K: the decision value for each class
        '''

        MAX = sp.finfo(sp.float64).max
        E_MAX = sp.log(
            MAX)  # Maximum value that is possible to compute with sp.exp

        ## Get information from the data
        nt = xt.shape[0]  # Number of testing samples
        C = self.ni.shape[0]  # Number of classes

        ## Initialization
        K = sp.empty((nt, C))

        if tau is None:
            TAU = self.tau
        else:
            TAU = tau

        for c in range(C):
            invCov, logdet = self.compute_inverse_logdet(c, TAU)
            cst = logdet - 2 * sp.log(self.prop[c])  # Pre compute the constant

            xtc = xt - self.mean[c, :]
            temp = sp.dot(invCov, xtc.T).T
            K[:, c] = sp.sum(xtc * temp, axis=1) + cst
            del temp, xtc

        yp = sp.argmin(K, 1)

        if confidenceMap is None:

            ## Assign the label save in classnum to the minimum value of K
            yp = self.classnum[yp]

            return yp

        else:

            K *= -0.5
            K[K > E_MAX], K[K < -E_MAX] = E_MAX, -E_MAX
            sp.exp(K, out=K)
            K /= K.sum(axis=1).reshape(nt, 1)
            K = K[sp.arange(len(K)), yp]
            #K = sp.diag(K[:,yp])

            yp = self.classnum[yp]

            return yp, K
Ejemplo n.º 19
0
def objective(pars,X,Y,yerr):
    """The objective function"""
    b= pars[0]
    s= pars[1]
    Pb= pars[2]
    Yb= pars[3]
    Vb= m.exp(pars[4])
    if Pb < 0. or Pb > 1.:
        return -sc.finfo(sc.dtype(sc.float64)).max
    return sc.sum(sc.log((1.-Pb)/sc.sqrt(2.*m.pi)/yerr*sc.exp(-0.5*(Y-s*X-b)**2./yerr**2.)+Pb/sc.sqrt(2.*m.pi*(Vb+yerr**2.))*sc.exp(-0.5*(Y-Yb)**2./(Vb+yerr**2.))))#+pars[4]
Ejemplo n.º 20
0
 def __init__(self, module, dataset, totalIterations = 100,
              xPrecision = finfo(float).eps, fPrecision = finfo(float).eps,
              init_scg=True, **kwargs):
     """Create a SCGTrainer to train the specified `module` on the
     specified `dataset`.
     """
     Trainer.__init__(self, module)
     self.setData(dataset)
     self.input_sequences = self.ds.getField('input')
     self.epoch = 0
     self.totalepochs = 0
     self.module = module
     #self.tmp_module = module.copy()
     if init_scg:
         self.scg = SCG(self.module.params, self.f, self.df, self,
                        totalIterations, xPrecision, fPrecision,
                        evalFunc = lambda x: str(x / self.ds.getLength()))
     else:
         print "Warning: SCG trainer not initialized!"
Ejemplo n.º 21
0
    def __init__(self, N, uni_ground):
        self.odr = 'C'
        self.typ = sp.complex128

        self.zero_tol = sp.finfo(self.typ).resolution
        """Tolerance for detecting zeros. This is used when (pseudo-) inverting 
           l and r."""

        self._sanity_checks = False

        self.N = N
        """The number of sites. Do not change after initializing."""
        
        self.N_centre = N / 2
        """The 'centre' site. This affects the gauge-fixing and canonical
           form. It is the site between the left-gauge parts and the 
           right-gauge parts."""
           
        self.D = sp.repeat(uni_ground.D, self.N + 2)
        """Vector containing the bond-dimensions. A[n] is a 
           q[n] x D[n - 1] x D[n] tensor."""
           
        self.q = sp.repeat(uni_ground.q, self.N + 2)
        """Vector containing the site Hilbert space dimensions. A[n] is a 
           q[n] x D[n - 1] x D[n] tensor."""
           
        self.S_hc = sp.repeat(sp.NaN, self.N + 1)
        """Vector containing the von Neumann entropy S_hc[n] corresponding to 
           splitting the state between sites n and n + 1. Available only
           after performing update(restore_CF=True) or restore_CF()."""   

        self.uni_l = copy.deepcopy(uni_ground)
        self.uni_l.symm_gauge = False
        self.uni_l.sanity_checks = self.sanity_checks
        self.uni_l.update()

        self.uni_r = copy.deepcopy(uni_ground)
        self.uni_r.sanity_checks = self.sanity_checks
        self.uni_r.symm_gauge = False
        self.uni_r.update()

        self.grown_left = 0
        self.grown_right = 0
        self.shrunk_left = 0
        self.shrunk_right = 0

        self._init_arrays()

        for n in xrange(self.N + 2):
            self.A[n][:] = self.uni_l.A

        self.r[self.N] = self.uni_r.r
        self.r[self.N + 1] = self.r[self.N]
        self.l[0] = self.uni_l.l
Ejemplo n.º 22
0
def fspecial_gaussian(hsize, sigma):
    hsize = [hsize, hsize]
    siz = [(hsize[0]-1.0)/2.0, (hsize[1]-1.0)/2.0]
    std = sigma
    [x, y] = np.meshgrid(np.arange(-siz[1], siz[1]+1), np.arange(-siz[0], siz[0]+1))
    arg = -(x*x + y*y)/(2*std*std)
    h = np.exp(arg)
    h[h < scipy.finfo(float).eps * h.max()] = 0
    sumh = h.sum()
    if sumh != 0:
        h = h/sumh
    return h
Ejemplo n.º 23
0
def test_numpy_deprecation_functionality():
    # Check that the deprecation wrappers don't break basic NumPy
    # functionality
    with deprecated_call():
        x = scipy.array([1, 2, 3], dtype=scipy.float64)
        assert x.dtype == scipy.float64
        assert x.dtype == np.float64

        x = scipy.finfo(scipy.float32)
        assert x.eps == np.finfo(np.float32).eps

        assert scipy.float64 == np.float64
        assert issubclass(np.float64, scipy.float64)
Ejemplo n.º 24
0
    def __init__(self, N, uni_ground):
        self.odr = 'C'
        self.typ = sp.complex128

        self.zero_tol = sp.finfo(self.typ).resolution
        """Tolerance for detecting zeros. This is used when (pseudo-) inverting 
           l and r."""

        self._sanity_checks = False

        self.N = N
        """The number of sites. Do not change after initializing."""
        
        self.N_centre = N / 2
        """The 'centre' site. This affects the gauge-fixing and canonical
           form. It is the site between the left-gauge parts and the 
           right-gauge parts."""
           
        self.D = sp.repeat(uni_ground.D, self.N + 2)
        """Vector containing the bond-dimensions. A[n] is a 
           q[n] x D[n - 1] x D[n] tensor."""
           
        self.q = sp.repeat(uni_ground.q, self.N + 2)
        """Vector containing the site Hilbert space dimensions. A[n] is a 
           q[n] x D[n - 1] x D[n] tensor."""
          
        self.uni_l = copy.deepcopy(uni_ground)
        self.uni_l.symm_gauge = True
        self.uni_l.sanity_checks = self.sanity_checks
        self.uni_l.update()
        
        if not N % self.uni_l.L == 0:
            print "Warning: Length of nonuniform window is not a multiple of the uniform block size."

        self.uni_r = copy.deepcopy(self.uni_l)

        self.grown_left = 0
        self.grown_right = 0
        self.shrunk_left = 0
        self.shrunk_right = 0

        self._init_arrays()

        for n in xrange(1, self.N + 1):
            self.A[n][:] = self.uni_l.A[(n - 1) % self.uni_l.L]
        
        for n in xrange(self.N + 2):
            self.r[n][:] = sp.asarray(self.uni_l.r[(n - 1) % self.uni_l.L])
            self.l[n][:] = sp.asarray(self.uni_l.l[(n - 1) % self.uni_l.L])
Ejemplo n.º 25
0
    def __init__(self, N, uni_ground):
        self.odr = 'C'
        self.typ = sp.complex128

        self.zero_tol = sp.finfo(self.typ).resolution
        """Tolerance for detecting zeros. This is used when (pseudo-) inverting 
           l and r."""

        self._sanity_checks = False

        self.N = N
        """The number of sites. Do not change after initializing."""
        
        self.N_centre = N // 2
        """The 'centre' site. This affects the gauge-fixing and canonical
           form. It is the site between the left-gauge parts and the 
           right-gauge parts."""
           
        self.D = sp.repeat(uni_ground.D, self.N + 2)
        """Vector containing the bond-dimensions. A[n] is a 
           q[n] x D[n - 1] x D[n] tensor."""
           
        self.q = sp.repeat(uni_ground.q, self.N + 2)
        """Vector containing the site Hilbert space dimensions. A[n] is a 
           q[n] x D[n - 1] x D[n] tensor."""
          
        self.uni_l = copy.deepcopy(uni_ground)
        self.uni_l.symm_gauge = True
        self.uni_l.sanity_checks = self.sanity_checks
        self.uni_l.update()
        
        if not N % self.uni_l.L == 0:
            print("Warning: Length of nonuniform window is not a multiple of the uniform block size.")

        self.uni_r = copy.deepcopy(self.uni_l)

        self.grown_left = 0
        self.grown_right = 0
        self.shrunk_left = 0
        self.shrunk_right = 0

        self._init_arrays()

        for n in range(1, self.N + 1):
            self.A[n][:] = self.uni_l.A[(n - 1) % self.uni_l.L]
        
        for n in range(self.N + 2):
            self.r[n][:] = sp.asarray(self.uni_l.r[(n - 1) % self.uni_l.L])
            self.l[n][:] = sp.asarray(self.uni_l.l[(n - 1) % self.uni_l.L])
Ejemplo n.º 26
0
def evaluate_hull(x, hull):
    """evaluate_hull: evaluate h_u(x) and (optional) h_l(x)

    Input:
       x     - abcissa
       hull  - the hull (see setup_hull for a definition)

    Output:
      hu(x) (optional), hl(x)

    History:
       2009-05-21 - Written - Bovy (NYU)
    """
    #Find in which [z_{i-1},z_i] interval x lies
    if x < hull[4][0]:
        #x lies in the first interval
        hux = hull[3][0] * (x - hull[1][0]) + hull[2][0]
        indx = 0
    else:
        if len(hull[5]) == 1:
            #There are only two intervals
            indx = 1
        else:
            indx = 1
            while indx < len(hull[4]) and hull[4][indx] < x:
                indx = indx + 1
            indx = indx - 1
        hux = hull[3][indx] * (x - hull[1][indx]) + hull[2][indx]
    #Now evaluate hlx
    neginf = sc.finfo(sc.dtype(sc.float64)).min
    if x < hull[1][0] or x > hull[1][-1]:
        hlx = neginf
    else:
        if indx == 0:
            hlx = ((hull[1][1] - x) * hull[2][0] +
                   (x - hull[1][0]) * hull[2][1]) / (hull[1][1] - hull[1][0])
        elif indx == len(hull[4]):
            hlx = (
                (hull[1][-1] - x) * hull[2][-2] +
                (x - hull[1][-2]) * hull[2][-1]) / (hull[1][-1] - hull[1][-2])
        elif x < hull[1][indx + 1]:
            hlx = ((hull[1][indx + 1] - x) * hull[2][indx] +
                   (x - hull[1][indx]) * hull[2][indx + 1]) / (
                       hull[1][indx + 1] - hull[1][indx])
        else:
            hlx = ((hull[1][indx + 2] - x) * hull[2][indx + 1] +
                   (x - hull[1][indx + 1]) * hull[2][indx + 2]) / (
                       hull[1][indx + 2] - hull[1][indx + 1])
    return hux, hlx
Ejemplo n.º 27
0
 def billard_setup_strip(self, R1, R2, d, N):
     # d = increment of radius
     # N = number of balls for the unit circle
     rads = sp.linspace(R1, R2, (R2-R1)/d)
     pts = []
     for r in rads:
         num = r * N
         base = sp.linspace(0, (2-sp.finfo(float).eps)*sp.pi, num) # split up the circumference to num pieces
         for arg in base: 
             x = r*(sp.cos(arg))
             y = r*(sp.sin(arg))
             pts.append((x,y))
     
     self.balls = sp.array(pts)
     self.corner_slopes()
Ejemplo n.º 28
0
def compute_E(PI):
    """Compute the entropy from soft assignment of the pixels to each cluster of the object.
    Input:
        -PI (array): belongship probability of each pixel (row) to each cluster (columns)
    Return:
        -E (float): entropy
    """
            
    E= 0
    ni,nC = PI.shape #Nbr of pixels in the object, number of clusters
    for c in range(nC): #For each cluster
        PI_c = 1./ni * sp.sum(PI[:,c]) #Average belongship probability of the obejct to this cluster
        if PI_c > sp.finfo(sp.float64).eps:
            E += - PI_c * sp.log(PI_c)
            
    return E   
Ejemplo n.º 29
0
def safe_logdet(cov):
    '''
    The function computes a secure version of the logdet of a covariance matrix and it returns the rcondition number of the matrix.
    Inputs:
        cov
    Outputs:
        the logdet
    '''
    eps = sp.finfo(sp.float64).eps
    e = linalg.eigvalsh(cov)
    if e.max() < eps:
        rcond = 0
    else:
        rcond = e.min() / e.max()
    e = sp.where(e < eps, eps, e)
    return sp.sum(sp.log(e)), rcond
Ejemplo n.º 30
0
def safe_logdet(cov):
    '''
    The function computes a secure version of the logdet of a covariance matrix and it returns the rcondition number of the matrix.
    Inputs:
        cov
    Outputs:
        the logdet
    '''
    eps = sp.finfo(sp.float64).eps
    e = linalg.eigvalsh(cov)
    if e.max()<eps:
        rcond = 0
    else:
        rcond = e.min()/e.max()    
    e = sp.where(e<eps,eps,e)    
    return sp.sum(sp.log(e)),rcond
Ejemplo n.º 31
0
    def __init__(self, numsites, uni_ground):
        self.u_gnd_l = uni.EvoMPS_TDVP_Uniform(uni_ground.D, uni_ground.q)
        self.u_gnd_l.sanity_checks = self.sanity_checks
        self.u_gnd_l.h_nn = uni_ground.h_nn
        self.u_gnd_l.h_nn_cptr = uni_ground.h_nn_cptr
        self.u_gnd_l.A = uni_ground.A.copy()
        self.u_gnd_l.l = uni_ground.l.copy()
        self.u_gnd_l.r = uni_ground.r.copy()

        self.u_gnd_l.symm_gauge = False
        self.u_gnd_l.update()
        self.u_gnd_l.calc_lr()
        self.u_gnd_l.calc_B()
        self.eta_uni = self.u_gnd_l.eta
        self.u_gnd_l_kmr = la.norm(self.u_gnd_l.r / la.norm(self.u_gnd_l.r) - 
                                   self.u_gnd_l.K / la.norm(self.u_gnd_l.K))

        self.u_gnd_r = uni.EvoMPS_TDVP_Uniform(uni_ground.D, uni_ground.q)
        self.u_gnd_r.sanity_checks = self.sanity_checks
        self.u_gnd_r.symm_gauge = False
        self.u_gnd_r.h_nn = uni_ground.h_nn
        self.u_gnd_r.h_nn_cptr = uni_ground.h_nn_cptr
        self.u_gnd_r.A = self.u_gnd_l.A.copy()
        self.u_gnd_r.l = self.u_gnd_l.l.copy()
        self.u_gnd_r.r = self.u_gnd_l.r.copy()
        
        self.grown_left = 0
        self.grown_right = 0
        self.shrunk_left = 0
        self.shrunk_right = 0

        self.h_nn = self.wrap_h
        self.h_nn_mat = None

        self.eps = sp.finfo(self.typ).eps

        self.N = numsites

        self._init_arrays()

        for n in xrange(self.N + 2):
            self.A[n][:] = self.u_gnd_l.A

        self.r[self.N] = self.u_gnd_r.r
        self.r[self.N + 1] = self.r[self.N]
        self.l[0] = self.u_gnd_l.l
Ejemplo n.º 32
0
    def learn(self, x, y):
        '''
        Function that learns the GMM with ridge regularizationb from training samples
        Input:
            x : the training samples
            y :  the labels
        Output:
            the mean, covariance and proportion of each class, as well as the spectral decomposition of the covariance matrix
        '''

        ## Get information from the data
        C = sp.unique(y).shape[0]
        #C = int(y.max(0))  # Number of classes
        n = x.shape[0]  # Number of samples
        d = x.shape[1]  # Number of variables
        eps = sp.finfo(sp.float64).eps

        ## Initialization
        self.ni = sp.empty(
            (C, 1))  # Vector of number of samples for each class
        self.prop = sp.empty((C, 1))  # Vector of proportion
        self.mean = sp.empty((C, d))  # Vector of means
        self.cov = sp.empty((C, d, d))  # Matrix of covariance
        self.Q = sp.empty((C, d, d))  # Matrix of eigenvectors
        self.L = sp.empty((C, d))  # Vector of eigenvalues
        self.classnum = sp.empty(C).astype('uint8')

        ## Learn the parameter of the model for each class
        for c, cR in enumerate(sp.unique(y)):

            j = sp.where(y == (cR))[0]

            self.classnum[c] = cR  # Save the right label
            self.ni[c] = float(j.size)
            self.prop[c] = self.ni[c] / n
            self.mean[c, :] = sp.mean(x[j, :], axis=0)
            self.cov[c, :, :] = sp.cov(
                x[j, :], bias=1, rowvar=0
            )  # Normalize by ni to be consistent with the update formulae

            # Spectral decomposition
            L, Q = linalg.eigh(self.cov[c, :, :])
            idx = L.argsort()[::-1]
            self.L[c, :] = L[idx]
            self.Q[c, :, :] = Q[:, idx]
Ejemplo n.º 33
0
def create_delta_vec(parvec, scales):
    ''' Make parameter delta vector suitable for numerical differentiation
        (NR 5.7 -- equation 5.7.8 -- optimal delta choice for centered differentiation)
    input: parameter vector (copied)
       default scale vector - used where parameter==0 -- obviously no scales[i] should be zero!!
    '''
    deltavec = sp.copy(parvec)
    # where equal to zero, set to scales -
    deltavec[parvec == 0.] = scales[parvec == 0.]
    npars = deltavec.size
    machine_resolution = (sp.finfo(deltavec.dtype)).resolution
    # trickery to get exactly machine representable delta:
    for i in range(npars):
        h = (machine_resolution)**(1.0 / 3.0) * deltavec[i]
        temp = deltavec[i] + h
        do_nothing_with(temp)
        deltavec[i] = temp - deltavec[i]
    return deltavec
Ejemplo n.º 34
0
    def learn(self,x,y):
        '''
        Function that learns the GMM with ridge regularizationb from training samples
        Input:
            x : the training samples
            y :  the labels
        Output:
            the mean, covariance and proportion of each class, as well as the spectral decomposition of the covariance matrix
        '''

        ## Get information from the data
        C = sp.unique(y).shape[0]
        #C = int(y.max(0))  # Number of classes
        n = x.shape[0]  # Number of samples
        d = x.shape[1]  # Number of variables
        eps = sp.finfo(sp.float64).eps

        ## Initialization
        self.ni = sp.empty((C,1))    # Vector of number of samples for each class
        self.prop = sp.empty((C,1))  # Vector of proportion
        self.mean = sp.empty((C,d))  # Vector of means
        self.cov = sp.empty((C,d,d)) # Matrix of covariance
        self.Q = sp.empty((C,d,d)) # Matrix of eigenvectors
        self.L = sp.empty((C,d)) # Vector of eigenvalues
        self.classnum = sp.empty(C).astype('uint8')
        
        ## Learn the parameter of the model for each class
        for c,cR in enumerate(sp.unique(y)):
            
            j = sp.where(y==(cR))[0]
            
            self.classnum[c] = cR # Save the right label
            self.ni[c] = float(j.size)    
            self.prop[c] = self.ni[c]/n
            self.mean[c,:] = sp.mean(x[j,:],axis=0)
            self.cov[c,:,:] = sp.cov(x[j,:],bias=1,rowvar=0)  # Normalize by ni to be consistent with the update formulae

            # Spectral decomposition
            L,Q = linalg.eigh(self.cov[c,:,:])
            idx = L.argsort()[::-1]
            self.L[c,:] = L[idx]
            self.Q[c,:,:]=Q[:,idx]
Ejemplo n.º 35
0
def evaluate_hull(x,hull):
    """evaluate_hull: evaluate h_u(x) and (optional) h_l(x)

    Input:
       x     - abcissa
       hull  - the hull (see setup_hull for a definition)

    Output:
      hu(x) (optional), hl(x)

    History:
       2009-05-21 - Written - Bovy (NYU)
    """
    #Find in which [z_{i-1},z_i] interval x lies
    if x < hull[4][0]:
        #x lies in the first interval
        hux= hull[3][0]*(x-hull[1][0])+hull[2][0]
        indx= 0
    else:
        if len(hull[5]) == 1:
            #There are only two intervals
            indx= 1
        else:
            indx= 1
            while indx < len(hull[4]) and hull[4][indx] < x:
                indx= indx+1
            indx= indx-1
        hux= hull[3][indx]*(x-hull[1][indx])+hull[2][indx]
    #Now evaluate hlx
    neginf= sc.finfo(sc.dtype(sc.float64)).min
    if x < hull[1][0] or x > hull[1][-1]:
        hlx= neginf
    else:
        if indx == 0:
            hlx= ((hull[1][1]-x)*hull[2][0]+(x-hull[1][0])*hull[2][1])/(hull[1][1]-hull[1][0])
        elif indx == len(hull[4]):
            hlx= ((hull[1][-1]-x)*hull[2][-2]+(x-hull[1][-2])*hull[2][-1])/(hull[1][-1]-hull[1][-2])
        elif x < hull[1][indx+1]:
            hlx= ((hull[1][indx+1]-x)*hull[2][indx]+(x-hull[1][indx])*hull[2][indx+1])/(hull[1][indx+1]-hull[1][indx])
        else:
            hlx= ((hull[1][indx+2]-x)*hull[2][indx+1]+(x-hull[1][indx+1])*hull[2][indx+2])/(hull[1][indx+2]-hull[1][indx+1])
    return hux, hlx
Ejemplo n.º 36
0
def orthonormal(m):
    """
    calculate eigen vectors of a random symmetric m by m matrix
    and fetch its eigenvectors

    verify it it is orthonormal, recurse it tests fail
    :param m:
    :return:
    """
    A = sp.rand(m, m)
    S = A * A.T
    _, P = linalg.eigh(S)

    # verification
    I = sp.eye(m)
    tolerance = sp.finfo(float).eps * 16
    if (P.dot(P.T) - I > tolerance).any():
        return orthonormal(m)

    return P
Ejemplo n.º 37
0
def zexpmv(A, v, t, norm_est=1., m=5, tol=0., trace=False, A_is_Herm=False):
    assert A.dtype.type is sp.complex128
    assert v.dtype.type is sp.complex128
    
    #Override expokit deault precision to match scipy sparse eigs more closely.
    if tol == 0:
        tol = sp.finfo(sp.complex128).eps * 2 #cannot take eps, as expokit changes this to sqrt(eps)!
    
    xn = A.shape[0]
    vf = sp.ones((xn,), dtype=A.dtype)
    
    m = min(xn - 1, m)
    
    nwsp = max(10, xn * (m + 2) + 5 * (m + 2)**2 + ideg + 1)
    wsp = sp.zeros((nwsp,), dtype=A.dtype)
    
    niwsp = max(7, m + 2)
    iwsp = sp.zeros((niwsp,), dtype=sp.int32)
    
    iflag = sp.zeros((1,), dtype=sp.int32)
    itrace = sp.array([int(trace)])
    
    if A_is_Herm:
        expokit.zhexpv(m, [t], v, vf, [tol], [norm_est], 
                       wsp, iwsp, A.matvec, itrace, iflag, n=[xn], 
                       lwsp=[len(wsp)], liwsp=[len(iwsp)])
    else:
        expokit.zgexpv(m, [t], v, vf, [tol], [norm_est], 
                       wsp, iwsp, A.matvec, itrace, iflag, n=[xn], 
                       lwsp=[len(wsp)], liwsp=[len(iwsp)])

    if iflag[0] == 1:
        print "Max steps reached!"
    elif iflag[0] == 2:
        print "Tolerance too high!"
    elif iflag[0] < 0:
        print "Bad arguments!"
    elif iflag[0] > 0:
        print "Unknown error!"
        
    return vf
Ejemplo n.º 38
0
def mylstsq(a, b, rcond):
    '''
    Compute a safe/fast least square fitting. 
    For that particular case, the number of unknown parameters is equal to the number of equations. 
    However, a is a covariance matrix that might estimated with a number of samples less than the number of variables, leading to a badly conditionned covariance matrix.
    So, the rcond number is check: if it is ok, we use the fast linalg.solve function; otherwise, we use the slow, but safe, linalg.lstsq function.
    Inputs:
    a: a symmetric definite positive matrix d times d
    b: a d times n matrix
    Outputs:
    x: a d times n matrix
    '''
    eps = sp.finfo(sp.float64).eps
    if rcond>eps: # If the condition number is not too bad try linear system
        try:
            x = linalg.solve(a,b)
        except linalg.LinAlgError: # If error, use least square estimations
            x = linalg.lstsq(a,b)[0]
    else:# Use least square estimate
        x = linalg.lstsq(a,b)[0]
    return x
Ejemplo n.º 39
0
def beamwidth(frequency, length):
    """
    The half power beamwidth of a finite length dipole antenna.
    :param frequency: The operating frequency (Hz).
    :param length: The length of the dipole (m).
    :return: The half power beamwidth of a small dipole antenna (deg).
    """
    # Calculate the wavenumber times the length
    kl = 2.0 * pi * frequency / c * length

    # Calculate the normalized radiation intensity
    theta = linspace(finfo(float).eps, 2.0 * pi, 10000)
    f = ((cos(0.5 * kl * cos(theta)) - cos(0.5 * kl)) / sin(theta))**2
    g = f / max(f)

    for iT, iU in zip(theta, g):
        if iU >= 0.5:
            theta_half = 0.5 * pi - iT
            break

    return 2.0 * theta_half * 180.0 / pi
Ejemplo n.º 40
0
def beamwidth(frequency, radius):
    """
    The half power beamwidth of a circular loop antenna.
    :param frequency: The operating frequency (Hz).
    :param radius: The radius of the circular loop (m).
    :return: The beamwidth (deg).
    """
    # Calculate the wavenumber
    k = 2.0 * pi * frequency / c

    # Calculate the normalized radiation intensity
    theta = linspace(finfo(float).eps, 2.0 * pi, 10000)
    f = (j1(k * radius * sin(theta)))**2
    g = f / max(f)

    for iT, iU in zip(theta, g):
        if iU >= 0.5:
            theta_half = 0.5 * pi - iT
            break

    return 2.0 * theta_half * 180.0 / pi
Ejemplo n.º 41
0
def mylstsq(a, b, rcond):
    '''
    Compute a safe/fast least square fitting. 
    For that particular case, the number of unknown parameters is equal to the number of equations. 
    However, a is a covariance matrix that might estimated with a number of samples less than the number of variables, leading to a badly conditionned covariance matrix.
    So, the rcond number is check: if it is ok, we use the fast linalg.solve function; otherwise, we use the slow, but safe, linalg.lstsq function.
    Inputs:
    a: a symmetric definite positive matrix d times d
    b: a d times n matrix
    Outputs:
    x: a d times n matrix
    '''
    eps = sp.finfo(sp.float64).eps
    if rcond > eps:  # If the condition number is not too bad try linear system
        try:
            x = linalg.solve(a, b)
        except linalg.LinAlgError:  # If error, use least square estimations
            x = linalg.lstsq(a, b)[0]
    else:  # Use least square estimate
        x = linalg.lstsq(a, b)[0]
    return x
Ejemplo n.º 42
0
def fixpoint(f, x, tol=None, maxit=100, **kwargs):
    """ Fixed point function iteration

    Parameters
    -------------
    f : function
      Function for which to find the fixed point.
    x : array 
      Initial guess.
    tol : float, optional
      Tolerance for convergence.
    maxit : int, optional
      Maximum number of iterations.

    Returns
    -----------
    info : integer
       Did function converge? -1 if it did not, and 0 if it did.
    relres : float
       Relative residual at last iteration.
    t : int
       Number of iterations
    gval : array
       Fixed point, where f(x) = x.
       
    """
    if tol is None:
        tol = sqrt(sp.finfo(float).eps)
    info = -1
    t = 0
    for it in range(maxit):
        t += 1
        gval = f(x, **kwargs)
        relres = la.norm(gval - x)
        if relres < tol:
            info = 0
            break
        x = gval
    return (info, relres, t, gval)
Ejemplo n.º 43
0
Archivo: ps3.py Proyecto: jrnold/psc585
    def newton(self, y, t=1, tol=None, maxit=100, verbose=False):
        """ Newton iteration

        Parameters
        ------------
        y : ndarray, shape (155, )
           Initial parameter guess. Changed in place.
        tol : float
           Tolerance for convergence
        maxit : int
           Maximum number of iterations
        verbose : bool
            Whether to print messages during iterations

        Returns
        -------
        info: integer
           Did function converge? True if it did.
        relres : float
           Relative residual of last iteration
        i : int
           Number of iterations


        """
        if tol is None:
            tol = sp.sqrt(sp.finfo(float).eps)
        info = False
        for i in range(maxit):
            f, df, dft = self.func(y, t)
            dy = la.solve(df, f)
            y -= dy
            relres = la.norm(dy)
            if verbose:
                print("%d: %f" % (i, relres))
            if relres  < tol:
                info = True
                break
        return (info, relres, i)
Ejemplo n.º 44
0
    def predict(self, xt, x, y, out_decision=None, out_proba=None):
        nt = xt.shape[0]
        C = int(y.max())
        D = sp.empty((nt, C))
        D += self.prop
        eps = sp.finfo(sp.float64).eps

        # Pre compute the Gramm kernel matrix
        Kt = KERNEL()
        Kt.compute_kernel(xt, z=x, sig=self.sig)
        Ki = KERNEL()

        for i in range(C):
            t = sp.where(y == (i + 1))[0]
            Ki.compute_kernel(x, z=x[t, :], sig=self.sig)
            T = Kt.K - sp.dot(Ki.K, sp.ones((self.ni[i])) / self.ni[i])
            temp = sp.dot(T, self.S)
            D[:, i] = sp.sum(T * temp, axis=1)

        # Check if negative value
        if D.min() < 0:
            D -= D.min()

        yp = D.argmin(1) + 1
        yp.shape = (nt, 1)

        # Format the output
        if out_proba is None:
            if out_decision is None:
                return yp
            else:
                return yp, D
        else:
            # Compute posterior !! Should be changed to a safe version
            P = sp.exp(-0.5 * D)
            P /= sp.sum(P, axis=1).reshape(nt, 1)
            P[P < eps] = 0
        return yp, D, P
Ejemplo n.º 45
0
    def predict(self, xt, x, y, out_decision=None, out_proba=None):
        nt = xt.shape[0]
        C = int(y.max())
        D = sp.empty((nt, C))
        D += self.prop
        eps = sp.finfo(sp.float64).eps

        # Pre compute the Gramm kernel matrix
        Kt = KERNEL()
        Kt.compute_kernel(xt, z=x, sig=self.sig)
        Ki = KERNEL()

        for i in range(C):
            t = sp.where(y == (i + 1))[0]
            Ki.compute_kernel(x, z=x[t, :], sig=self.sig)
            T = Kt.K - sp.dot(Ki.K, sp.ones((self.ni[i])) / self.ni[i])
            temp = sp.dot(T, self.S)
            D[:, i] = sp.sum(T * temp, axis=1)

        # Check if negative value
        if D.min() < 0:
            D -= D.min()

        yp = D.argmin(1) + 1
        yp.shape = (nt, 1)

        # Format the output
        if out_proba is None:
            if out_decision is None:
                return yp
            else:
                return yp, D
        else:
            # Compute posterior !! Should be changed to a safe version
            P = sp.exp(-0.5 * D)
            P /= sp.sum(P, axis=1).reshape(nt, 1)
            P[P < eps] = 0
        return yp, D, P
def area(pts):
    from scipy.spatial import ConvexHull
    # Get the area of convex hull enclosing points (2D)

    # check if collinear
    tfcollinear = True
    eps = sp.finfo(float).eps
    for kk in range(2, len(pts)):
        if(
         pts[0][0] * (pts[1][1] - pts[kk][1]) +
         pts[1][0] * (pts[kk][1] - pts[0][1]) +
         pts[kk][0] * (pts[0][1] - pts[1][1]) > eps):
            tfcollinear = False
            break

    # calculate convex hull of pts
    if tfcollinear:
        area = 0
    else:
        hull = ConvexHull(pts)
        area = hull.volume

    return area
Ejemplo n.º 47
0
    def decomposition(self, M):
        """
            Compute the decompostion of symmetric matrix
            Inputs:
                M:   matrix to decompose
            Outputs:
                vp:    eigenvalues
                Q:     eigenvectors
                rcond: conditioning
        """
        # Decomposition
        vp,Q = linalg.eigh(M)

        # Compute conditioning
        eps = sp.finfo(sp.float64).eps
        if vp.max()<eps:
            rcond = 0
        else:
            rcond = vp.min()/vp.max()

        vp[vp<eps] = eps

        return vp,Q,rcond
Ejemplo n.º 48
0
def axis_angle_from_rotation_matrix(rm):
    """
    Converts 3x3 rotation matrix to axis and angle representation.
    
    :type rm: 3x3 :obj:`float` matrix
    :param rm: Rotation matrix.
    :rtype: :obj:`tuple`
    :return: :samp:`(axis, radian_angle)` pair (angle in radians).
    """
    eps = (16*sp.finfo(rm.dtype).eps)
    aa = sp.array((0,0,1), dtype=rm.dtype) 
    theta = aa[0];
    c = (sp.trace(rm) - 1)/2;
    if (c > 1):
        c = 1;
    if (c < -1):
        c = -1;
    if (math.fabs(math.fabs(c)-1) >= eps):
        theta = math.acos(c);
        s = math.sqrt(1-c*c);
        inv2s = 1/(2*s);
        aa[0] = inv2s*(rm[2,1] - rm[1,2]);
        aa[1] = inv2s*(rm[0,2] - rm[2,0]);
        aa[2] = inv2s*(rm[1,0] - rm[0,1]);
    elif (c >= 0):
        theta = 0;
    else:
        rmI = (rm + sp.eye(3,3,dtype=rm.dtype));
        theta = np.pi;
        for i in range(0,3):
            n2 = np.linalg.norm(rmI[:,i]);
            if (n2 > 0):
                aa = col(rmI, i);
                break;

    return aa, theta
Ejemplo n.º 49
0
    def __init__(self, N, uni_ground):

        super(EvoMPS_TDVP_Sandwich, self).__init__(N, uni_ground)

        assert uni_ground.ham_sites == 2, 'Sandwiches only supported for \
                                           nearest-neighbour Hamiltonians at present!'

        self.uni_l.calc_B()
        self.eta_sq_uni = self.uni_l.eta_sq
        print("Bulk eta: ", self.eta_sq_uni)

        self.h_nn = None
        """The Hamiltonian for the nonuniform region. 
           Can be changed, for example, to perform
           a quench or to study an impurity problem. 
           The number of neighbouring sites acted on must be 
           specified in ham_sites."""

        if callable(self.uni_l.ham):
            self.h_nn = lambda n, s, t, u, v: self.uni_l.ham(s, t, u, v)
        else:
            self.h_nn = [self.uni_l.ham] * (self.N + 1)

        self.eps = sp.finfo(self.typ).eps
Ejemplo n.º 50
0
    def __init__(self, N, uni_ground):        
        
        super(EvoMPS_TDVP_Sandwich, self).__init__(N, uni_ground)
        
        assert uni_ground.ham_sites == 2, 'Sandwiches only supported for \
                                           nearest-neighbour Hamiltonians at present!'
        
        self.uni_l.calc_B()
        self.eta_sq_uni = self.uni_l.eta_sq
        print("Bulk eta: ", self.eta_sq_uni)
        
        self.h_nn = None
        """The Hamiltonian for the nonuniform region. 
           Can be changed, for example, to perform
           a quench or to study an impurity problem. 
           The number of neighbouring sites acted on must be 
           specified in ham_sites."""
        
        if callable(self.uni_l.ham):
            self.h_nn = lambda n, s, t, u, v: self.uni_l.ham(s, t, u, v)
        else:
            self.h_nn = [self.uni_l.ham] * (self.N + 1)

        self.eps = sp.finfo(self.typ).eps
def d2c(sys,method='zoh'):
    """Continous to discrete conversion with ZOH method

    Call:
    sysc=c2d(sys,method='log')

    Parameters
    ----------
    sys :   System in statespace or Tf form 
    method: 'zoh' or 'bi'

    Returns
    -------
    sysc: continous system ss or tf
    

    """
    flag = 0
    if isinstance(sys, TransferFunction):
        sys=tf2ss(sys)
        flag=1

    a=sys.A
    b=sys.B
    c=sys.C
    d=sys.D
    Ts=sys.Tsamp
    n=shape(a)[0]
    nb=shape(b)[1]
    nc=shape(c)[0]
    tol=1e-12
    
    if method=='zoh':
        if n==1:
            if b[0,0]==1:
                A=0
                B=b/sys.Tsamp
                C=c
                D=d
        else:
            tmp1=hstack((a,b))
            tmp2=hstack((zeros((nb,n)),eye(nb)))
            tmp=vstack((tmp1,tmp2))
            s=logm(tmp)
            s=s/Ts
            if norm(imag(s),inf) > sqrt(sp.finfo(float).eps):
                print "Warning: accuracy may be poor"
            s=real(s)
            A=s[0:n,0:n]
            B=s[0:n,n:n+nb]
            C=c
            D=d
    elif method=='bi':
        a=mat(a)
        b=mat(b)
        c=mat(c)
        d=mat(d)
        poles=eigvals(a)
        if any(abs(poles-1)<200*sp.finfo(float).eps):
            print "d2c: some poles very close to one. May get bad results."
        
        I=mat(eye(n,n))
        tk = 2 / sqrt (Ts)
        A = (2/Ts)*(a-I)*inv(a+I)
        iab = inv(I+a)*b
        B = tk*iab
        C = tk*(c*inv(I+a))
        D = d- (c*iab)
    else:
        print "Method not supported"
        return
    
    sysc=ss(A,B,C,D)
    if flag==1:
        sysc=ss2tf(sysc)
    return sysc
Ejemplo n.º 52
0
 def __call__(self, X, evalfunc, maxEpoch=100, verbose=False, convergenceThreshold=None):
     """ Run the scaled conjugate gradient descent """
     eps = finfo(float).eps
     sigma0 = 1.0e-4
     epoch = 0
     
     # Initial function value and gradient
     fold, gradnew = evalfunc(X)
     fnew = fold
     gradold = gradnew.copy()
         
     # Initial search direction
     d = -gradnew.copy()
     
     # Force calculation of ddirectional derivs
     success = True
     
     # nsuccess counts number of successes
     nsuccess = 0
     
     # Initial scale parameter
     beta = 1.0
     theta = 0.0
     
     # Lower and upper bound on scale
     betamin = 1.0e-15
     betamax = 1.0e100
     
     # Set the convergence threshold
     deltaThreshold = 1.0e-8
     ratioThreshold = 1.0e-6
     if convergenceThreshold is not None:
         deltaThreshold = convergenceThreshold[0]
         ratioThreshold = convergenceThreshold[1]
     pass
     
     # Main optimization loop
     epoch = 1
     while epoch < maxEpoch:
         
         # Calculate first and second directional derivatives
         if success:
             mu = dot(d, gradnew)
             if mu >= 0:
                 d = -gradnew.copy()
                 mu = dot(d, gradnew)
             pass
             kappa = dot(d, d)
             if kappa < eps:
                 print("kappa: ", kappa, " eps: ", eps)
                 print("Terminated due to kappa < eps.")
                 return
             pass
             sigma = sigma0 / sqrt(kappa)
             Xplus = X.copy()
             Xplus.params[:] = X.params + sigma * d
             _, gplus = evalfunc(Xplus)
             theta = dot(d, gplus - gradnew) / sigma
         pass
         
         # Increase effective curvature and evaluate step size alpha
         delta = theta + beta * kappa
         if delta <= 0:
             delta = beta * kappa
             beta = beta - theta / kappa
         pass
         alpha = -mu/delta
         
         # Calculate the comparison ratio
         Xnew = X.copy()
         Xnew.params[:] = X.params + alpha * d
         fnew, _ = evalfunc(Xnew)
         
         Delta = 2.0 * (fnew - fold) / (alpha * mu)
         if Delta >= 0.0:
             success = True
             nsuccess += 1
             X = Xnew.copy()
             fnow = fnew
         else:
             success = False
             fnow = fold
         pass
         
         if verbose:
             print("Epoch {:d} Error {:f} Scale {:f}".format(epoch, fnow, beta))
         
         if success:
             # Test for termination
             if absolute(alpha * d).max() < ratioThreshold:
                 if absolute(fnew - fold) < deltaThreshold:
                     return
                 pass
             else:
                 # Update variables for new position
                 fold = fnew
                 gradold = gradnew.copy()
                 _, gradnew = evalfunc(X)
                 
                 # If the gradient is zero, then we are done.
                 if dot(gradnew, gradnew) == 0:
                     print("Optimization converges. Final error: ", fnew)
                     return
                 pass
             pass
         pass
         
         # Adjust beta according to comparison ratio
         if Delta < 0.25:
             beta = min(4.0 * beta, betamax)
         pass
         if Delta > 0.75:
             beta = max(0.5 * beta, betamin)
         pass
         
         # Update search direction using Polack-Ribiere formula, or restart
         # in direction of negative gradient after nparams steps
         if nsuccess == X.params.shape[0]:
             d = -gradnew.copy()
             nsuccess = 0
         else:
             if success:
                 gamma = dot(gradold - gradnew, gradnew) / mu
                 d = dot(gamma, d) - gradnew
             pass
         pass
         epoch += 1
     pass
     # If we get here, then we haven't terminated in the given number of
     # iterations.
     print("Warning: Maximum number of iterations has been exceeded")
Ejemplo n.º 53
0
"""
Taken from sklearn.gaussian_process module and stripped out naked to the bare minimum
"""

from scipy import linalg as LA
import scipy as sp
from sklearn.utils import array2d
from sklearn.gaussian_process import correlation_models
import Cholesky

MACHINE_EPSILON = sp.finfo(sp.double).eps    


def kernel(d, theta, correlation='squared_exponential'):
    if correlation is 'absolute_exponential':
        return sp.exp(-d / theta) # correlation_models.absolute_exponential(theta, d)
    elif  correlation is 'squared_exponential':
        return sp.exp(-d**2 / (2.0 * theta**2)) # correlation_models.squared_exponential(theta, d)
    elif  correlation is 'generalized_exponential':
        return correlation_models.generalized_exponential(theta, d)
    elif  correlation is 'cubic':
        return correlation_models.cubic(theta, d)
    elif  correlation is 'linear':
        return correlation_models.linear(theta, d)
    else:
        print "Correlation model %s not understood" % correlation
        return None

    
def matrix_distance(A, B):
Ejemplo n.º 54
0
     squeeze, tile, reshape, \
     ones, zeros, int_, \
     setxor1d, sort, union1d, unique, \
     finfo
from scipy.linalg import svd
import numpy as num

# module variables
sqr6i  = 1./sqrt(6.)
sqr3i  = 1./sqrt(3.)
sqr2i  = 1./sqrt(2.)
sqr2   = sqrt(2.)
sqr3   = sqrt(3.)
sqr2b3 = sqrt(2./3.)

fpTol = finfo(float).eps                # ~2.2e-16
vTol  = 1.0e-14


def columnNorm(a):
    """
    normalize array of column vectors (hstacked, axis = 0)
    """
    if len(a.shape) > 2:
        raise RuntimeError, "incorrect shape: arg must be 1-d or 2-d, yours is %d" %(len(a.shape))

    cnrma = sqrt(sum(asarray(a)**2, 0))

    return cnrma

def rowNorm(a):
Ejemplo n.º 55
0
"""noise generation with multivariate autoregressive models"""
__docformat__ = "restructuredtext"


##---IMPORTS

# packages
import scipy as N
from scipy import linalg as NL, random as NR
from collections import deque
from noise_gen import NoiseGen


##---CONSTANTS

EPS = N.finfo(N.float64).eps


##---FUNCTIONS

def ar_fit(p_data, p_or_plist=range(100), selector='sbc'):
    """fits a (multivariate) AR (_A_uto_R_egrssive) model to data

    :Parameters:
        p_data : ndarray
            Data with observations on the rows and variables on the columns
        p_or_plist : list
            List of model orders to select from. This list has to be continuous
            with a step size of 1, e.g. [10,11,12,13,14]
        selector : str
            One of 'sbc' for the Schwarz Bayesian Criterion or 'fpe' for the
Ejemplo n.º 56
0
    def __init__(self, numsites, D, q):
        """Creates a new TDVP_MPS object.
        
        The TDVP_MPS class implements the time-dependent variational principle 
        for matrix product states for systems with open boundary conditions and
        a hamiltonian consisting of a nearest-neighbour interaction term and a 
        single-site term (external field).
        
        Bond dimensions will be adjusted where they are too high to be useful.
        FIXME: Add reference.
        
        Parameters
        ----------
        numsites : int
            The number of lattice sites.
        D : ndarray
            A 1-d array, length numsites, of integers indicating the desired bond dimensions.
        q : ndarray
            A 1-d array, also length numsites, of integers indicating the 
            dimension of the hilbert space for each site.
    
        Returns
        -------
        sqrt_A : ndarray
            An array of the same shape and type as A containing the matrix square root of A.        
        """
        self.eps = sp.finfo(self.typ).eps
        
        self.N = numsites
        self.D = sp.array(D)
        self.q = sp.array(q)
        
        #Make indicies correspond to the thesis
        self.K = sp.empty((self.N + 1), dtype=sp.ndarray) #Elements 1..N
        self.C = sp.empty((self.N), dtype=sp.ndarray) #Elements 1..N-1
        self.A = sp.empty((self.N + 1), dtype=sp.ndarray) #Elements 1..N
        
        self.r = sp.empty((self.N + 1), dtype=sp.ndarray) #Elements 0..N
        self.l = sp.empty((self.N + 1), dtype=sp.ndarray)        
        
        if (self.D.ndim != 1) or (self.q.ndim != 1):
            raise NameError('D and q must be 1-dimensional!')
            
        #TODO: Check for integer type.
        
        #Don't do anything pointless
        self.D[0] = 1
        self.D[self.N] = 1

        qacc = 1
        for n in reversed(xrange(self.N)):
            if qacc < self.D.max(): #Avoid overflow!
                qacc *= self.q[n + 1]

            if self.D[n] > qacc:
                self.D[n] = qacc
                
        qacc = 1
        for n in xrange(1, self.N + 1):
            if qacc < self.D.max(): #Avoid overflow!
                qacc *= q[n - 1]

            if self.D[n] > qacc:
                self.D[n] = qacc
        
        self.r[0] = sp.zeros((self.D[0], self.D[0]), dtype=self.typ, order=self.odr)  
        self.l[0] = sp.eye(self.D[0], self.D[0], dtype=self.typ).copy(order=self.odr) #Already set the 0th element (not a dummy)    
    
        for n in xrange(1, self.N + 1):
            self.K[n] = sp.zeros((self.D[n-1], self.D[n-1]), dtype=self.typ, order=self.odr)    
            self.r[n] = sp.zeros((self.D[n], self.D[n]), dtype=self.typ, order=self.odr)
            self.l[n] = sp.zeros((self.D[n], self.D[n]), dtype=self.typ, order=self.odr)
            self.A[n] = sp.empty((self.q[n], self.D[n-1], self.D[n]), dtype=self.typ, order=self.odr)
            if n < self.N:
                self.C[n] = sp.empty((self.q[n], self.q[n+1], self.D[n-1], self.D[n+1]), dtype=self.typ, order=self.odr)
        sp.fill_diagonal(self.r[self.N], 1.)
        self.setup_A()
        
        self.eta = sp.zeros((self.N + 1), dtype=self.typ)
Ejemplo n.º 57
0
    def take_step_implicit(self, dtau, midpoint=True):
        """A backward (implicit) integration step.
        
        Based on p. 8-10 of arXiv:1103.0936v2 [cond-mat.str-el].
        
        NOTE: Not currently working as well as expected. Iterative solution of 
              implicit equation stops converging at some point...
        
        This is made trickier by the gauge freedom. We solve the implicit equation iteratively, aligning the tangent
        vectors along the gauge orbits for each step to obtain the physically relevant difference dA. The gauge-alignment is done
        by solving a matrix equation.
        
        The iteration seems to be difficult. At the moment, iteration over the whole chain is combined with iteration over a single
        site (a single A[n]). Iteration over the chain is needed because the evolution of a single site depends on the state of the
        whole chain. The algorithm runs through the chain from N to 1, iterating a few times over each site (depending on how many
        chain iterations we have done, since iterating over a single site becomes more fruitful as the rest of the chain stabilizes).
        
        In running_update mode, which is likely the most sensible choice, the current midpoint guess is updated after visiting each
        site. I.e. The trial backwards step at site n is based on the updates that were made to site n + 1, n + 2 during the current chain
        iteration.
        
        Parameters
        ----------
        dtau : complex
            The (imaginary or real) amount of imaginary time (tau) to step.
        midpoint : bool
            Whether to use approximately time-symmetric midpoint integration,
            or just a backward-Euler step.
        """        
        #---------------------------
        #Hard-coded params:
        debug = True
        dbg_bstep = False
        safe_mode = True
        
        tol = sp.finfo(sp.complex128).eps * 3
        max_iter = 10
        itr_switch_mode = 10
        #---------------------------
        
        if midpoint:
            dtau = dtau / 2
        
        self.restore_RCF()

        #Take a copy of the current state
        A0 = sp.empty_like(self.A)
        for n in xrange(1, self.N + 1):
            A0[n] = self.A[n].copy()
        
        #Take initial forward-Euler step
        self.take_step(dtau)     

        itr = 0
        delta = 1
        delta_prev = 0                
        final_check = False

        while delta > tol * (self.N - 1) and itr < max_iter or final_check:
            print "OUTER"
            running_update = itr < itr_switch_mode
            
            A_np1 = A0[self.N]            
            
            #Prepare for next calculation of B from the new A
            self.restore_RCF() #updates l and r
            
            if running_update:
                self.calc_C() #we really do need all of these, since B directly uses C[n-1]
                self.calc_K()            
            
            g0_n = sp.eye(self.D[self.N - 1], dtype=self.typ)       #g0_n is the gauge transform matrix needed to solve the implicit equation
            
            #Loop through the chain, optimizing the individual A's
            delta = 0
            for n in reversed(xrange(1, self.N)): #We start at N - 1, since the right vector can't be altered here.
                print "SWEEP"
                if not running_update: #save new A[n + 1] and replace with old version for building B
                    A_np1_new = self.A[n + 1].copy()
                    self.A[n + 1] = A_np1  
                    A_np1 = self.A[n].copy()
                    max_itr_n = 1 #wait until the next run-through of the chain to change A[n] again
                else:
                    max_itr_n = itr + 1 #do more iterations here as the outer loop progresses
                
                delta_n = 1
                itr_n = 0
                while True:
                    print "INNER"
                    #Find transformation to gauge-align A0 with the backwards-obtained A.. is this enough?
                    M = m.mmul(A0[n][0], g0_n, self.r[n], m.H(self.A[n][0]))
                    for s in xrange(1, self.q[n]):
                        M += m.mmul(A0[n][s], g0_n, self.r[n], m.H(self.A[n][s]))
                    
                    g0_nm1 = la.solve(self.r[n - 1], M, sym_pos=True, overwrite_b=True)
                    
                    if not (delta_n > tol and itr_n < max_itr_n):
                        break
                    
                    B = self.calc_B(n)
                    
                    if B is None:
                        delta_n = 0
                        fnorm = 0
                        break
                    
                    g0_nm1_inv = la.inv(g0_nm1) #sadly, we need the inverse too...    
                    r_dA = sp.zeros_like(self.r[n - 1])
                    dA = sp.empty_like(self.A[n])
                    sqsum = 0
                    for s in xrange(self.q[n]):
                        dA[s] = m.mmul(g0_nm1_inv, A0[n][s], g0_n)
                        dA[s] -= self.A[n][s] 
                        dA[s] -= dtau * B[s]
                        if not final_check:
                            self.A[n][s] += dA[s]
    
                    for s in xrange(self.q[n]):
                        r_dA += m.mmul(dA[s], self.r[n], m.H(dA[s]))
                        sqsum += sum(dA[s]**2)
                    
                    fnorm = sp.sqrt(sqsum)
                    
                    delta_n = sp.sqrt(sp.trace(m.mmul(self.l[n - 1], r_dA)))
                    
                    if running_update: #Since we want to use the current A[n] and A[n + 1], we need this:
                        if safe_mode:
                            self.restore_RCF()
                            self.calc_C()
                            self.calc_K()
                        else:
                            self.restore_RCF(start=n) #will also renormalize
                            self.calc_C(n_low=n-1, n_high=n)
                            self.calc_K(n_low=n, n_high=n+1)
                                        
                    itr_n += 1
                    
                    if final_check:
                        break
                    
                if not running_update: #save new A[n + 1] and replace with old version for building B
                    self.A[n + 1] = A_np1_new
                
                if debug:
                    print "delta_%d: %g, (%d iterations)" % (n, delta_n.real, itr_n) + ", fnorm = " + str(fnorm)
                delta += delta_n
                
                if safe_mode:
                    self.calc_r()
                else:
                    self.calc_r(n - 2, n - 1) #We only need these for the next step.
                
                g0_n = g0_nm1                
                            
            itr += 1
            if debug:
                print "delta: %g  delta delta: %g (%d iterations)" % (delta.real, (delta - delta_prev).real, itr)
            delta_prev = delta
            
            if debug:
                if final_check:
                    break
                elif delta <= tol * (self.N - 1) or itr >= max_iter:
                    print "Final check to get final delta:"
                    final_check = True
        
        #Test backward step!        
        if dbg_bstep:
            Anew = sp.empty_like(self.A)
            for n in xrange(1, self.N + 1):
                Anew[n] = self.A[n].copy()
            
#            self.calc_l()
#            self.simple_renorm()
#            self.restore_RCF()
            self.calc_C()
            self.calc_K()        
            self.take_step(-dtau)
            self.restore_RCF()
            
            delta2 = 0            
            for n in reversed(xrange(1, self.N + 1)):
                #print n
                dA = A0[n] - self.A[n]
                #Surely this dA should also preserve the gauge choice, since both A's are in ON_R...                
                #print dA/A0[n]
                r_dA = sp.zeros_like(self.r[n - 1])
                sqsum = 0
                for s in xrange(self.q[n]):
                    r_dA += m.mmul(dA[s], self.r[n], m.H(dA[s]))
                    sqsum += sum(dA[s]**2)
                delta_n = sp.sqrt(sp.trace(m.mmul(self.l[n - 1], r_dA)))                
                delta2 += delta_n
                if debug:
                    print "A[%d] OK?: " % n + str(sp.allclose(dA, 0)) + ", delta = " + str(delta_n) + ", fnorm = " + str(sp.sqrt(sqsum))
                #print delta_n
            if debug:
                print "Total delta: " + str(delta2)
                
            for n in xrange(1, self.N + 1):
                self.A[n] = Anew[n]
        else:
            delta2 = 0
            
        if midpoint:
            #Take a final step from the midpoint
            #self.restore_RCF() #updates l and r            
            self.calc_l()
            self.simple_renorm()
            self.calc_C()
            self.calc_K()
            self.take_step(dtau)
            
        return itr, delta, delta2