Ejemplo n.º 1
0
    def __init__(self, T, P, mezcla):
        self.T = unidades.Temperature(T)
        self.P = unidades.Pressure(P, "atm")
        self.mezcla = mezcla
        self.componente = mezcla.componente
        self.fraccion = mezcla.fraccion

        self.B = self.b * self.P.atm / R_atml / self.T
        self.Tita = self.tita * self.P.atm / (R_atml * self.T)**2

        delta = self.delta * self.P.atm / R_atml / self.T
        epsilon = self.epsilon * (self.P.atm / R_atml / self.T)**2
        eta = self.eta * self.P.atm / R_atml / self.T
        Z = roots([
            1, delta - self.B - 1, self.Tita + epsilon - delta * (self.B + 1),
            -epsilon * (self.B + 1) - self.Tita * eta
        ])
        self.Z = r_[Z[0].real, Z[2].real]

        self.V = self.Z * R_atml * self.T / self.P.atm  #mol/l
        self.x, self.xi, self.yi, self.Ki = self._Flash()
        self.H_exc = -(self.tita + self.dTitadT) / R_atml / self.T / (
            self.delta**2 - 4 * self.epsilon)**0.5 * log(
                (2 * self.V + self.delta -
                 (self.delta**2 - 4 * self.epsilon)**0.5) /
                (2 * self.V + self.delta +
                 (self.delta**2 - 4 * self.epsilon)**0.5)) + 1 - self.Z
Ejemplo n.º 2
0
Archivo: RCWA.py Proyecto: LeiDai/EMpy
def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c):
    """Dispersion relation for the extraordinary wave.

    NOTE
    See eq. 16 in Glytsis, "Three-dimensional (vector) rigorous
    coupled-wave analysis of anisotropic grating diffraction",
    JOSA A, 7(8), 1990 Always give positive real or negative
    imaginary.
    """

    if kx.shape != ky.shape or c.size != 3:
        raise ValueError('kx and ky must have the same length and c must have 3 components')

    kz = S.empty_like(kx)

    for ii in xrange(0, kx.size):

        alpha = nE**2 - nO**2
        beta = kx[ii]/k * c[0] + ky[ii]/k * c[1]

        # coeffs
        C = S.array([nO**2 + c[2]**2 * alpha, \
                     2. * c[2] * beta * alpha, \
                     nO**2 * (kx[ii]**2 + ky[ii]**2) / k**2 + alpha * beta**2 - nO**2 * nE**2])

        # two solutions of type +x or -x, purely real or purely imag
        tmp_kz = k * S.roots(C)

        # get the negative imaginary part or the positive real one
        if S.any(S.isreal(tmp_kz)):
            kz[ii] = S.absolute(tmp_kz[0])
        else:
            kz[ii] = -1j * S.absolute(tmp_kz[0])

    return kz
Ejemplo n.º 3
0
    def __init__(self, T, P, mezcla):
        P_atm = P/101325
        self.T = unidades.Temperature(T)
        self.P = unidades.Pressure(P)
        self.mezcla = mezcla
        self.componente = mezcla.componente
        self.zi = mezcla.fraccion

        self.B = self.b*P/R/T
        self.Tita = self.tita*P/(R*T)**2

        delta = self.delta*P/R/T
        epsilon = self.epsilon*(P/R/T)**2

        # δ1, δ2 calculated from polynomial factorization
        self.delta1 = ((self.delta**2-4*self.epsilon)**0.5-self.delta)/2/self.b
        self.delta2 = ((self.delta**2-4*self.epsilon)**0.5+self.delta)/2/self.b

        # Eq 4-6.3 in [1]_
        coeff = [1, delta-self.B-1, self.Tita+epsilon-delta*(self.B+1),
                 -epsilon*(self.B+1)-self.Tita*self.B]
        Z = roots(coeff)
        # print("Z", Z)
        # TODO: use the anallycal solution, Span, pag 50

        # Set the minimum and maximum root values as liquid and gas Z values
        self.Z = r_[Z[0].real, Z[2].real]
        self.Zl = min(Z).real
        self.Zg = max(Z).real

        self.V = self.Z*R_atml*T/P_atm  # l/mol
        self.rho = 1/self.V
        self.Vl = unidades.MolarVolume(self.Zl*R*T/P, "m3mol")   # l/mol
        self.Vg = unidades.MolarVolume(self.Zg*R*T/P, "m3mol")  # l/mol
Ejemplo n.º 4
0
Archivo: costs.py Proyecto: wey-gu/gpbo
    def npred(cev):
        rts = sp.roots([p[3] / 4., p[2] / 3., p[1] / 2., p[0] + cev, -C])

        nmax = max([sp.real(i) for i in rts if sp.isreal(i)])
        cbar = p[0] + p[1] * nmax / 2. + p[2] * (nmax**2) / 3. + p[3] * (
            nmax**3) / 4.
        return nmax, cbar
Ejemplo n.º 5
0
def vanderwaals(phase, P, T, Pc, Tc, MW, **kwargs):
    r"""
    Uses Van der Waals equation of state to calculate the density of a real gas
 
    Parameters
    ----------
    P, T, Pc, Tc, MW: float, array_like
        P pressure of the gas in [Pa]
        T temperature of the gas in [K]
        Pc critical pressure of the gas in [Pa]
        T critical temperature of the gas in [K]
        MW molecular weight of the gas in [kg/mol]
            
    Returns
    -------
    rho, the density in [mol/m3]
    
    """

    P = phase['pore.pressure']
    T = phase['pore.temperature']
    Pc = phase['pore.criticalpressure']
    Tc = phase['pore.criticaltemperature']
    R = 8.314
    a = 27 * (R**2) * (Tc**2) / (64 * Pc)
    b = R * Tc / (8 * Pc)
    a0 = 1
    a1 = -1 / b
    a2 = (R * T + b * P) / (a * b)
    a3 = -P / (a * b)
    density = sp.roots([a0, a1, a2, a3])
    value = sp.real(density[2])
    return value
Ejemplo n.º 6
0
    def _lib(self, cmp, T):
        if cmp.id in dat:
            # Use the compound specific parameters values
            xic, f = dat[cmp.id]
        else:
            # Use the generalization correlations, Eq 20-21
            f = 0.452413 + 1.30982 * cmp.f_acent - 0.295937 * cmp.f_acent**2
            xic = 0.329032 - 0.076799 * cmp.f_acent + 0.0211947 * cmp.f_acent**2

        # Eq 8
        c = (1 - 3 * xic) * R * cmp.Tc / cmp.Pc

        # Eq 10
        b = roots([1, 2 - 3 * xic, 3 * xic**2, -xic**3])
        Bpositivos = []
        for i in b:
            if i > 0:
                Bpositivos.append(i)
        Omegab = min(Bpositivos)
        b = Omegab * R * cmp.Tc / cmp.Pc

        # Eq 9
        Omegaa = 3 * xic**2 + 3 * (1 -
                                   2 * xic) * Omegab + Omegab**2 + 1 - 3 * xic

        if cmp.id in PT2:
            # Using improved alpha correlation from [2]_
            c1, c2, c3, n = PT2[cmp.id]
            alfa = 1 + c1*(T/cmp.Tc-1) + c2*((T/cmp.Tc)**0.5-1) + \
                c3*((T/cmp.Tc)**n-1)
        else:
            alfa = (1 + f * (1 - (T / cmp.Tc)**0.5))**2
        a = Omegaa * alfa * R**2 * cmp.Tc**2 / cmp.Pc

        return a, b, c
Ejemplo n.º 7
0
def quadfit(lowerLimit, upperLimit, x,y):
	import scipy
	from scipy.optimize import leastsq
	
	y = y[lowerLimit:upperLimit]
	x = x[lowerLimit:upperLimit]
	
	maxY = max(y)
	
	p0 = array([-276025.,1051.,1.])
	plsq = leastsq(quadresiduals, p0, args=(y, x), maxfev=2000)
	
	rplsq = []
	i=1
	while i <= len(plsq[0]):
		rplsq.append(plsq[0][-i])
		i = i+1
		
	diff = scipy.polyder(rplsq,1)
	roots = scipy.roots(diff)
	
	peak = 0
	for root in roots:
		if root < x[-1] and root > x[0]:
			peak = root
	
	fit = []
	
	for i in  x:
		fit.append((i,quadfunction(i,plsq[0])))
	
	return float(real(peak))
Ejemplo n.º 8
0
def polyint(lowerLimit, upperLimit, x, y):
	import scipy
	from scipy.optimize import leastsq
	
	y = y[lowerLimit:upperLimit]
	x = x[lowerLimit:upperLimit]
	
	maxY = max(y)
	
	p0 = array([-276025,1051,-1,1,100])
	plsq = leastsq(polyresiduals, p0, args=(y, x), maxfev=2000)
	
	rplsq = []
	i=1
	while i <= len(plsq[0]):
		rplsq.append(plsq[0][-i])
		i = i+1
		
	diff = scipy.polyder(rplsq,1)
	roots = scipy.roots(diff)
	
	peak = 0
	for root in roots:
		if root < x[-1] and root > x[0]:
			peak = root
	
	peakIntensity = polyfunction(peak,plsq[0])
		
	return float(real(peakIntensity))
Ejemplo n.º 9
0
 def test_roots(self):
     polinomio = [1.3, 4, .6, -1]  # polinomio = 1.3 x^3 + 4 x^2 + 0.6 x - 1
     x = sp.arange(-4, 1, .05)
     y = sp.polyval(polinomio, x)
     raices = sp.roots(polinomio)
     self.assertEqual(raices[0], -2.816023020827658)
     self.assertEqual(raices[1], -0.6691329703979497)
     self.assertEqual(raices[2], 0.4082329143025312)
Ejemplo n.º 10
0
 def getOmegas(self, typeeos, OmegaB=False):
     acc = self.acc
     if typeeos in ['srk']:
         OmegaC = 0.0
         onethird = 1.0 / 3.0
         OmegaB = onethird * (2**onethird - 1)
         OmegaD = OmegaB + 0.0
         OmegaA = onethird**2 / (2**onethird - 1)
     elif typeeos == 'pr':
         OmegaB = 0.077796
         OmegaA = 0.457235
         OmegaC = OmegaB + 0.0
         OmegaD = OmegaB + 0.0
     elif typeeos == 'pt':
         Zc = 0.3272 - 0.0537 * acc - 0.0147 * acc**2  #Note: NOT experimental Zc!
         A = 1.0
         B = 2 - 3 * Zc
         C = 3 * Zc**2
         D = -Zc**3
         rts = scipy.roots([A, B, C, D])
         OmegaB = min([
             r.real for r in rts if (r.real > 0.0) and (abs(r.imag) < 1e-9)
         ])
         OmegaD = OmegaB + 0.0
         OmegaC = 1 - 3 * Zc
         OmegaA = 3 * Zc**2 + OmegaB * OmegaC + OmegaC * OmegaD + OmegaB * OmegaD + OmegaC + OmegaD
     elif typeeos in ['hkm2']:
         Zc = 0.3175 - 0.0364 * acc - 0.0245 * acc**2  #Note: NOT experimental Zc!
         A = 1.0
         B = 1.25 - 3 * Zc
         C = 3 * Zc**2 - 1.5 * Zc + 0.5
         D = -Zc**3
         rts = scipy.roots([A, B, C, D])
         OmegaB = min([
             r.real for r in rts if (r.real > 0.0) and (abs(r.imag) < 1e-9)
         ])
         OmegaE = 6 * Zc - 3 * OmegaB - 2
         OmegaA = 3 * Zc**2 - 0.5 * OmegaB**2 - 0.75 * OmegaB * OmegaE - 0.5 * (
             OmegaB + OmegaE)
         n = -0.5
         m = -0.5
         nbplusme = n * OmegaB + m * OmegaE
         nbme = n * OmegaB * m * OmegaE
         OmegaD = 0.5 * (nbplusme - scipy.sqrt(nbplusme**2 + 4 * nbme))
         OmegaC = -nbme / OmegaD
     return OmegaA, OmegaB, OmegaC, OmegaD
Ejemplo n.º 11
0
def solve_composition(a, potentials, P=1., T=500., verbose=False):
    """
    Calculate the equilibrium composition and free energy of a homonuclear gas mixture

    Arguments
        a: iterable of number of atoms in homonuclear molecule
            e.g. [2,8] if only considering S2, S8
        potentials: chemical potentials at reference pressure and given T of species studied, in J mol-1
        P: Pressure in units of reference pressure
            e.g. P=0.001 if study pressure is 1 mbar and reference pressure for potentials is 1 bar
        T: Temperature in K. This temperature must also be used when generating input potentials.
        verbose: Boolean flag. Print intermediate values.
    Returns
        n, mu_S:
            n: Amount of component in gas mixture, in units of mol molecule / mole atoms.
               To obtain units of atom%, n_atom_pc = [100 * a[i] * n_i for i, n_i in enumerate(n)]
            mu_S: Chemical potential of gas mixture in J mol-1
    """
    def vprint(*args):
        if verbose:
            for arg in args:
                print arg,
        else:
            pass

    from scipy.constants import R
        
    a = np.array(a)
    vprint("mu values: ", potentials, "J mol-1\n")
    vprint("RT = {0} J mol-1\n".format(R*T))
    vprint("mu / RT: ", np.array(potentials)/(R*T), '\n')
    # Form empty polynomial
    poly = [0]*(max(a)+1)
    poly[0] = -P
    for i, ai in enumerate(a):
        poly[ai] += np.exp((-potentials[i])/(R*T))
    poly.reverse()
    vprint("terms of polynomial: " + str(poly) + '\n')
        
    roots = scipy.roots(poly)
    good_root = False
    for root in roots:
        if root == root.real and root >= 0 :
            good_root = root
    
    # Root = exp(lambda/RT)
    lam = np.log(good_root.real) * R * T
    vprint("Lagrange multiplier = free energy/atom =  {0}\n".format(lam))
    mu_S = lam
    
    # Now to recover n values
    vprint("P=", P, "T=", T, "a=",a, '\n')

    phi = np.exp((a*lam - potentials)/(R*T))
    vprint(phi)
    b = 1.         # 1 mole of S atoms basis
    n = b * phi / (sum(a*phi))
    return n, mu_S
Ejemplo n.º 12
0
 def S_eq(self,T,P):
     c0,c1,c2 = self.c_factors(T)
     coeff = [c2, c1, c0-np.log(P)]
     S = np.real(sp.roots(coeff))
     S_temp = S[S>=0.0]
     S_out = S_temp[S_temp<200]
     if len(S_out)==0:
         S_out = 0.0
     return S_out/self.S_multiply[self.S_unit]
Ejemplo n.º 13
0
def R_of_l(V, l):
    '''
    radius of a spherocylinder with segment length l, such that
    total volume is V.
    '''
    R = scipy.roots([(4.0 / 3.0) * np.pi, np.pi * l, 0.0, -V])
    R_phys = np.real(R[np.logical_and(np.isreal(R), R > 0.0)])
    if len(R_phys) != 1:
        raise Exception('More or less than one physical radius found')
    return R_phys[0]
    def calculate_time_to_collision_single(self, other_particle):
        """
        Find the time until this particle will intersect with other_particle
        using linear extrapolation.

        This is done by analytically solving the equation
        (s_1 - s_2) ** 2 = (r_1 +- r_2) ** 2, which is the point where both
        circles make contact.

        The - in the right hand side of the equation is there for the case where
        one of the circles is currently inside the other.

        Arguments:
            other_particle: another Particle object.

        Returns: a float representing the time until these objects
                 intersect, or NaN if these particles are not on a
                 (future) collision trajectory.
        """

        # Calculate all of the coefficients.
        velocity_diff = self._velocity - other_particle.get_current_velocity()
        position_diff = self._position - other_particle.get_current_position()

        dt_sq_coefficient = sp.dot(velocity_diff, velocity_diff)
        dt_coefficient = 2 * sp.dot(position_diff, velocity_diff)
        constant_coefficient_lhs = sp.dot(position_diff, position_diff)

        # (R1 +- R2) ** 2
        if self.intersects(other_particle):
            rhs = (self._radius - other_particle._radius)**2
        else:
            rhs = (self._radius + other_particle._radius)**2

        constant_coefficient = constant_coefficient_lhs - rhs

        discriminant = dt_coefficient ** 2 \
                       - (4 * dt_sq_coefficient * constant_coefficient)

        if discriminant < 0:
            return sp.nan

        #sqrt_discriminant = sp.sqrt(discriminant)

        roots = sp.roots(
            [dt_sq_coefficient, dt_coefficient, constant_coefficient])

        if sp.any(roots > Particle.tol):

            # We're only interested in the first collision, that has a dt which
            # is greater than zero, so return the smallest positive root:
            return min(root for root in roots if root > Particle.tol)

        return sp.nan
Ejemplo n.º 15
0
def vanderwaals(
    phase,
    pore_P="pore.pressure",
    pore_T="pore.temperature",
    pore_Pc="pore.critical_pressure",
    pore_Tc="pore.critical_temperature",
    **kwargs
):
    r"""
    Uses Van der Waals equation of state to calculate the density of a real gas

    Parameters
    ----------
    pore_P : string
        The dictionary key containing the pressure values in Pascals (Pa)

    pore_T : string
        The dictionary key containing the temperature values in Kelvin (K)

    pore_Pc : string
        The dictionary key containing the critical pressure values in Pascals
        (Pa)

    pore_Tc : string
        The dictionary key containing the critical temperature values in Kelvin
        (K)

    Returns
    -------
    rho, the density in [mol/m3]

    Notes
    -----
    This equation and its constant coefficients are taken [1]_ which uses the
    cgs units system. All input parameters are expected in SI, then converted
    in the method.

    """

    P = phase[pore_P] / 100000
    T = phase[pore_T]
    Pc = phase[pore_Pc] / 100000  # convert to bars
    Tc = phase[pore_Tc]
    R = 83.1447
    a = 27 * (R ** 2) * (Tc ** 2) / (64 * Pc)
    b = R * Tc / (8 * Pc)
    a1 = -1 / b
    a2 = (R * T + b * P) / (a * b)
    a3 = -P / (a * b)
    a0 = sp.ones(sp.shape(a1))
    coeffs = sp.vstack((a0, a1, a2, a3)).T
    density = sp.array([sp.roots(C) for C in coeffs])
    value = sp.real(density[:, 2]) * 1e6  # Convert it to mol/m3
    return value
Ejemplo n.º 16
0
 def Z(self,t,p): # we pass p because in this case the pressure is the independent variable hence we don't use self.p
     #Z3+AZ2+BZ+C=0
     eps = self.typeeos.epsilon
     sig = self.typeeos.sigma
     pb = (p*self.b)/(self.r*t)
     ap = (p*self.a*self.alpha(t))/((self.r*t)**2)
     A = (eps+sig-1)*pb -1
     B= sig*eps*(pb**2)-(sig+eps)*(pb**2)-(sig+eps)*pb+ap
     C= -sig*eps*pb**3-sig*eps*pb**2-ap*pb
     roots = scipy.roots([1.0,A,B,C]) # gives all roots, even complex ones
     roots = [x.real for x in roots if abs(x.imag) < 1e-16] #.real and .imag are keywords coded in python
     return roots
Ejemplo n.º 17
0
def complex_basins(func, dfunc, coeffs, interval, npoints):
    """Plot func over the complex interval and the
    basins of attraction with npoints resolution"""

    seeds = sp.zeros((2, npoints, npoints), dtype='complex128')
    seeds[0:,:,] = sp.ones((npoints, 1))*sp.linspace(interval[0], interval[1], npoints)
    seeds[0:,:,] = seeds[0:,:,] + 1j*seeds[0:,:,]

    colors = pyplot.cm.colors.cnames.keys()
    colors.remove('black')
    clen = len(colors)
    for i in xrange(npoints):
        for j in xrange(npoints):
            seeds[1,i,j] = newton(func, dfunc, seeds[0,i,j])

    #return seeds
    #find the unique roots of seed values
    roots, indices = sp.unique(seeds[1])
    #for each root, associate a color
    col = sp.zeros_like(roots.shape)

    for i in range(len(roots)):
        col[i] = colors.pop(sp.random.randint(clen))



    #seeds[1] = newtonv(func, )

    #set the color for each
    #tol = 1e-7
    #valcol = [[]]
    #for valx in range(npoints):
        #for valy in range(npoints):
            #if valx and valy == 0:
                #valcol.append(colors[0])
                #continue
            #if not(abs(seeds[1,valx,valy]-seeds[1,valx,valy-1]) <= tol):
                #valcol.append(colors.pop(sp.random.randint(1,len(colors))))
            #else:
                #valcol.append(valcol[0][0])

    #for col in range(npoints):
        #for col1 in range(npoints):
            #pyplot.plot(seeds[0,col,col1], seeds[1,col,col1], marker=',', color=valcol[col][col1])

    tol = 1e-07
    roots = sp.roots(coeffs)
    pyplot.hold(True)
    #for i in range(len(roots)):
        #pyplot.plot(seeds[abs(seeds[1:,:,]-roots[i])<tol], color=colors.pop(sp.random.randint(len(colors))), linestyle='None', marker='.')
    pyplot.pcolor(seeds[0], seeds[1])
    pyplot.hold(False)
    pyplot.show()
Ejemplo n.º 18
0
    def calculo(self):
        entrada = self.kwargs["entrada"]
        self.rendimientoCalculado = Dimensionless(self.kwargs["rendimiento"])

        if self.kwargs["Pout"]:
            DeltaP = Pressure(self.kwargs["Pout"] - entrada.P)
        elif self.kwargs["deltaP"]:
            DeltaP = Pressure(self.kwargs["deltaP"])
        elif self.kwargs["Carga"]:
            DeltaP = Pressure(self.kwargs["Carga"] * entrada.Liquido.rho * g)
        else:
            DeltaP = Pressure(0)

        if self.kwargs["usarCurva"]:
            b1 = self.kwargs["diametro"] != self.kwargs["curvaCaracteristica"][
                0]  # noqa
            b2 = self.kwargs["velocidad"] != self.kwargs[
                "curvaCaracteristica"][1]  # noqa
            if b1 or b2:
                self.curvaActual = self.calcularCurvaActual()
            else:
                self.curvaActual = self.kwargs["curvaCaracteristica"]
            self.Ajustar_Curvas_Caracteristicas()

        if not self.kwargs["usarCurva"]:
            head = Length(DeltaP / g / entrada.Liquido.rho)
            power = Power(head * g * entrada.Liquido.rho * entrada.Q /
                          self.rendimientoCalculado)
            P_freno = Power(power * self.rendimientoCalculado)
        elif not self.kwargs["incognita"]:
            head = Length(polyval(self.CurvaHQ, entrada.Q))
            DeltaP = Pressure(head * g * entrada.Liquido.rho)
            power = Power(entrada.Q * DeltaP)
            P_freno = Power(polyval(self.CurvaPotQ, entrada.Q))
            self.rendimientoCalculado = Dimensionless(power / P_freno)
        else:
            head = Length(self.DeltaP / g / entrada.Liquido.rho)
            poli = [self.CurvaHQ[0], self.CurvaHQ[1], self.CurvaHQ[2] - head]
            Q = roots(poli)[0]
            power = Power(Q * self.DeltaP)
            entrada = entrada.clone(split=Q / entrada.Q)
            P_freno = Power(polyval(self.CurvaPotQ, Q))
            self.rendimientoCalculado = Dimensionless(power / P_freno)

        self.deltaP = DeltaP
        self.headCalculada = head
        self.power = power
        self.P_freno = P_freno
        self.salida = [entrada.clone(P=entrada.P + DeltaP)]
        self.Pin = entrada.P
        self.PoutCalculada = self.salida[0].P
        self.volflow = entrada.Q
        self.cp_cv = entrada.Liquido.cp_cv
Ejemplo n.º 19
0
 def getOmegas(self, typeeos, OmegaB = False):
     acc = self.acc
     if typeeos in ['srk']:
         OmegaC = 0.0
         onethird = 1.0/3.0
         OmegaB = onethird*(2**onethird-1)
         OmegaD = OmegaB + 0.0
         OmegaA = onethird**2/(2**onethird-1)
     elif typeeos == 'pr':
         OmegaB = 0.077796 
         OmegaA = 0.457235
         OmegaC = OmegaB + 0.0
         OmegaD = OmegaB + 0.0
     elif typeeos == 'pt':
         Zc = 0.3272 - 0.0537*acc - 0.0147*acc**2 #Note: NOT experimental Zc!
         A = 1.0
         B = 2 - 3*Zc
         C = 3*Zc**2
         D = -Zc**3
         rts = scipy.roots([A, B, C, D])
         OmegaB = min([r.real for r in rts if (r.real > 0.0) and (abs(r.imag) < 1e-9)])
         OmegaD = OmegaB + 0.0
         OmegaC = 1 - 3*Zc
         OmegaA = 3*Zc**2 + OmegaB*OmegaC + OmegaC*OmegaD + OmegaB*OmegaD + OmegaC + OmegaD
     elif typeeos in  ['hkm2']:
         Zc = 0.3175 - 0.0364*acc -0.0245*acc**2  #Note: NOT experimental Zc!
         A = 1.0
         B = 1.25 - 3*Zc
         C = 3*Zc**2 - 1.5*Zc + 0.5
         D = -Zc**3
         rts = scipy.roots([A, B, C, D])
         OmegaB = min([r.real for r in rts if (r.real > 0.0) and (abs(r.imag) < 1e-9)])
         OmegaE = 6*Zc - 3*OmegaB - 2
         OmegaA = 3*Zc**2 - 0.5*OmegaB**2 - 0.75*OmegaB*OmegaE - 0.5*(OmegaB+OmegaE)
         n = -0.5; m = -0.5
         nbplusme = n*OmegaB + m*OmegaE
         nbme = n*OmegaB*m*OmegaE
         OmegaD = 0.5*(nbplusme - scipy.sqrt(nbplusme**2+4*nbme))
         OmegaC = -nbme/OmegaD
     return OmegaA, OmegaB, OmegaC, OmegaD
Ejemplo n.º 20
0
def vanderwaals(phase,
                pore_P='pore.pressure',
                pore_T='pore.temperature',
                pore_Pc='pore.critical_pressure',
                pore_Tc='pore.critical_temperature',
                **kwargs):
    r"""
    Uses Van der Waals equation of state to calculate the density of a real gas

    Parameters
    ----------
    pore_P : string
        The dictionary key containing the pressure values in Pascals (Pa)

    pore_T : string
        The dictionary key containing the temperature values in Kelvin (K)

    pore_Pc : string
        The dictionary key containing the critical pressure values in Pascals
        (Pa)

    pore_Tc : string
        The dictionary key containing the critical temperature values in Kelvin
        (K)

    Returns
    -------
    rho, the density in [mol/m3]

    Notes
    -----
    This equation and its constant coefficients are taken [1]_ which uses the
    cgs units system. All input parameters are expected in SI, then converted
    in the method.

    """

    P = phase[pore_P] / 100000
    T = phase[pore_T]
    Pc = phase[pore_Pc] / 100000  # convert to bars
    Tc = phase[pore_Tc]
    R = 83.1447
    a = 27 * (R**2) * (Tc**2) / (64 * Pc)
    b = R * Tc / (8 * Pc)
    a1 = -1 / b
    a2 = (R * T + b * P) / (a * b)
    a3 = -P / (a * b)
    a0 = sp.ones(sp.shape(a1))
    coeffs = sp.vstack((a0, a1, a2, a3)).T
    density = sp.array([sp.roots(C) for C in coeffs])
    value = sp.real(density[:, 2]) * 1e6  # Convert it to mol/m3
    return value
Ejemplo n.º 21
0
def complex_basins(func, dfunc, coeffs, interval, npoints):
    """Plot func over the complex interval and the
    basins of attraction with npoints resolution"""

    seeds = sp.zeros((2, npoints, npoints), dtype='complex128')
    seeds[0:, :, ] = sp.ones(
        (npoints, 1)) * sp.linspace(interval[0], interval[1], npoints)
    seeds[0:, :, ] = seeds[0:, :, ] + 1j * seeds[0:, :, ]

    colors = pyplot.cm.colors.cnames.keys()
    colors.remove('black')
    clen = len(colors)
    for i in xrange(npoints):
        for j in xrange(npoints):
            seeds[1, i, j] = newton(func, dfunc, seeds[0, i, j])

    #return seeds
    #find the unique roots of seed values
    roots, indices = sp.unique(seeds[1])
    #for each root, associate a color
    col = sp.zeros_like(roots.shape)

    for i in range(len(roots)):
        col[i] = colors.pop(sp.random.randint(clen))

    #seeds[1] = newtonv(func, )

    #set the color for each
    #tol = 1e-7
    #valcol = [[]]
    #for valx in range(npoints):
    #for valy in range(npoints):
    #if valx and valy == 0:
    #valcol.append(colors[0])
    #continue
    #if not(abs(seeds[1,valx,valy]-seeds[1,valx,valy-1]) <= tol):
    #valcol.append(colors.pop(sp.random.randint(1,len(colors))))
    #else:
    #valcol.append(valcol[0][0])

    #for col in range(npoints):
    #for col1 in range(npoints):
    #pyplot.plot(seeds[0,col,col1], seeds[1,col,col1], marker=',', color=valcol[col][col1])

    tol = 1e-07
    roots = sp.roots(coeffs)
    pyplot.hold(True)
    #for i in range(len(roots)):
    #pyplot.plot(seeds[abs(seeds[1:,:,]-roots[i])<tol], color=colors.pop(sp.random.randint(len(colors))), linestyle='None', marker='.')
    pyplot.pcolor(seeds[0], seeds[1])
    pyplot.hold(False)
    pyplot.show()
Ejemplo n.º 22
0
def vanderwaals(target,
                pressure='pore.pressure',
                temperature='pore.temperature',
                critical_pressure='pore.critical_pressure',
                critical_temperature='pore.critical_temperature'):
    r"""
    Uses Van der Waals equation of state to calculate the density of a real gas

    Parameters
    ----------
    target : OpenPNM Object
        The object for which these values are being calculated.  This
        controls the length of the calculated array, and also provides
        access to other necessary thermofluid properties.

    pressure : string
        The dictionary key containing the pressure values in Pascals (Pa)

    temperature : string
        The dictionary key containing the temperature values in Kelvin (K)

    critical_pressure : string
        The dictionary key containing the critical pressure values in Pascals
        (Pa)

    critical_temperature : string
        The dictionary key containing the critical temperature values in Kelvin
        (K)

    Returns
    -------
    value : NumPy ndarray
        Array containing molar density values [mol/m3]

    """

    P = target[pressure] / 100000
    T = target[temperature]
    Pc = target[critical_pressure] / 100000  # convert to bars
    Tc = target[critical_temperature]
    R = 83.1447
    a = 27 * (R**2) * (Tc**2) / (64 * Pc)
    b = R * Tc / (8 * Pc)
    a1 = -1 / b
    a2 = (R * T + b * P) / (a * b)
    a3 = -P / (a * b)
    a0 = sp.ones(sp.shape(a1))
    coeffs = sp.vstack((a0, a1, a2, a3)).T
    density = sp.array([sp.roots(C) for C in coeffs])
    value = sp.real(density[:, 2]) * 1e6  # Convert it to mol/m3
    return value
Ejemplo n.º 23
0
    def calculo(self):
        entrada = self.kwargs["entrada"]
        self.rendimientoCalculado = Dimensionless(self.kwargs["rendimiento"])

        if self.kwargs["Pout"]:
            DeltaP = Pressure(self.kwargs["Pout"]-entrada.P)
        elif self.kwargs["deltaP"]:
            DeltaP = Pressure(self.kwargs["deltaP"])
        elif self.kwargs["Carga"]:
            DeltaP = Pressure(self.kwargs["Carga"]*entrada.Liquido.rho*g)
        else:
            DeltaP = Pressure(0)

        if self.kwargs["usarCurva"]:
            b1 = self.kwargs["diametro"] != self.kwargs["curvaCaracteristica"][0]  # noqa
            b2 = self.kwargs["velocidad"] != self.kwargs["curvaCaracteristica"][1]  # noqa
            if b1 or b2:
                self.curvaActual = self.calcularCurvaActual()
            else:
                self.curvaActual = self.kwargs["curvaCaracteristica"]
            self.Ajustar_Curvas_Caracteristicas()

        if not self.kwargs["usarCurva"]:
            head = Length(DeltaP/g/entrada.Liquido.rho)
            power = Power(head*g*entrada.Liquido.rho*entrada.Q /
                          self.rendimientoCalculado)
            P_freno = Power(power*self.rendimientoCalculado)
        elif not self.kwargs["incognita"]:
            head = Length(polyval(self.CurvaHQ, entrada.Q))
            DeltaP = Pressure(head*g*entrada.Liquido.rho)
            power = Power(entrada.Q*DeltaP)
            P_freno = Power(polyval(self.CurvaPotQ, entrada.Q))
            self.rendimientoCalculado = Dimensionless(power/P_freno)
        else:
            head = Length(self.DeltaP/g/entrada.Liquido.rho)
            poli = [self.CurvaHQ[0], self.CurvaHQ[1], self.CurvaHQ[2]-head]
            Q = roots(poli)[0]
            power = Power(Q*self.DeltaP)
            entrada = entrada.clone(split=Q/entrada.Q)
            P_freno = Power(polyval(self.CurvaPotQ, Q))
            self.rendimientoCalculado = Dimensionless(power/P_freno)

        self.deltaP = DeltaP
        self.headCalculada = head
        self.power = power
        self.P_freno = P_freno
        self.salida = [entrada.clone(P=entrada.P+DeltaP)]
        self.Pin = entrada.P
        self.PoutCalculada = self.salida[0].P
        self.volflow = entrada.Q
        self.cp_cv = entrada.Liquido.cp_cv
Ejemplo n.º 24
0
 def getPborder(self,t): # this is used to get V where the dP/dv = 0. the input equation is the differentiated equation
     e = self.typeeos.epsilon
     s= self.typeeos.sigma
     A= -self.r*t*(self.b*self.typeeos.epsilon-self.typeeos.sigma)
     B = self.a*self.alpha(t)
     b = self.b
     C = -1
     a5 =A*b**4*e**2*s**2 + B*b**4*e**2 + C*b**4*s**2 
     a1 = (A + B + C)
     a2 = 2*A*b*e + 2*A*b*s + 2*B*b*e - 2*B*b + 2*C*b*s - 2*C*b
     a3 = A*b**2*e**2 + 4*A*b**2*e*s + A*b**2*s**2 + B*b**2*e**2 - 4*B*b**2*e + B*b**2 + C*b**2*s**2 - 4*C*b**2*s + C*b**2
     a4 = (2*A*b**3*e**2*s + 2*A*b**3*e*s**2 - 2*B*b**3*e**2 + 2*B*b**3*e - 2*C*b**3*s**2 + 2*C*b**3*s)
     vsol = scipy.roots([a1,a2,a3,a4,a5])
     return vsol
Ejemplo n.º 25
0
    def LGR(self,figura):
        """
        Função para traçado do Lugar Geométrico das Raízes
        
        kvect: Vetor dos ganhos;
        figura: referência a uma figura do Matplotlib.
        
        O LGR é traçado sempre com ganho K = 1.
        """

        num = self.polyDnum
        den = self.polyDden
        
        # Criando vetor de ganhos (sem os pontos críticos).
        # Kmin, Kmax e numero de pontos são atributos desta classe.
        delta_k = (self.Kmax-self.Kmin) / self.Kpontos
        kvect = numpy.arange(self.Kmin,self.Kmax,delta_k)
        
        # Geracao dos pontos de separacao
        # Fazendo d(-1/G(s))/ds = 0
        deriv = scipy.polyder(den)*num - scipy.polyder(num)*den
        cpss = scipy.roots(deriv) # candidatos a ponto de separacao
        # Verificacao de quais os candidatos pertinentes
        for raiz in cpss:		
            aux = num(raiz)
            if aux != 0:
                Kc = -den(raiz) / num(raiz)
                if (numpy.isreal(Kc)) and (Kc <= self.Kmax) and (Kc >= self.Kmin):
                        kvect = numpy.append(kvect,Kc)
        # Reordena o kvect:
        kvect = numpy.sort(kvect);
        
        # Calculate the roots:
        root_vector = MyRootLocus(num,den,kvect)
        
        # Ploting:
        figura.clf()
        ax = figura.add_subplot(111)
        # Open loop poles:
        poles = numpy.array(den.r)
        ax.plot(numpy.real(poles), numpy.imag(poles), 'x')
        # Open loop zeros:
        zeros = numpy.array(num.r)
        if zeros.any():
            ax.plot(numpy.real(zeros), numpy.imag(zeros), 'o')
        for col in root_vector.T:
            # Ploting the root locus.
            ax.plot(numpy.real(col), numpy.imag(col), '-')
        
        return root_vector
Ejemplo n.º 26
0
    def LGR(self,figura):
        """
        Função para traçado do Lugar Geométrico das Raízes
        
        kvect: Vetor dos ganhos;
        figura: referência a uma figura do Matplotlib.
        
        O LGR é traçado sempre com ganho K = 1.
        """

        num = self.polyDnum
        den = self.polyDden
        
        # Criando vetor de ganhos (sem os pontos críticos).
        # Kmin, Kmax e numero de pontos são atributos desta classe.
        delta_k = (self.Kmax-self.Kmin) / self.Kpontos
        kvect = numpy.arange(self.Kmin,self.Kmax,delta_k)
        
        # Geracao dos pontos de separacao
        # Fazendo d(-1/G(s))/ds = 0
        deriv = scipy.polyder(den)*num - scipy.polyder(num)*den
        cpss = scipy.roots(deriv) # candidatos a ponto de separacao
        # Verificacao de quais os candidatos pertinentes
        for raiz in cpss:		
            aux = num(raiz)
            if aux != 0:
                Kc = -den(raiz) / num(raiz)
                if (numpy.isreal(Kc)) and (Kc <= self.Kmax) and (Kc >= self.Kmin):
                        kvect = numpy.append(kvect,Kc)
        # Reordena o kvect:
        kvect = numpy.sort(kvect);
        
        # Calculate the roots:
        root_vector = MyRootLocus(num,den,kvect)
        
        # Ploting:
        figura.clf()
        ax = figura.add_subplot(111)
        # Open loop poles:
        poles = numpy.array(den.r)
        ax.plot(numpy.real(poles), numpy.imag(poles), 'x')
        # Open loop zeros:
        zeros = numpy.array(num.r)
        if zeros.any():
            ax.plot(numpy.real(zeros), numpy.imag(zeros), 'o')
        for col in root_vector.T:
            # Ploting the root locus.
            ax.plot(numpy.real(col), numpy.imag(col), '-')
        
        return root_vector
Ejemplo n.º 27
0
def vanderwaals(target, pressure='pore.pressure',
                temperature='pore.temperature',
                critical_pressure='pore.critical_pressure',
                critical_temperature='pore.critical_temperature'):
    r"""
    Uses Van der Waals equation of state to calculate the density of a real gas

    Parameters
    ----------
    target : OpenPNM Object
        The object for which these values are being calculated.  This
        controls the length of the calculated array, and also provides
        access to other necessary thermofluid properties.

    pressure : string
        The dictionary key containing the pressure values in Pascals (Pa)

    temperature : string
        The dictionary key containing the temperature values in Kelvin (K)

    critical_pressure : string
        The dictionary key containing the critical pressure values in Pascals
        (Pa)

    critical_temperature : string
        The dictionary key containing the critical temperature values in Kelvin
        (K)

    Returns
    -------
    value : NumPy ndarray
        Array containing molar density values [mol/m3]

    """

    P = target[pressure]/100000
    T = target[temperature]
    Pc = target[critical_pressure]/100000  # convert to bars
    Tc = target[critical_temperature]
    R = 83.1447
    a = 27*(R**2)*(Tc**2)/(64*Pc)
    b = R*Tc/(8*Pc)
    a1 = -1/b
    a2 = (R*T+b*P)/(a*b)
    a3 = -P/(a*b)
    a0 = sp.ones(sp.shape(a1))
    coeffs = sp.vstack((a0, a1, a2, a3)).T
    density = sp.array([sp.roots(C) for C in coeffs])
    value = sp.real(density[:, 2])*1e6  # Convert it to mol/m3
    return value
def low_accuracy_recompute_alpha_varying_fields(
        sph_start, sph_end, t_start, t_end, mag_params):
    """
    Compute effective damping from change in magnetisation and change in
    applied field.

    From Nonlinear magnetization dynamics in nanosystems eqn (2.15).

    See notes 30/7/13.

    Derivatives are estimated using BDF1 finite differences.
    """

    # Only for normalised problems!
    assert(mag_params.Ms == 1)

    # Get some values
    dt = t_end - t_start
    m_cart_end = utils.sph2cart(sph_end)
    h_eff_end = heff(mag_params, t_end, m_cart_end)
    mxh = sp.cross(m_cart_end, h_eff_end)

    # Finite difference derivatives
    dhadt = (mag_params.Hvec(t_start) - mag_params.Hvec(t_end))/dt

    assert(all(dhadt == 0))  # no field for now

    dedt = (llg_state_energy(sph_end, mag_params, t_end)
            - llg_state_energy(sph_start, mag_params, t_start)
            )/dt

    sigma = sp.dot(mxh, mxh) / (dedt + sp.dot(m_cart_end, dhadt))

    possible_alphas = sp.roots([1, sigma, 1])

    a = (-sigma + sqrt(sigma**2 - 4))/2
    b = (-sigma - sqrt(sigma**2 - 4))/2

    possible_alphas2 = [a, b]
    utils.assert_list_almost_equal(possible_alphas, possible_alphas2)

    print(sigma, possible_alphas)

    def real_and_positive(x):
        return sp.isreal(x) and x > 0

    alphas = filter(real_and_positive, possible_alphas)
    assert(len(alphas) == 1)
    return sp.real(alphas[0])
Ejemplo n.º 29
0
 def getvborder(self, T, alpha = False):
     if not alpha:
         alpha = self.alpha(T)
     RT = self.R*T
     a, b, c, d = self.a*alpha, self.b, self.c, self.d
     a4 = -1.0
     a3 = -2*(c+d) + 2*a/RT
     a2 = -c**2 - d**2 - 4*a*b/RT + a*c/RT + a*d/RT
     a1 = 2*c**2*d + 2*c*d**2 + 2*a*b**2/RT - 2*a*b*c/RT - 2*a*b*d/RT
     a0 = -c**2*d**2 + a*b**2*c/RT + a*b**2*d/RT
     roots = scipy.roots([a4.real, a3.real, a2.real, a1.real, a0.real])
     roots = [x.real for x in roots if abs(x.imag) < 1e-16 and x.real > b]
     if len(roots) == 2:
         vborder = [roots[0], roots[1]]
         return True, min(vborder), max(vborder)
     else:
         return False, None, None
Ejemplo n.º 30
0
 def Z(self, T, P, alpha = False):
     P = 1e-20 if P == 0.0 else P
     if not alpha:
         alpha = self.alpha(T)
     PRT = P/(self.R*T)
     a, b, c, d = self.a*alpha, self.b, self.c, self.d
     A = PRT*(c + d - b) - 1
     B = PRT**2*(a/P - b*c - c*d - d*b) - PRT*(c+d)
     C = PRT**3*(b*c*d+c*d/PRT-a*b/P)
     roots = scipy.roots([1, A.real, B.real, C.real])
     roots = [x.real for x in roots if abs(x.imag) < 1e-16]
     if len(roots) == 3:
         return [min(roots), max(roots)]
     elif len(roots) == 1:
         return [roots[0]]
     else:
         return []            
Ejemplo n.º 31
0
 def Z(self, T, P, alpha=False):
     P = 1e-20 if P == 0.0 else P
     if not alpha:
         alpha = self.alpha(T)
     PRT = P / (self.R * T)
     a, b, c, d = self.a * alpha, self.b, self.c, self.d
     A = PRT * (c + d - b) - 1
     B = PRT**2 * (a / P - b * c - c * d - d * b) - PRT * (c + d)
     C = PRT**3 * (b * c * d + c * d / PRT - a * b / P)
     roots = scipy.roots([1, A.real, B.real, C.real])
     roots = [x.real for x in roots if abs(x.imag) < 1e-16]
     if len(roots) == 3:
         return [min(roots), max(roots)]
     elif len(roots) == 1:
         return [roots[0]]
     else:
         return []
Ejemplo n.º 32
0
 def getvborder(self, T, alpha=False):
     if not alpha:
         alpha = self.alpha(T)
     RT = self.R * T
     a, b, c, d = self.a * alpha, self.b, self.c, self.d
     a4 = -1.0
     a3 = -2 * (c + d) + 2 * a / RT
     a2 = -c**2 - d**2 - 4 * a * b / RT + a * c / RT + a * d / RT
     a1 = 2 * c**2 * d + 2 * c * d**2 + 2 * a * b**2 / RT - 2 * a * b * c / RT - 2 * a * b * d / RT
     a0 = -c**2 * d**2 + a * b**2 * c / RT + a * b**2 * d / RT
     roots = scipy.roots([a4.real, a3.real, a2.real, a1.real, a0.real])
     roots = [x.real for x in roots if abs(x.imag) < 1e-16 and x.real > b]
     if len(roots) == 2:
         vborder = [roots[0], roots[1]]
         return True, min(vborder), max(vborder)
     else:
         return False, None, None
Ejemplo n.º 33
0
    def __lib(self, cmp, T):
        Tr = T / cmp.Tc

        if cmp.id in dat:
            Xc, m, p, d = dat[cmp.id]
        else:
            Zc = cmp.Pc.kPa * cmp.Vc * cmp.M / R / cmp.Tc

            d = cmp.Vc.ccg * cmp.M / 3  # Eq 11
            Xc = 1.063 * Zc  # Eq 12

            # Eq 13
            m = 0.662 + 3.12 * cmp.f_acent - 0.854 * cmp.f_acent**2 + 9.3 * (
                Zc - 0.3)

            if cmp.M <= 128:
                p = 0.475 + 2 * cmp.f_acent  # Eq 14a
            else:
                p = 0.613 + 0.62 * cmp.f_acent + 4.06 * cmp.f_acent**2  # Eq 14b

        alfa = 1 + m * (1 - Tr**0.5) + p * (0.7**0.5 - Tr**0.5) * (1 - Tr**0.5)

        # From here common functionality of original TB EoS
        # Convert d from cc/mol to m3/mol
        d /= 1e6

        Cc = 1 - 3 * Xc  # Eq 6
        Dc = d * cmp.Pc / R / cmp.Tc  # Eq 12

        # Bc calculated ad the smallest positive root of Eq 8
        B = roots([1, 2 - 3 * Xc, 3 * Xc**2, -Dc**2 - Xc**3])
        Bpositivos = []
        for Bi in B:
            if Bi > 0:
                Bpositivos.append(Bi)
        Bc = min(Bpositivos)

        Ac = 3 * Xc**2 + 2 * Bc * Cc + Bc + Cc + Bc**2 + Dc**2  # Eq 7
        ac = Ac * R**2 * cmp.Tc**2 / cmp.Pc
        a = ac * alfa  # Eq 23

        b = Bc * R * cmp.Tc / cmp.Pc
        c = R * cmp.Tc / cmp.Pc * (1 - 3 * Xc)  # Eq 10

        return a, b, c, d
Ejemplo n.º 34
0
    def tmin(self, r, z, trace=False):
        """Calculates and returns the s value along the norm vector
        which minimizes the distance from the ray to a circle defined by
        input (r,z). 

        Args:
            r: value, iterable or scipy.array, radius in meters 
            
            z: value, iterable or scipy.array, z value in meters
        
        Kwargs:
            trace: bool if set true, the ray is assumed to be traced within a
            tokamak.  A further evaluation reduces the value to one within
            the bounds of the vacuum vessel/limiter.

        Returns:
            numpy array of s values in meters
        """
        r = scipy.atleast_1d(r)
        z = scipy.atleast_1d(z)
        params = _beam.lineCirc(self(0).x(),
                                self.norm.unit,
                                r,
                                z)

        sout = scipy.zeros(r.shape)

        for i in xrange(len(params)):
            temp = scipy.roots(params[i])

            # only positive real solutions are taken
            temp = temp[scipy.imag(temp) == 0]
            temp = scipy.real(temp[temp > 0])

            test = self(temp).r()
            
            # must decide between local and global minima
            sout[i] = temp[((test[0]-r[i])**2 
                            + (test[2] - z[i])**2).argmin()]
            
            if trace and ((sout[i] > self.norm.s[-1]) or (sout[i] < self.norm.s[-2])):
                #need to implement this such that it searches only in area of interest
                sout[i] = None

        return sout
Ejemplo n.º 35
0
    def tmin(self, r, z, trace=False):
        """Calculates and returns the s value along the norm vector
        which minimizes the distance from the ray to a circle defined by
        input (r,z). 

        Args:
            r: value, iterable or scipy.array, radius in meters 
            
            z: value, iterable or scipy.array, z value in meters
        
        Kwargs:
            trace: bool if set true, the ray is assumed to be traced within a
            tokamak.  A further evaluation reduces the value to one within
            the bounds of the vacuum vessel/limiter.

        Returns:
            numpy array of s values in meters
        """
        r = scipy.atleast_1d(r)
        z = scipy.atleast_1d(z)
        params = _beam.lineCirc(self(0).x(), self.norm.unit, r, z)

        sout = scipy.zeros(r.shape)

        for i in range(len(params)):
            temp = scipy.roots(params[i])

            # only positive real solutions are taken
            temp = temp[scipy.imag(temp) == 0]
            temp = scipy.real(temp[temp > 0])

            test = self(temp).r()

            # must decide between local and global minima
            sout[i] = temp[((test[0] - r[i])**2 +
                            (test[2] - z[i])**2).argmin()]

            if trace and ((sout[i] > self.norm.s[-1]) or
                          (sout[i] < self.norm.s[-2])):
                #need to implement this such that it searches only in area of interest
                sout[i] = None

        return sout
Ejemplo n.º 36
0
 def Z(self, T, P):
     R = self.R; a = self.a; b = self.b
     sigma = self.typeEOS.sigma; epsilon = self.typeEOS.epsilon
     alpha = self.alpha(T)
     p_p = P*b/R/T; a_p = P*a*alpha/R**2/T**2
     
     a3 = 1.0
     a2 = epsilon*p_p + p_p*sigma - p_p - 1.0
     a1 = a_p + epsilon*p_p**2*sigma - epsilon*p_p**2 - epsilon*p_p - p_p**2*sigma - p_p*sigma
     a0 = -a_p*p_p - epsilon*p_p**3*sigma - epsilon*p_p**2*sigma
     
     roots = scipy.roots([a3, a2, a1, a0])
     roots = [rt.real for rt in roots if abs(rt.imag) < 1e-16]
     if len(roots) == 3:
         return scipy.array([min(roots), max(roots)])
     elif len(roots) == 1:
         return scipy.array(roots)
     else:
         return []   
Ejemplo n.º 37
0
 def getPborder(self, T):
     a = self.a; b = self.b
     alpha = self.alpha(T)
     R = self.R; s = self.typeEOS.sigma; e = self.typeEOS.epsilon
     A = a*alpha/(s-e)/b/R/T
     
     a4 = 1.0
     a3 = 2*A*b*e - 2*A*b*s + 2*b*e + 2*b*s       
     a2 = A*b**2*e**2 - 4*A*b**2*e - A*b**2*s**2 + 4*A*b**2*s + b**2*e**2 + 4*b**2*e*s + b**2*s**2
     a1 = -2*A*b**3*e**2 + 2*A*b**3*e + 2*A*b**3*s**2 - 2*A*b**3*s + 2*b**3*e**2*s + 2*b**3*e*s**2
     a0 = A*b**4*e**2 - A*b**4*s**2 + b**4*e**2*s**2
     
     roots = scipy.roots([a4, a3, a2, a1, a0])
     roots = [x.real for x in roots if abs(x.imag) < 1e-16 and x.real > b]
     if len(roots) == 2:
         PP = [self.P(T, roots[0]), self.P(T, roots[1])]
         return True, min(PP), max(PP)
     else:
         return False, None, None
Ejemplo n.º 38
0
def dispersion_relation_extraordinary(kx, ky, k, nO, nE, c):
    """Dispersion relation for the extraordinary wave.

    NOTE
    See eq. 16 in Glytsis, "Three-dimensional (vector) rigorous
    coupled-wave analysis of anisotropic grating diffraction",
    JOSA A, 7(8), 1990 Always give positive real or negative
    imaginary.
    """

    if kx.shape != ky.shape or c.size != 3:
        raise ValueError(
            "kx and ky must have the same length and c must have 3 components"
        )

    kz = S.empty_like(kx)

    for ii in range(0, kx.size):

        alpha = nE ** 2 - nO ** 2
        beta = kx[ii] / k * c[0] + ky[ii] / k * c[1]

        # coeffs
        C = S.array(
            [
                nO ** 2 + c[2] ** 2 * alpha,
                2.0 * c[2] * beta * alpha,
                nO ** 2 * (kx[ii] ** 2 + ky[ii] ** 2) / k ** 2
                + alpha * beta ** 2
                - nO ** 2 * nE ** 2,
            ]
        )

        # two solutions of type +x or -x, purely real or purely imag
        tmp_kz = k * S.roots(C)

        # get the negative imaginary part or the positive real one
        if S.any(S.isreal(tmp_kz)):
            kz[ii] = S.absolute(tmp_kz[0])
        else:
            kz[ii] = -1j * S.absolute(tmp_kz[0])

    return kz
Ejemplo n.º 39
0
    def __init__(self, T, P, mezcla):
        self.T=unidades.Temperature(T)
        self.P=unidades.Pressure(P, "atm")
        self.mezcla=mezcla
        self.componente=mezcla.componente
        self.fraccion=mezcla.fraccion

        self.B=self.b*self.P.atm/R_atml/self.T
        self.Tita=self.tita*self.P.atm/(R_atml*self.T)**2

        delta=self.delta*self.P.atm/R_atml/self.T
        epsilon=self.epsilon*(self.P.atm/R_atml/self.T)**2
        eta=self.eta*self.P.atm/R_atml/self.T
        Z=roots([1, delta-self.B-1, self.Tita+epsilon-delta*(self.B+1), -epsilon*(self.B+1)-self.Tita*eta])
        self.Z=r_[Z[0].real, Z[2].real]

        self.V=self.Z*R_atml*self.T/self.P.atm  #mol/l
        self.x, self.xi, self.yi, self.Ki=self._Flash()
        self.H_exc=-(self.tita+self.dTitadT)/R_atml/self.T/(self.delta**2-4*self.epsilon)**0.5*log((2*self.V+self.delta-(self.delta**2-4*self.epsilon)**0.5)/(2*self.V+self.delta+(self.delta**2-4*self.epsilon)**0.5))+1-self.Z
Ejemplo n.º 40
0
def PTC_lib(compuesto, T):
    """Librería de cálculo de la ecuación de estado de Patel-Teja-Crause"""
    if compuesto.Tc!=0 and compuesto.Pc!=0 and compuesto.vc!=0:
        Zc=compuesto.Pc.atm*compuesto.vc*compuesto.peso_molecular/R_atml/compuesto.Tc
    else:
        Zc=0.253168556+0.09253329*exp(-0.0048018*compuesto.peso_molecular)

    c=(1-3*Zc)*R_atml*compuesto.Tc/compuesto.Pc.atm
    omega=roots([1, 2-3*Zc, 3*Zc**2, -Zc**3])
    Bpositivos=[]
    for i in omega:
        if i>0:
            Bpositivos.append(i)
    omegab=min(Bpositivos)
    b=omegab*R_atml*compuesto.Tc/compuesto.Pc.atm

    f=0.002519*compuesto.peso_molecular+0.70647
    alfa=(1+f*(1-sqrt(T/compuesto.Tc)))**2
    omegaa=3*Zc**2+3*(1-2*Zc)*omegab+omegab**2+1-3*Zc
    a=omegaa*R_atml**2*compuesto.Tc**2/compuesto.Pc.atm**2*alfa
    return a, b, c
Ejemplo n.º 41
0
def PTC_lib(compuesto, T):
    """Librería de cálculo de la ecuación de estado de Patel-Teja-Crause"""
    if compuesto.Tc!=0 and compuesto.Pc!=0 and compuesto.vc!=0:
        Zc=compuesto.Pc.atm*compuesto.vc*compuesto.peso_molecular/R_atml/compuesto.Tc
    else:
        Zc=0.253168556+0.09253329*exp(-0.0048018*compuesto.peso_molecular)

    c=(1-3*Zc)*R_atml*compuesto.Tc/compuesto.Pc.atm
    omega=roots([1, 2-3*Zc, 3*Zc**2, -Zc**3])
    Bpositivos=[]
    for i in omega:
        if i>0:
            Bpositivos.append(i)
    omegab=min(Bpositivos)
    b=omegab*R_atml*compuesto.Tc/compuesto.Pc.atm

    f=0.002519*compuesto.peso_molecular+0.70647
    alfa=(1+f*(1-sqrt(T/compuesto.Tc)))**2
    omegaa=3*Zc**2+3*(1-2*Zc)*omegab+omegab**2+1-3*Zc
    a=omegaa*R_atml**2*compuesto.Tc**2/compuesto.Pc.atm**2*alfa
    return a, b, c
Ejemplo n.º 42
0
def PT_lib(compuesto, T):
    """Librería de cálculo de la ecuación de estado de Patel-Teja"""
    if compuesto.Tc != 0 and compuesto.Pc != 0 and compuesto.vc != 0:
        Zc = compuesto.Pc.atm * compuesto.vc * compuesto.peso_molecular / R_atml / compuesto.Tc
    else:
        Zc = 0.329032 + 0.076799 * compuesto.f_acent - 0.0211947 * compuesto.f_acent**2

    c = (1 - 3 * Zc) * R_atml * compuesto.Tc / compuesto.Pc.atm
    omega = roots([1, 2 - 3 * Zc, 3 * Zc**2, -Zc**3])
    Bpositivos = []
    for i in omega:
        if i > 0:
            Bpositivos.append(i)
    omegab = min(Bpositivos)
    b = omegab * R_atml * compuesto.Tc / compuesto.Pc.atm

    f = 0.452413 + 1.30982 * compuesto.f_acent - 0.295937 * compuesto.f_acent**2
    alfa = (1 + f * (1 - sqrt(T / compuesto.Tc)))**2
    omegaa = 3 * Zc**2 + 3 * (1 - 2 * Zc) * omegab + omegab**2 + 1 - 3 * Zc
    a = omegaa * R_atml**2 * compuesto.Tc**2 / compuesto.Pc.atm**2 * alfa
    return a, b, c
Ejemplo n.º 43
0
def PT_lib(compuesto, T):
    """Librería de cálculo de la ecuación de estado de Patel-Teja"""
    if compuesto.Tc!=0 and compuesto.Pc!=0 and compuesto.vc!=0:
        Zc=compuesto.Pc.atm*compuesto.vc*compuesto.peso_molecular/R_atml/compuesto.Tc
    else:
        Zc=0.329032+0.076799*compuesto.f_acent-0.0211947*compuesto.f_acent**2

    c=(1-3*Zc)*R_atml*compuesto.Tc/compuesto.Pc.atm
    omega=roots([1, 2-3*Zc, 3*Zc**2, -Zc**3])
    Bpositivos=[]
    for i in omega:
        if i>0:
            Bpositivos.append(i)
    omegab=min(Bpositivos)
    b=omegab*R_atml*compuesto.Tc/compuesto.Pc.atm

    f=0.452413+1.30982*compuesto.f_acent-0.295937*compuesto.f_acent**2
    alfa=(1+f*(1-sqrt(T/compuesto.Tc)))**2
    omegaa=3*Zc**2+3*(1-2*Zc)*omegab+omegab**2+1-3*Zc
    a=omegaa*R_atml**2*compuesto.Tc**2/compuesto.Pc.atm**2*alfa
    return a, b, c
Ejemplo n.º 44
0
def AproxBessel(Retardo, Wrg, Tol, N=0, Nmin=0, Nmax=15):
    s = sympy.Symbol('s')
    if N == 0:
        #Trato de obtener la funcion de bessel que cumpla con lo pedido
        N = 1
        #Si tengo un valor de Nmin voy a empezar desde ahi
        if Nmin != 0:
            N = Nmin
        while (N < Nmax) and (Nmin <= N):
            Polinomio = PoliBessel(N)
            Tranferencia = Polinomio.subs(s, 0) / Polinomio.subs(s, 1j * Wrg)
            Temp = ((Wrg**(2 * N)) *
                    (abs(Tranferencia)**2)) / (Polinomio.subs(s, 0)**2)
            if (Temp < Tol):
                break
            else:
                N += 1
        #Chequeo para ver si estoy en el Nmax
        if N == Nmax:
            Polinomio = PoliBessel(N)
            print("Se alcanzo el limite")
        elif N == Nmin:
            print("Se alconzo el minimo")
    else:
        Polinomio = PoliBessel(N)
    #obtengo la funcion tranferencia
    Tranferencia = Polinomio.subs(s, 0) / Polinomio
    #Busco los polos
    Num, Den = sympy.fraction(Tranferencia)
    Den_Coef = sympy.Poly(Den)
    Den_Coef = Den_Coef.all_coeffs()
    Polos = scipy.roots(Den_Coef)
    for i in range(len(Polos)):
        Polos[i] = Polos[i]
    #Devuelvo el orden, los polos y la constante
    Num = 1
    return N, Polos, Num
Ejemplo n.º 45
0
    def PontosSeparacao(self):
        """
        Calcula os pontos de separação e retorna só os pertinentes.
        """
        num = self.polyDnum
        den = self.polyDden

        pontos = []        
        ganhos = []
        
        # Geracao dos pontos de separacao
        # Fazendo d(-1/G(s))/ds = 0
        deriv = scipy.polyder(den)*num - scipy.polyder(num)*den
        cpss = scipy.roots(deriv) # candidatos a ponto de separacao
        # Verificacao de quais os candidatos pertinentes
        for raiz in cpss:		
            aux = num(raiz)
            if aux != 0:
                Kc = -den(raiz) / num(raiz)
                if (numpy.isreal(Kc)):# and (Kc <= self.Kmax) and (Kc >= self.Kmin):
                    pontos.append(raiz)
                    ganhos.append(Kc)
        
        return pontos, ganhos
Ejemplo n.º 46
0
def _BOpntsLoc(sys):
    """Breakout point locater
    
    This returns the location of breakout points on the root locus and 
    the associated gains at those locations.
    
    Parameters
    ----------
    sys: StateSpace or TransferFunction
        Linear system
        
    Returns
    -------
    KatBO:
        list of gains at which a breakout point occurs
    BOpnts:
        list of breakout points
    """
    (nump, denp) = _systopoly1d(sys)
    
    # Breakout points potentially occur where N*D' - N'*D = 0
    numpD = polyder(nump)
    denpD = polyder(denp)
    BOpnts = roots((nump*denpD) - (numpD*denp))
    
    # Selects only the Breakout points on the real line
    BOpnts = BOpnts[imag(BOpnts) == 0] 
    
    # Finds gains from breakout points
    fgain = vectorize(lambda s: polyval(-denp,s)/polyval(nump,s))
    KatBO = fgain(BOpnts)
    
    # Selects only the positive gains at the Breakout points
    KatBO = KatBO[KatBO >= 0]

    return KatBO, BOpnts
Ejemplo n.º 47
0
    def PontosSeparacao(self):
        """
        Calcula os pontos de separação e retorna só os pertinentes.
        """
        num = self.polyDnum
        den = self.polyDden

        pontos = []        
        ganhos = []
        
        # Geracao dos pontos de separacao
        # Fazendo d(-1/G(s))/ds = 0
        deriv = scipy.polyder(den)*num - scipy.polyder(num)*den
        cpss = scipy.roots(deriv) # candidatos a ponto de separacao
        # Verificacao de quais os candidatos pertinentes
        for raiz in cpss:		
            aux = num(raiz)
            if aux != 0:
                Kc = -den(raiz) / num(raiz)
                if (numpy.isreal(Kc)):# and (Kc <= self.Kmax) and (Kc >= self.Kmin):
                    pontos.append(raiz)
                    ganhos.append(Kc)
        
        return pontos, ganhos
Ejemplo n.º 48
0
gss1 = ss(A,B,C,D)
gss = ss(A,B,C2,D2)
gz = c2d(gss,ts,'zoh')

# Control design
wn = 10
xi1 = np.sqrt(2)/2 
xi2 = np.sqrt(3)/2 
xi2 = 0.85

cl_p1 = [1,2*xi1*wn,wn**2]
cl_p2 = [1,2*xi2*wn,wn**2]
cl_p3 = [1,wn]
cl_poly1 = sp.polymul(cl_p1,cl_p2)
cl_poly = sp.polymul(cl_poly1,cl_p3)
cl_poles = sp.roots(cl_poly)     # Desired continous poles
cl_polesd = sp.exp(cl_poles*ts)  # Desired discrete poles

# Add discrete integrator for steady state zero error
Phi_f = np.vstack((gz.A,-gz.C*ts))
Phi_f = np.hstack((Phi_f,[[0],[0],[0],[0],[1]]))
G_f = np.vstack((gz.B,zeros((1,1))))

# Pole placement
k = place(Phi_f,G_f,cl_polesd)

# Observer design - reduced order observer
poli_of = 5*sp.roots(cl_poly1)     # Desired continous poles
poli_o = 5*cl_poles[0:2]
poli_oz = sp.exp(poli_o*ts) 
poli_ozf = sp.exp(poli_of*ts)
Ejemplo n.º 49
0
def real_roots(expr):
    import scipy as sc
    r = sc.roots(coeffs(expr))
    return np.real( r[np.imag(r)==0] )
Ejemplo n.º 50
0
def roots(expr):
    import scipy as sc
    return sc.roots(coeffs(expr))
Ejemplo n.º 51
0
def lars_regression_noise_old(Yp, X, positive, noise, verbose=False):
    """
     Run LARS for regression problems with LASSO penalty, with optional positivity constraints
     Author: Andrea Giovannucci. Adapted code from Eftychios Pnevmatikakis


     Parameters:
        -------
       Yp:          Yp[:,t] is the observed data at time t

       X:           the regresion problem is Yp=X*W + noise

       maxcomps:    maximum number of active components to allow

       positive:    a flag to enforce positivity

       noise:       the noise of the observation equation. if it is not
                    provided as an argument, the noise is computed from the
                    variance at the end point of the algorithm. The noise is
                    used in the computation of the Cp criterion.

     Returns:
    -------
       Ws: weights from each iteration
       lambdas: lambda_ values at each iteration

       Cps: C_p estimates
       last_break:     last_break(m) == n means that the last break with m non-zero weights is at Ws(:,:,n)

    See Also:
    -------
        LARS : https://en.wikipedia.org/wiki/Least-angle_regression
        group Lasso :
    """
    # INITAILIZATION
    T = len(Yp)  # of time steps
    k = 1
    Yp = np.squeeze(np.asarray(Yp))
    # necessary for matrix multiplications
    Yp = np.expand_dims(Yp, axis=1)
    _, T = np.shape(Yp)  # of time steps
    _, N = np.shape(X)  # of compartments

    # 1 : Start with all Weights equal to zero.
    maxcomps = N
    W = np.zeros((N, k))
    active_set = np.zeros((N, k))
    visited_set = np.zeros((N, k))
    lambdas = []
    #  Just preallocation. Ws may end with more or less than maxcomp columns
    Ws = []
    r = np.expand_dims(np.dot(X.T, Yp.flatten()), axis=1)  # N-dim vector
    M = np.dot(-X.T, X)  # N x N matrix

    # %% begin main loop
    i = 0
    flag = 0
    while 1:
        if flag == 1:
            W_lam = 0
            break
            # % calculate new gradient component if necessary
        if i > 0 and new >= 0 and visited_set[new] == 0:  # AG NOT CLEAR HERE
            visited_set[new] = 1  # % remember this direction was computed
        # % Compute full gradient of Q
        dQ = r + np.dot(M, W)

        # % Compute new W
        if i == 0:
            if positive:
                dQa = dQ
            else:
                dQa = np.abs(dQ)
            lambda_, new = np.max(dQa), np.argmax(dQa)

            if lambda_ < 0:
                print('All negative directions!')
                break
        else:  # 2 : Find the predictor x_{j} most correlated with y

            # % calculate vector to travel along
            avec, gamma_plus, gamma_minus = calcAvec(
                new, dQ, W, lambda_, active_set, M, positive)
            # % calculate time of travel and next new direction
            if new == -1:  # % if we just dropped a direction we don't allow it to emerge
                if dropped_sign == 1:  # % with the same sign
                    gamma_plus[dropped] = np.inf
                else:
                    gamma_minus[dropped] = np.inf
            # 3 : Increase the coefficient W in the direction of the sign of its correlation with y
            # % don't consider active components
            gamma_plus[active_set == 1] = np.inf
            # % or components outside the range [0, lambda_]
            gamma_plus[gamma_plus <= 0] = np.inf
            gamma_plus[gamma_plus > lambda_] = np.inf
            gp_min, gp_min_ind = np.min(gamma_plus), np.argmin(gamma_plus)

            if positive:
                gm_min = np.inf  # % don't consider new directions that would grow negative
            else:
                gamma_minus[active_set == 1] = np.inf
                gamma_minus[gamma_minus > lambda_] = np.inf
                gamma_minus[gamma_minus <= 0] = np.inf
                gm_min, gm_min_ind = np.min(
                    gamma_minus), np.argmin(gamma_minus)

            [g_min, which] = np.min(gp_min), np.argmin(gp_min)
# % if there are no possible new components, try move to the end
            if g_min == np.inf:
                g_min = lambda_
# % This happens when all the components are already active or, if positive==1,
# when there are no new positive directions

            # % LARS check  (is g_min*avec too large?)
            gamma_zero = old_div(-W[active_set == 1], np.squeeze(avec))
            gamma_zero_full = np.zeros((N, k))
            gamma_zero_full[active_set == 1] = gamma_zero
            gamma_zero_full[gamma_zero_full <= 0] = np.inf
            gz_min, gz_min_ind = np.min(
                gamma_zero_full), np.argmin(gamma_zero_full)
            # 4: Increase Wj,Wk in their joint least squares direction, until some other predictor x_{m}
            # has as much correlation with the residual r. (see 5)
            if gz_min < g_min:
                if verbose:
                    print(('DROPPING active weight:' + str(gz_min_ind)))
                active_set[gz_min_ind] = 0
                dropped = gz_min_ind
                dropped_sign = np.sign(W[dropped])
                W[gz_min_ind] = 0
                avec = avec[gamma_zero != gz_min]
                g_min = gz_min
                new = -1

            elif g_min < lambda_:
                if which == 0:
                    new = gp_min_ind
                    if verbose:
                        print(('new positive component:' + str(new)))

                else:
                    new = gm_min_ind
                    print(('new negative component:' + str(new)))

            W[active_set == 1] = W[active_set == 1] + \
                np.dot(g_min, np.squeeze(avec))
            if positive:
                if any(W < 0):
                    flag = 1

            lambda_ = lambda_ - g_min

        # %  Update weights and lambdas
        lambdas.append(lambda_)
        Ws.append(W.copy())
        # 5 : Take residuals r=y-y_  along the way. Stop when some other predictor x_{k}
        # has as much correlation with  r as x_{j} has.
        if len((Yp - np.dot(X, W)).shape) > 2:
            res = scipy.linalg.norm(np.squeeze(Yp - np.dot(X, W)), 'fro') ** 2
        else:
            res = scipy.linalg.norm(Yp - np.dot(X, W), 'fro') ** 2

            # % Check finishing conditions
        if lambda_ == 0 or (new >= 0 and np.sum(active_set) == maxcomps) or (res < noise):
            if verbose:
                print('end. \n')
            break
        # 6: Continue until: all predictors are in the model
        if new >= 0:
            active_set[new] = 1

        i = i + 1

    Ws_old = Ws
    # end main loop

    #%% final calculation of mus
    Ws = np.asarray(np.swapaxes(np.swapaxes(Ws_old, 0, 1), 1, 2))
    if flag == 0:
        if i > 0:
            Ws = np.squeeze(Ws[:, :, :len(lambdas)])
            w_dir = old_div(-(Ws[:, i] - Ws[:, i - 1]),
                            (lambdas[i] - lambdas[i - 1]))
            Aw = np.dot(X, w_dir)
            y_res = np.squeeze(
                Yp) - np.dot(X, Ws[:, i - 1] + w_dir * lambdas[i - 1])
            ld = scipy.roots([scipy.linalg.norm(Aw) ** 2, -2 * np.dot(Aw.T, y_res),
                              np.dot(y_res.T, y_res) - noise])
            lam = ld[np.intersect1d(
                np.where(ld > lambdas[i]), np.where(ld < lambdas[i - 1]))]
            if len(lam) == 0 or np.any(lam) < 0 or np.any(~np.isreal(lam)):
                lam = np.array([lambdas[i]])

            W_lam = Ws[:, i - 1] + np.dot(w_dir, lambdas[i - 1] - lam[0])
        else:
            warn('LARS REGRESSION NOT SOLVABLE, USING NN LEAST SQUARE')
            W_lam = scipy.optimize.nnls(X, np.ravel(Yp))[0]
            lam = 10

    else:
        W_lam = 0
        Ws = 0
        lambdas = 0
        lam = 0

    return Ws, lambdas, W_lam, lam, flag
Ejemplo n.º 52
0
def TB_lib(compuesto, T):
    """Librería de cálculo de la ecuación de estado de Trebble-Bishnoi"""
    if compuesto.Tc!=0.0 and compuesto.Pc.atm!=0.0 and compuesto.vc!=0.0:
        Zc=compuesto.Pc.atm*compuesto.vc*compuesto.peso_molecular/R_atml/compuesto.Tc
    else:
        if compuesto.f_acent<0.225:
            TcPc=775.9+12009*compuesto.f_acent-57335*compuesto.f_acent**2+91393*compuesto.f_acent**3
        elif compuesto.f_acent<=1.:
            TcPc=1876-1160*compuesto.f_acent
        else:
            TcPc=compuesto.Tc*compuesto.Pc.MPa

        if compuesto.f_acent>=-0.14:
            Zc=0.29-0.0885*compuesto.f_acent-0.0005/((compuesto.Tc*compuesto.Pc.MPa)**0.5-TcPc**0.5)
        else:
            Zc=0.3024

    d=0.341*compuesto.vc*compuesto.peso_molecular-0.005
    Xc=1.075*Zc
    Dc=d*compuesto.Pc.atm/R_atml/compuesto.Tc
    Cc=1-3*Xc
    B=roots([1, 2-3*Xc, 3*Xc**2, -Dc**2-Xc**3])
    Bpositivos=[]
    for i in range(3):
        if B[i]>0:
            Bpositivos.append(B[i])
    Bc=min(Bpositivos)
    Ac=3*Xc**2+2*Bc*Cc+Bc+Cc+Bc**2+Dc**2

    if compuesto.indice==212 and compuesto.tr(T)<=1:
        q1=-0.31913
    elif compuesto.f_acent<-0.1:
        q1=0.66208+4.63961*compuesto.f_acent+7.45183*compuesto.f_acent**2
    elif compuesto.f_acent<=0.4:
        q1=0.35+0.7924*compuesto.f_acent+0.1875*compuesto.f_acent**2-28.93*(0.3-Zc)**2
    elif compuesto.f_acent>0.4:
        q1=0.32+0.9424*compuesto.f_acent-28.93*(0.3-Zc)**2

    if compuesto.f_acent<-0.0423:
        q2=0
    elif compuesto.f_acent<=0.3:
        q2=0.05246+1.15058*compuesto.f_acent-1.99348*compuesto.f_acent**2+1.5949*compuesto.f_acent**3-1.39267*compuesto.f_acent**4
    else:
        q2=0.17959+0.23471*compuesto.f_acent

    alfa=exp(q1*(1-compuesto.tr(T)))
    if T<=compuesto.Tc:
        beta=1.+q2*(1-compuesto.tr(T)+log(compuesto.tr(T)))
    else:
        beta=1
    ac=Ac*R_atml**2*compuesto.Tc**2/compuesto.Pc.atm
    bc=Bc*R_atml*compuesto.Tc/compuesto.Pc.atm
    c=Cc*R_atml*compuesto.Tc/compuesto.Pc.atm

    return ac*alfa, bc*beta, c, d

    def TB_Fugacidad(self, T, P):
        """Método de cálculo de la fugacidad mediante la ecuación de estado de Trebble-Bishnoi"""
        a, b, c, d, q1, q2=self.TB_lib(T, P)
        z=self.TB_Z(T, P)
        A=a*P/R_atml**2/T**2
        B=b*P/R_atml/T
        u=1+c/b
        t=1+6*c/b+c**2/b**2+4*d**2/b**2
        tita=abs(t)**0.5
        if t>=0:
            lamda=log((2*z+B*(u-tita))/(2*z+B*(u+tita)))
        else:
            lamda=2*arctan((2*z+u*B)/B/tita)-pi
        fi=z-1-log(z-B)+A/B/tita*lamda
        return unidades.Pressure(P*exp(fi), "atm")

    def TB_U_exceso(self, T, P):
        """Método de cálculo de la energía interna de exceso mediante la ecuación de estado de Trebble-Bishnoi"""
        a, b, c, d, q1, q2=self.TB_lib(T, P)
        v=self.TB_V(T, P)
        z=P*v/R_atml/T
        A=a*P/R_atml**2/T**2
        B=b*P/R_atml/T
        u=1+c/b
        t=1+6*c/b+c**2/b**2+4*d**2/b**2
        tita=abs(t)**0.5
        if t>=0:
            lamda=log((2*z+B*(u-tita))/(2*z+B*(u+tita)))
        else:
            lamda=2*arctan((2*z+u*B)/B/tita)-pi

        delta=v**2+(b+c)*v-b*c-d**2
        beta=1.+q2*(1-self.tr(T)+log(self.tr(T)))
        da=-q1*a/self.Tc
        if self.tr(T)<=1.0:
            db=b/beta*(1/T-1/self.Tc)
        else:
            db=0
        U=lamda/b/tita*(a-da*T)+db*T*(-R_atml*T/(v-b)+a/b**2/t*((v*(3*c+b)-b*c+c**2-2*d**2)/delta+(3*c+b)*lamda/b/tita)) #atm*l/mol
        return unidades.Enthalpy(U*101325/1000/self.peso_molecular, "Jkg")

    def TB_H_exceso(self, T, P):
        """Método de cálculo de la entalpía de exceso mediante la ecuación de estado de Trebble-Bishnoi"""
        p=unidades.Pressure(P, "atm")
        U=self.TB_U_exceso(T, P)
        a, b, c, d, q1, q2=self.TB_lib(T, P)
        t=1+6*c/b+c**2/b**2+4*d**2/b**2
        if t>=0:
            v=self.TB_V(T, P).m3g*self.peso_molecular
            return unidades.Enthalpy(p*v-R/T/self.peso_molecular+U.Jg, "Jg")
        else:
            Z=self.TB_Z(T, P)
            return unidades.Enthalpy(R/self.peso_molecular*T*(Z-1)+U.Jg, "Jg")

    def TB_Entalpia(self, T, P):
        """Método de cálculo de la entalpía mediante la ecuación de estado de Trebble-Bishnoi"""
        Ho=self._Ho(T)
        Delta=self.TB_H_exceso(T, P)
        return unidades.Enthalpy(Delta+Ho)

    def TB_S_exceso(self, T, P):
        """Método de cálculo de la entropía de exceso mediante la ecuación de estado de Trebble-Bishnoi"""
        H=self.TB_H_exceso(T, P)
        f=self.TB_Fugacidad(T, P)
        return unidades.SpecificHeat(H.Jg/T-R/self.peso_molecular*log(f.atm/P), "JgK")

    def TB_Entropia(self, T, P):
        """Método de cálculo de la entropía mediante la ecuación de estado de Trebble-Bishnoi"""
        So=self._so(T)
        Delta=self.TB_S_exceso(T, P)
        return unidades.SpecificHeat(Delta+So)

    def TB_Cv_exceso(self, T, P):
        """Método de cálculo de la capacidad calorífica a volumen constante de exceso mediante la ecuación de estado de Trebble-Bishnoi"""
        a, b, c, d, q1, q2=self.TB_lib(T, P)
        v=self.TB_V(T, P)
        z=P*v/R_atml/T
        t=1+6*c/b+c**2/b**2+4*d**2/b**2
        tita=abs(t)**0.5
        A=a*P/R_atml**2/T**2
        B=b*P/R_atml/T
        u=1+c/b
        delta=v**2+(b+c)*v-b*c-d**2
        beta=1.+q2*(1-self.tr(T)+log(self.tr(T)))
        da=-q1*a/self.Tc
        dda=q1**2*a/self.Tc**2
        if self.tr(T)<=1.0:
            db=b/beta*(1/T-1/self.Tc)
            ddb=-q2*b/beta/T**2
        else:
            db=0
            ddb=0

        dt=-db/b**2*(6*c+2*c**2/b+8*d**2/b)
        dtita=abs(dt)/20
        if t>=0:
            lamda=log((2*z+B*(u-tita))/(2*z+B*(u+tita)))
            dlamda=(db-db*tita-b*dtita)/(2*v+b+c-b*tita)-(db+db*tita+b*dtita)/((2*v+b+c+b*tita))
        else:
            lamda=2*arctan((2*z+u*B)/B/tita)-pi
            dlamda=2/(1+((2*v+b+c)/b/tita)**2)*(db/b/tita-(2*v+b+c)*(db/b**2/tita+dtita/b/tita**2))

        Cv=1/b/tita*(dlamda*(a-da*T)-lamda*dda*T-lamda*(a-da*T)*(db/b+dtita/tita))+(ddb*T+db)*(-R_atml*T/(v-b)+a/b**2/t*((v*(3*c+b)-b*c+c**2-2*d**2)/delta+(3*c+b)*lamda/b/tita))+db*T*(-R_atml/(v-b)-R_atml*T*db/(v-b)**2+1/b**2/t*(da-2*a*db/b-a*dt/t)*((v*(3*c+b)-b*c+c**2-2*d**2)/delta+(3*c+b)*lamda/b/tita)+a/b**2/t*(db*(v-c)*(v**2-2*c*v-c**2+d**2)/delta**2+db*lamda/b/tita+(3*c+b)/b/tita*(dlamda-lamda*(db/b+dtita/tita))))
        return unidades.SpecificHeat(Cv*101325/1000/self.peso_molecular, "JkgK")

    def TB_Cv(self, T, P):
        """Método de cálculo de la capacidad calorifica a volumen constante mediante la ecuación de estado de Trebble-Bishnoi"""
        Cvo=self.Cv_ideal(T)
        Delta=self.TB_Cv_exceso(T, P)
        return unidades.SpecificHeat(Delta+Cvo)

    def TB_Cp_exceso(self, T, P):
        """Método de cálculo de la capacidad calorífica a presión constante de exceso mediante la ecuación de estado de Trebble-Bishnoi"""
        a, b, c, d, q1, q2=self.TB_lib(T, P)
        v=self.TB_V(T, P)
        Cv=self.TB_Cv_exceso(T, P)

        beta=1.+q2*(1-self.tr(T)+log(self.tr(T)))
        delta=v**2+(b+c)*v-b*c-d**2
        da=-q1*a/self.Tc
        if self.tr(T)<=1.0:
            db=b/beta*(1/T-1/self.Tc)
        else:
            db=0

        dpdt=R_atml/(v-b)+R*T*db/(v-b)**2-da/delta+a*(v-c)*db/delta**2
        dpdv=-R_atml*T/(v-b)**2+a*(2*v+b+c)/delta**2
        Cp=-R-T*dpdt**2/dpdv*101325/1000+Cv.JgK*self.peso_molecular

        return unidades.SpecificHeat(Cp/self.peso_molecular, "JgK")

    def TB_Cp(self, T, P):
        """Método de cálculo de la capacidad calorifica a presión constante mediante la ecuación de estado de Trebble-Bishnoi"""
        Cpo=self.Cp_ideal(T)
        Delta=self.TB_Cp_exceso(T, P)
        return unidades.SpecificHeat(Delta+Cpo)

    def TB_Joule_Thomson(self, T, P):
        """Método de cálculo del coeficiente de Joule-Thomson mediante la ecuación de estado de Trebble-Bishnoi"""
        v=self.TB_V(T, P)
        Cp=self.TB_Cp(T, P)
        a, b, c, d, q1, q2=self.TB_lib(T, P)

        beta=1.+q2*(1-self.tr(T)+log(self.tr(T)))
        delta=v**2+(b+c)*v-b*c-d**2
        da=-q1*a/self.Tc
        if self.tr(T)<=1.0:
            db=b/beta*(1/T-1/self.Tc)
        else:
            db=0
        dpdt=R_atml/(v-b)+R*T*db/(v-b)**2-da/delta+a*(v-c)*db/delta**2
        dpdv=-R_atml*T/(v-b)**2+a*(2*v+b+c)/delta**2

        return -(T*dpdt+v*dpdv)/Cp/dpdv
Ejemplo n.º 53
0
def lars_regression_noise_old(Yp, X, positive, noise, verbose=False):
    """
     Run LARS for regression problems with LASSO penalty, with optional positivity constraints
     Author: Andrea Giovannucci. Adapted code from Eftychios Pnevmatikakis


     Input Parameters:
       Yp:          Yp[:,t] is the observed data at time t
       X:           the regresion problem is Yp=X*W + noise
       maxcomps:    maximum number of active components to allow
       positive:    a flag to enforce positivity
       noise:       the noise of the observation equation. if it is not
                    provided as an argument, the noise is computed from the
                    variance at the end point of the algorithm. The noise is
                    used in the computation of the Cp criterion.


     Output Parameters:
       Ws: weights from each iteration
       lambdas: lambda_ values at each iteration
       TODO: W_lam, lam, flag
       Cps: C_p estimates
       last_break:     last_break(m) == n means that the last break with m non-zero weights is at Ws(:,:,n)
    """
    #%%

    # verbose=true;

    # do NNLS first
    # if  hard noise constraint problem infeasible we are done, otherwise good for warm-starting
#    W_lam, RSS = scipy.optimize.nnls(X, np.ravel(Yp))
#    RSS = RSS * RSS
#    if RSS > noise:  # hard noise constraint problem infeasible
#        return 0, 0, W_lam, 0, 0
#
#    while 1:
#        eliminate = []
#        for i in np.where(W_lam[:-1] > 0)[0]:  # W_lam[:-1] to skip background
#            mask = W_lam > 0
#            mask[i] = 0
#            Wtmp, tmp = scipy.optimize.nnls(X * mask, np.ravel(Yp))
#            if tmp * tmp < noise:
#                eliminate.append([i, tmp])
#        if eliminate == []:
#            return 0, 0, W_lam, 0, 0
#        else:
#            W_lam[eliminate[np.argmin(np.array(eliminate)[:, 1])][0]] = 0

    # obsolete stuff below

    # solve hard noise constraint problem
    T = len(Yp)  # of time steps
#    A = Yp.dot(X)
#    B = X.T.dot(X)
#    dB = 1 / np.diag(B)
#    import pdb
#    pdb.set_trace()
#    z = np.sqrt(1 / dB)
#    lam = np.max(1 * np.sqrt(noise / T) * z)
#    counter = 0
#    res = X.dot(W_lam) - Yp
#    tmp = X.dot(dB)
#    aa = tmp.dot(tmp)
#    while (RSS < noise * .9999 or RSS > noise * 1.0001) and counter < 20:
#        counter += 1
#        bb = tmp.dot(res)
#        cc = RSS - noise
#        if counter > 1:
#            lam += (bb + (0 if bb * bb <= aa * cc else np.sqrt(bb * bb - aa * cc))) / aa
#        for _ in range(3):
#            for i in range(len(W_lam)):
#                W_lam[i] = np.clip(W_lam[i] + (A[i] - W_lam.dot(B)[i] - lam) * dB[i], 0, np.inf)
#        res = X.dot(W_lam) - Yp
#        RSS = res.dot(res)
#    return 1, 1, W_lam, 1, 1

    k = 1
    Yp = np.squeeze(np.asarray(Yp))

    Yp = np.expand_dims(Yp, axis=1)  # necessary for matrix multiplications

    _, T = np.shape(Yp)  # of time steps
    _, N = np.shape(X)  # of compartments

    maxcomps = N
    W = np.zeros((N, k))
    active_set = np.zeros((N, k))
    visited_set = np.zeros((N, k))
    lambdas = []
    # =np.zeros((W.shape[0],W.shape[1],maxcomps));  # Just preallocation. Ws may end with more or less than maxcomp columns
    Ws = []
    r = np.expand_dims(np.dot(X.T, Yp.flatten()), axis=1)       # N-dim vector
    M = np.dot(-X.T, X)            # N x N matrix

    #%% begin main loop
    i = 0
    flag = 0
    while 1:
        if flag == 1:
            W_lam = 0
            break
    #% calculate new gradient component if necessary
        if i > 0 and new >= 0 and visited_set[new] == 0:  # AG NOT CLEAR HERE
            visited_set[new] = 1  # % remember this direction was computed

    #% Compute full gradient of Q
        dQ = r + np.dot(M, W)

    #% Compute new W
        if i == 0:
            if positive:
                dQa = dQ
            else:
                dQa = np.abs(dQ)
            lambda_, new = np.max(dQa), np.argmax(dQa)

            if lambda_ < 0:
                print('All negative directions!')
                break
        else:

            #% calculate vector to travel along
            avec, gamma_plus, gamma_minus = calcAvec(new, dQ, W, lambda_, active_set, M, positive)

           # % calculate time of travel and next new direction
            if new == -1:                              # % if we just dropped a direction we don't allow it to emerge
                if dropped_sign == 1:               # % with the same sign
                    gamma_plus[dropped] = np.inf
                else:
                    gamma_minus[dropped] = np.inf

            gamma_plus[active_set == 1] = np.inf  # % don't consider active components
            gamma_plus[gamma_plus <= 0] = np.inf  # % or components outside the range [0, lambda_]
            gamma_plus[gamma_plus > lambda_] = np.inf
            gp_min, gp_min_ind = np.min(gamma_plus), np.argmin(gamma_plus)

            if positive:
                gm_min = np.inf  # % don't consider new directions that would grow negative
            else:
                gamma_minus[active_set == 1] = np.inf
                gamma_minus[gamma_minus > lambda_] = np.inf
                gamma_minus[gamma_minus <= 0] = np.inf
                gm_min, gm_min_ind = np.min(gamma_minus), np.argmin(gamma_minus)

            [g_min, which] = np.min(gp_min), np.argmin(gp_min)

            if g_min == np.inf:  # % if there are no possible new components, try move to the end
                g_min = lambda_  # % This happens when all the components are already active or, if positive==1, when there are no new positive directions

            #% LARS check  (is g_min*avec too large?)
            gamma_zero = old_div(-W[active_set == 1], np.squeeze(avec))
            gamma_zero_full = np.zeros((N, k))
            gamma_zero_full[active_set == 1] = gamma_zero
            gamma_zero_full[gamma_zero_full <= 0] = np.inf
            gz_min, gz_min_ind = np.min(gamma_zero_full), np.argmin(gamma_zero_full)

            if gz_min < g_min:
                #                print 'check_here'
                if verbose:
                    print(('DROPPING active weight:' + str(gz_min_ind)))

                active_set[gz_min_ind] = 0
                dropped = gz_min_ind
                dropped_sign = np.sign(W[dropped])
                W[gz_min_ind] = 0
                avec = avec[gamma_zero != gz_min]
                g_min = gz_min
                new = -1  # new = 0;

            elif g_min < lambda_:
                if which == 0:
                    new = gp_min_ind
                    if verbose:
                        print(('new positive component:' + str(new)))

                else:
                    new = gm_min_ind
                    print(('new negative component:' + str(new)))

            W[active_set == 1] = W[active_set == 1] + np.dot(g_min, np.squeeze(avec))

            if positive:
                if any(W < 0):
                    # min(W);
                    flag = 1
                    #%error('negative W component');

            lambda_ = lambda_ - g_min

    #%  Update weights and lambdas

        lambdas.append(lambda_)
        Ws.append(W.copy())

    #    print Ws
        if len((Yp - np.dot(X, W)).shape) > 2:
            res = scipy.linalg.norm(np.squeeze(Yp - np.dot(X, W)), 'fro')**2
        else:
            res = scipy.linalg.norm(Yp - np.dot(X, W), 'fro')**2

    #% Check finishing conditions
        if lambda_ == 0 or (new >= 0 and np.sum(active_set) == maxcomps) or (res < noise):
            if verbose:
                print('end. \n')
            break

        #%
        if new >= 0:
            active_set[new] = 1

        i = i + 1

    Ws_old = Ws
    # end main loop

    #%% final calculation of mus
    Ws = np.asarray(np.swapaxes(np.swapaxes(Ws_old, 0, 1), 1, 2))
    if flag == 0:
        if i > 0:
            Ws = np.squeeze(Ws[:, :, :len(lambdas)])
            w_dir = old_div(-(Ws[:, i] - Ws[:, i - 1]), (lambdas[i] - lambdas[i - 1]))
            Aw = np.dot(X, w_dir)
            y_res = np.squeeze(Yp) - np.dot(X, Ws[:, i - 1] + w_dir * lambdas[i - 1])
            ld = scipy.roots([scipy.linalg.norm(Aw)**2, -2 * np.dot(Aw.T, y_res),
                              np.dot(y_res.T, y_res) - noise])
            lam = ld[np.intersect1d(np.where(ld > lambdas[i]), np.where(ld < lambdas[i - 1]))]
            if len(lam) == 0 or np.any(lam) < 0 or np.any(~np.isreal(lam)):
                lam = np.array([lambdas[i]])

            W_lam = Ws[:, i - 1] + np.dot(w_dir, lambdas[i - 1] - lam[0])
        else:
            warn('LARS REGRESSION NOT SOLVABLE, USING NN LEAST SQUARE')
            W_lam = scipy.optimize.nnls(X, np.ravel(Yp))[0]
#            problem = picos.Problem(X,Yp)
#            W_lam = problem.add_variable('W_lam', X.shape[1])
#            problem.set_objective('min', 1|W_lam)
#            problem.add_constraint(W_lam >= 0)
#            problem.add_constraint(picos.norm(matrix(Yp.astype(np.float))-matrix(X.astype(np.float))*W_lam,2)<=np.sqrt(noise))
#            sel_solver = []
#            problem.solver_selection()
#            problem.solve(verbose=True)

    #        cvx_begin quiet
    #            variable W_lam(size(X,2));
    #            minimize(sum(W_lam));
    #            subject to
    #                W_lam >= 0;
    #                norm(Yp-X*W_lam)<= sqrt(noise);
    #        cvx_end
            lam = 10

    else:
        W_lam = 0
        Ws = 0
        lambdas = 0
        lam = 0

    return Ws, lambdas, W_lam, lam, flag
Ejemplo n.º 54
0
def lars_regression_noise_old(Yp, X, positive, noise, verbose=False):
    """
     Run LARS for regression problems with LASSO penalty, with optional positivity constraints
     Author: Andrea Giovannucci. Adapted code from Eftychios Pnevmatikakis


     Input Parameters:
       Yp:          Yp[:,t] is the observed data at time t
       X:           the regresion problem is Yp=X*W + noise
       maxcomps:    maximum number of active components to allow
       positive:    a flag to enforce positivity
       noise:       the noise of the observation equation. if it is not
                    provided as an argument, the noise is computed from the
                    variance at the end point of the algorithm. The noise is
                    used in the computation of the Cp criterion.


     Output Parameters:
       Ws: weights from each iteration
       lambdas: lambda_ values at each iteration
       TODO: W_lam, lam, flag
       Cps: C_p estimates
       last_break:     last_break(m) == n means that the last break with m non-zero weights is at Ws(:,:,n)
    """
    #%%

    # verbose=true;

    # do NNLS first
    # if  hard noise constraint problem infeasible we are done, otherwise good for warm-starting
#    W_lam, RSS = scipy.optimize.nnls(X, np.ravel(Yp))
#    RSS = RSS * RSS
#    if RSS > noise:  # hard noise constraint problem infeasible
#        return 0, 0, W_lam, 0, 0
#
#    while 1:
#        eliminate = []
#        for i in np.where(W_lam[:-1] > 0)[0]:  # W_lam[:-1] to skip background
#            mask = W_lam > 0
#            mask[i] = 0
#            Wtmp, tmp = scipy.optimize.nnls(X * mask, np.ravel(Yp))
#            if tmp * tmp < noise:
#                eliminate.append([i, tmp])
#        if eliminate == []:
#            return 0, 0, W_lam, 0, 0
#        else:
#            W_lam[eliminate[np.argmin(np.array(eliminate)[:, 1])][0]] = 0

    # obsolete stuff below

    # solve hard noise constraint problem
    T = len(Yp)  # of time steps
#    A = Yp.dot(X)
#    B = X.T.dot(X)
#    dB = 1 / np.diag(B)
#    import pdb
#    pdb.set_trace()
#    z = np.sqrt(1 / dB)
#    lam = np.max(1 * np.sqrt(noise / T) * z)
#    counter = 0
#    res = X.dot(W_lam) - Yp
#    tmp = X.dot(dB)
#    aa = tmp.dot(tmp)
#    while (RSS < noise * .9999 or RSS > noise * 1.0001) and counter < 20:
#        counter += 1
#        bb = tmp.dot(res)
#        cc = RSS - noise
#        if counter > 1:
#            lam += (bb + (0 if bb * bb <= aa * cc else np.sqrt(bb * bb - aa * cc))) / aa
#        for _ in range(3):
#            for i in range(len(W_lam)):
#                W_lam[i] = np.clip(W_lam[i] + (A[i] - W_lam.dot(B)[i] - lam) * dB[i], 0, np.inf)
#        res = X.dot(W_lam) - Yp
#        RSS = res.dot(res)
#    return 1, 1, W_lam, 1, 1

    k = 1
    Yp = np.squeeze(np.asarray(Yp))

    Yp = np.expand_dims(Yp, axis=1)  # necessary for matrix multiplications

    _, T = np.shape(Yp)  # of time steps
    _, N = np.shape(X)  # of compartments

    maxcomps = N
    W = np.zeros((N, k))
    active_set = np.zeros((N, k))
    visited_set = np.zeros((N, k))
    lambdas = []
    # =np.zeros((W.shape[0],W.shape[1],maxcomps));  # Just preallocation. Ws may end with more or less than maxcomp columns
    Ws = []
    r = np.expand_dims(np.dot(X.T, Yp.flatten()), axis=1)       # N-dim vector
    M = np.dot(-X.T, X)            # N x N matrix

    #%% begin main loop
    i = 0
    flag = 0
    while 1:
        if flag == 1:
            W_lam = 0
            break
    #% calculate new gradient component if necessary
        if i > 0 and new >= 0 and visited_set[new] == 0:  # AG NOT CLEAR HERE
            visited_set[new] = 1  # % remember this direction was computed

    #% Compute full gradient of Q
        dQ = r + np.dot(M, W)

    #% Compute new W
        if i == 0:
            if positive:
                dQa = dQ
            else:
                dQa = np.abs(dQ)
            lambda_, new = np.max(dQa), np.argmax(dQa)

            if lambda_ < 0:
                print('All negative directions!')
                break
        else:

            #% calculate vector to travel along
            avec, gamma_plus, gamma_minus = calcAvec(new, dQ, W, lambda_, active_set, M, positive)

           # % calculate time of travel and next new direction
            if new == -1:                              # % if we just dropped a direction we don't allow it to emerge
                if dropped_sign == 1:               # % with the same sign
                    gamma_plus[dropped] = np.inf
                else:
                    gamma_minus[dropped] = np.inf

            gamma_plus[active_set == 1] = np.inf  # % don't consider active components
            gamma_plus[gamma_plus <= 0] = np.inf  # % or components outside the range [0, lambda_]
            gamma_plus[gamma_plus > lambda_] = np.inf
            gp_min, gp_min_ind = np.min(gamma_plus), np.argmin(gamma_plus)

            if positive:
                gm_min = np.inf  # % don't consider new directions that would grow negative
            else:
                gamma_minus[active_set == 1] = np.inf
                gamma_minus[gamma_minus > lambda_] = np.inf
                gamma_minus[gamma_minus <= 0] = np.inf
                gm_min, gm_min_ind = np.min(gamma_minus), np.argmin(gamma_minus)

            [g_min, which] = np.min(gp_min), np.argmin(gp_min)

            if g_min == np.inf:  # % if there are no possible new components, try move to the end
                g_min = lambda_  # % This happens when all the components are already active or, if positive==1, when there are no new positive directions

            #% LARS check  (is g_min*avec too large?)
            gamma_zero = old_div(-W[active_set == 1], np.squeeze(avec))
            gamma_zero_full = np.zeros((N, k))
            gamma_zero_full[active_set == 1] = gamma_zero
            gamma_zero_full[gamma_zero_full <= 0] = np.inf
            gz_min, gz_min_ind = np.min(gamma_zero_full), np.argmin(gamma_zero_full)

            if gz_min < g_min:
                #                print 'check_here'
                if verbose:
                    print(('DROPPING active weight:' + str(gz_min_ind)))

                active_set[gz_min_ind] = 0
                dropped = gz_min_ind
                dropped_sign = np.sign(W[dropped])
                W[gz_min_ind] = 0
                avec = avec[gamma_zero != gz_min]
                g_min = gz_min
                new = -1  # new = 0;

            elif g_min < lambda_:
                if which == 0:
                    new = gp_min_ind
                    if verbose:
                        print(('new positive component:' + str(new)))

                else:
                    new = gm_min_ind
                    print(('new negative component:' + str(new)))

            W[active_set == 1] = W[active_set == 1] + np.dot(g_min, np.squeeze(avec))

            if positive:
                if any(W < 0):
                    # min(W);
                    flag = 1
                    #%error('negative W component');

            lambda_ = lambda_ - g_min

    #%  Update weights and lambdas

        lambdas.append(lambda_)
        Ws.append(W.copy())

    #    print Ws
        if len((Yp - np.dot(X, W)).shape) > 2:
            res = scipy.linalg.norm(np.squeeze(Yp - np.dot(X, W)), 'fro')**2
        else:
            res = scipy.linalg.norm(Yp - np.dot(X, W), 'fro')**2

    #% Check finishing conditions
        if lambda_ == 0 or (new >= 0 and np.sum(active_set) == maxcomps) or (res < noise):
            if verbose:
                print('end. \n')
            break

        #%
        if new >= 0:
            active_set[new] = 1

        i = i + 1

    Ws_old = Ws
    # end main loop

    #%% final calculation of mus
    Ws = np.asarray(np.swapaxes(np.swapaxes(Ws_old, 0, 1), 1, 2))
    if flag == 0:
        if i > 0:
            Ws = np.squeeze(Ws[:, :, :len(lambdas)])
            w_dir = old_div(-(Ws[:, i] - Ws[:, i - 1]), (lambdas[i] - lambdas[i - 1]))
            Aw = np.dot(X, w_dir)
            y_res = np.squeeze(Yp) - np.dot(X, Ws[:, i - 1] + w_dir * lambdas[i - 1])
            ld = scipy.roots([scipy.linalg.norm(Aw)**2, -2 * np.dot(Aw.T, y_res),
                              np.dot(y_res.T, y_res) - noise])
            lam = ld[np.intersect1d(np.where(ld > lambdas[i]), np.where(ld < lambdas[i - 1]))]
            if len(lam) == 0 or np.any(lam) < 0 or np.any(~np.isreal(lam)):
                lam = np.array([lambdas[i]])

            W_lam = Ws[:, i - 1] + np.dot(w_dir, lambdas[i - 1] - lam[0])
        else:
            warn('LARS REGRESSION NOT SOLVABLE, USING NN LEAST SQUARE')
            W_lam = scipy.optimize.nnls(X, np.ravel(Yp))[0]
#            problem = picos.Problem(X,Yp)
#            W_lam = problem.add_variable('W_lam', X.shape[1])
#            problem.set_objective('min', 1|W_lam)
#            problem.add_constraint(W_lam >= 0)
#            problem.add_constraint(picos.norm(matrix(Yp.astype(np.float))-matrix(X.astype(np.float))*W_lam,2)<=np.sqrt(noise))
#            sel_solver = []
#            problem.solver_selection()
#            problem.solve(verbose=True)

    #        cvx_begin quiet
    #            variable W_lam(size(X,2));
    #            minimize(sum(W_lam));
    #            subject to
    #                W_lam >= 0;
    #                norm(Yp-X*W_lam)<= sqrt(noise);
    #        cvx_end
            lam = 10

    else:
        W_lam = 0
        Ws = 0
        lambdas = 0
        lam = 0

    return Ws, lambdas, W_lam, lam, flag
Ejemplo n.º 55
0
def lars_regression_noise_old(Yp, X, positive, noise, verbose=False):
    """
     Run LARS for regression problems with LASSO penalty, with optional positivity constraints
     Author: Andrea Giovannucci. Adapted code from Eftychios Pnevmatikakis


     Parameters:
        -------
       Yp:          Yp[:,t] is the observed data at time t

       X:           the regresion problem is Yp=X*W + noise

       maxcomps:    maximum number of active components to allow

       positive:    a flag to enforce positivity

       noise:       the noise of the observation equation. if it is not
                    provided as an argument, the noise is computed from the
                    variance at the end point of the algorithm. The noise is
                    used in the computation of the Cp criterion.

     Returns:
    -------
       Ws: weights from each iteration
       lambdas: lambda_ values at each iteration

       Cps: C_p estimates
       last_break:     last_break(m) == n means that the last break with m non-zero weights is at Ws(:,:,n)

    See Also:
    -------
        LARS : https://en.wikipedia.org/wiki/Least-angle_regression
        group Lasso :
    """
    # INITAILIZATION
    T = len(Yp)  # of time steps
    k = 1
    Yp = np.squeeze(np.asarray(Yp))
    # necessary for matrix multiplications
    Yp = np.expand_dims(Yp, axis=1)
    _, T = np.shape(Yp)  # of time steps
    _, N = np.shape(X)  # of compartments

    # 1 : Start with all Weights equal to zero.
    maxcomps = N
    W = np.zeros((N, k))
    active_set = np.zeros((N, k))
    visited_set = np.zeros((N, k))
    lambdas = []
    #  Just preallocation. Ws may end with more or less than maxcomp columns
    Ws = []
    r = np.expand_dims(np.dot(X.T, Yp.flatten()), axis=1)  # N-dim vector
    M = np.dot(-X.T, X)  # N x N matrix

    # %% begin main loop
    i = 0
    flag = 0
    while 1:
        if flag == 1:
            W_lam = 0
            break
            # % calculate new gradient component if necessary
        if i > 0 and new >= 0 and visited_set[new] == 0:  # AG NOT CLEAR HERE
            visited_set[new] = 1  # % remember this direction was computed
        # % Compute full gradient of Q
        dQ = r + np.dot(M, W)

        # % Compute new W
        if i == 0:
            if positive:
                dQa = dQ
            else:
                dQa = np.abs(dQ)
            lambda_, new = np.max(dQa), np.argmax(dQa)

            if lambda_ < 0:
                print('All negative directions!')
                break
        else:  # 2 : Find the predictor x_{j} most correlated with y

            # % calculate vector to travel along
            avec, gamma_plus, gamma_minus = calcAvec(
                new, dQ, W, lambda_, active_set, M, positive)
            # % calculate time of travel and next new direction
            if new == -1:  # % if we just dropped a direction we don't allow it to emerge
                if dropped_sign == 1:  # % with the same sign
                    gamma_plus[dropped] = np.inf
                else:
                    gamma_minus[dropped] = np.inf
            # 3 : Increase the coefficient W in the direction of the sign of its correlation with y
            # % don't consider active components
            gamma_plus[active_set == 1] = np.inf
            # % or components outside the range [0, lambda_]
            gamma_plus[gamma_plus <= 0] = np.inf
            gamma_plus[gamma_plus > lambda_] = np.inf
            gp_min, gp_min_ind = np.min(gamma_plus), np.argmin(gamma_plus)

            if positive:
                gm_min = np.inf  # % don't consider new directions that would grow negative
            else:
                gamma_minus[active_set == 1] = np.inf
                gamma_minus[gamma_minus > lambda_] = np.inf
                gamma_minus[gamma_minus <= 0] = np.inf
                gm_min, gm_min_ind = np.min(
                    gamma_minus), np.argmin(gamma_minus)

            [g_min, which] = np.min(gp_min), np.argmin(gp_min)
# % if there are no possible new components, try move to the end
            if g_min == np.inf:
                g_min = lambda_
# % This happens when all the components are already active or, if positive==1,
# when there are no new positive directions

            # % LARS check  (is g_min*avec too large?)
            gamma_zero = old_div(-W[active_set == 1], np.squeeze(avec))
            gamma_zero_full = np.zeros((N, k))
            gamma_zero_full[active_set == 1] = gamma_zero
            gamma_zero_full[gamma_zero_full <= 0] = np.inf
            gz_min, gz_min_ind = np.min(
                gamma_zero_full), np.argmin(gamma_zero_full)
            # 4: Increase Wj,Wk in their joint least squares direction, until some other predictor x_{m}
            # has as much correlation with the residual r. (see 5)
            if gz_min < g_min:
                if verbose:
                    print(('DROPPING active weight:' + str(gz_min_ind)))
                active_set[gz_min_ind] = 0
                dropped = gz_min_ind
                dropped_sign = np.sign(W[dropped])
                W[gz_min_ind] = 0
                avec = avec[gamma_zero != gz_min]
                g_min = gz_min
                new = -1

            elif g_min < lambda_:
                if which == 0:
                    new = gp_min_ind
                    if verbose:
                        print(('new positive component:' + str(new)))

                else:
                    new = gm_min_ind
                    print(('new negative component:' + str(new)))

            W[active_set == 1] = W[active_set == 1] + \
                np.dot(g_min, np.squeeze(avec))
            if positive:
                if any(W < 0):
                    flag = 1

            lambda_ = lambda_ - g_min

        # %  Update weights and lambdas
        lambdas.append(lambda_)
        Ws.append(W.copy())
        # 5 : Take residuals r=y-y_  along the way. Stop when some other predictor x_{k}
        # has as much correlation with  r as x_{j} has.
        if len((Yp - np.dot(X, W)).shape) > 2:
            res = scipy.linalg.norm(np.squeeze(Yp - np.dot(X, W)), 'fro') ** 2
        else:
            res = scipy.linalg.norm(Yp - np.dot(X, W), 'fro') ** 2

            # % Check finishing conditions
        if lambda_ == 0 or (new >= 0 and np.sum(active_set) == maxcomps) or (res < noise):
            if verbose:
                print('end. \n')
            break
        # 6: Continue until: all predictors are in the model
        if new >= 0:
            active_set[new] = 1

        i = i + 1

    Ws_old = Ws
    # end main loop

    #%% final calculation of mus
    Ws = np.asarray(np.swapaxes(np.swapaxes(Ws_old, 0, 1), 1, 2))
    if flag == 0:
        if i > 0:
            Ws = np.squeeze(Ws[:, :, :len(lambdas)])
            w_dir = old_div(-(Ws[:, i] - Ws[:, i - 1]),
                            (lambdas[i] - lambdas[i - 1]))
            Aw = np.dot(X, w_dir)
            y_res = np.squeeze(
                Yp) - np.dot(X, Ws[:, i - 1] + w_dir * lambdas[i - 1])
            ld = scipy.roots([scipy.linalg.norm(Aw) ** 2, -2 * np.dot(Aw.T, y_res),
                              np.dot(y_res.T, y_res) - noise])
            lam = ld[np.intersect1d(
                np.where(ld > lambdas[i]), np.where(ld < lambdas[i - 1]))]
            if len(lam) == 0 or np.any(lam) < 0 or np.any(~np.isreal(lam)):
                lam = np.array([lambdas[i]])

            W_lam = Ws[:, i - 1] + np.dot(w_dir, lambdas[i - 1] - lam[0])
        else:
            warn('LARS REGRESSION NOT SOLVABLE, USING NN LEAST SQUARE')
            W_lam = scipy.optimize.nnls(X, np.ravel(Yp))[0]
            lam = 10

    else:
        W_lam = 0
        Ws = 0
        lambdas = 0
        lam = 0

    return Ws, lambdas, W_lam, lam, flag
Ejemplo n.º 56
0
def main(argv):

	##################################################################
	# Parse arguments

	fitopt = {0:'gaussian',1:'2nd order polynome'}
	
	from optparse import OptionParser
	
	parser = OptionParser()
	
	parser.add_option(	'--fittype',
						help='Which type of fit will be performed. Options are %r.'%fitopt,
						type='int',
						default=0)

	opt,args = parser.parse_args(argv)

	print 'Will find minimum by %s fitting...'%(fitopt[opt.fittype])
	##################################################################
	# Parameters
	HJD0 = 2450111.5144
	Porb =  0.44267714
	#
	##################################################################
	# Input definition
	_path = os.path.expanduser('~/Documents/analise/CAL87/emap_0305keV_rateall')
	#_cldat = 'cal87_0305keV_rateall.dat.122' #'cal87_0305keV_rateall.dat.122'
	#_cldat = '../cal87_0153250101_b250s_051keV_master_pnm1m2.tfits' #'cal87_0305keV_rateall.dat.122'
	_cldat = '../cal87_0153250101_b250s_0514keV_master_pnm1m2.tfits' #'cal87_0305keV_rateall.dat.122'
	#_clmod = 'cal87_0305keV_rateall.prd.122'
	#
	##################################################################
	# Reading data
	
	#cldat = np.loadtxt(os.path.join(_path,_cldat),unpack=True)
	#clmod = np.loadtxt(os.path.join(_path,_clmod),unpack=True)
	table = pyfits.open(os.path.join(_path,_cldat))
	time_hjd = table[1].data['TIME']/86400.+2450814.5000
	rate_all = table[1].data['RATE_ALL']
	error_all = table[1].data['ERROR_ALL']
	#
	##################################################################
	# Fitting
	
	if opt.fittype == 0:
	
		phase = (time_hjd - HJD0) / Porb
		phase = phase-np.floor(phase)
		phase[phase > 0.5] -= 1.0
		sort = phase.argsort()
		cldat = np.array([phase[sort],rate_all[sort],error_all[sort]])
		func = lambda p,x: p[0] + p[1]*np.exp(-((x-p[2])/p[3])**2.0)
		fitfunc = lambda p,x,y: y - func(p,x)
		
		p0  = [np.mean(cldat[1]),np.min(cldat[1])-np.mean(cldat[1]),1e-1,0.15]
		
		sol,cov,info,mesg,ier = leastsq(fitfunc,
										p0,
										args=(cldat[0],cldat[1]),
										full_output=True)
	
		print sol
		py.errorbar(	cldat[0],
						cldat[1],
						cldat[2],
						fmt='rs:',
						capsize=0)
		py.plot(cldat[0],
				func(sol,cldat[0]),'k-')
	if opt.fittype == 1:
		# Fit parabola
		phase = (time_hjd - HJD0) / Porb
		ciclos = np.unique(np.floor(phase))
		print '# - %i cycles, fitting %i eclipses...'%(len(ciclos),len(ciclos)-1)

		for i in range(len(ciclos)-1):
			print '## - Fitting from phases [%f:%f]'%(ciclos[i+1]-0.5,ciclos[i+1]+0.5)
			mask = np.bitwise_and(phase >ciclos[i+1]-0.5,phase < ciclos[i+1]+0.5)
			cldat = np.array([phase[mask]-ciclos[i+1],rate_all[mask],error_all[mask]])
			mask = np.bitwise_and(cldat[0] > -0.1, cldat[0]<0.1)
			p,residuals,rank,singular_values,rcond = polyfit(cldat[0][mask],
															 cldat[1][mask],
															 deg=2,full=True)
		
			print '# - Bootstraping...'
			ndata = MC_sim(cldat[1][mask],cldat[2][mask],100)
			bootpar = np.array([p])
			bootroots = np.array([roots(p).real])
			for j in range(len(ndata)):
				bp = polyfit( cldat[0][mask],
							 ndata[j],
							 deg=2,full=False)
				bootpar = np.append(bootpar,bp)
				bootroots = np.append(bootroots,np.roots(bp).real)
			bootpar = bootpar.reshape(-1,3)
			print bootpar.shape,bootpar[0]
			
			print p,singular_values
			print roots(p)
			print bootroots.mean(),'+/-',bootroots.std()
			py.subplot(2,len(ciclos)-1,i+1)
			py.errorbar(	cldat[0][mask],
							cldat[1][mask],
							cldat[2][mask],
							fmt='rs:',
							capsize=0)
			py.plot(cldat[0][mask],
					polyval(p,cldat[0][mask]),'k-')
					
			py.subplot(2,len(ciclos)-1,len(ciclos)-1+i+1)
			py.hist(bootroots,bins=40)

		py.show()
		return 0
		
		
		mask = np.bitwise_and(cldat[0] > -0.05, cldat[0]<0.09)
		p,residuals,rank,singular_values,rcond = polyfit(cldat[0][mask],
														 cldat[1][mask],
														 deg=2,full=True)
		py.errorbar(	cldat[0][mask],
						cldat[1][mask],
						cldat[2][mask],
						fmt='rs:',
						capsize=0)
		py.plot(cldat[0][mask],
				polyval(p,cldat[0][mask]),'k-')
		print p,singular_values
		print roots(p)
		
		
		
	#
	##################################################################
	# End
	
	py.show()
	
	return 0
Ejemplo n.º 57
0
def duff_amp_solve(mu = 0.01, k = 0.013, alpha = .2, sigma = (-0.5,.5)):
    sigma = sp.linspace(sigma[0],sigma[1],1000)
    #print(sigma.size)
    #print(sigma)
    a = sp.zeros((sigma.size,3))*1j
    first = 1
    #print(a)
    for idx, sig in enumerate(sigma):
        #print(idx)
        
        p = sp.array([alpha**2, 0, -16./3.*alpha*sig, 0, 64./9.*(mu**2 + sig**2),0,-64./9.*k**2])
        soln = sp.roots(p)
        #print('original soln')
        #print(soln)
        #print(soln)
        #print(sp.sort(soln)[0:5:2])
        sorted_indices = sp.argsort(sp.absolute(soln))
        a[idx,:] = soln[sorted_indices][0:5:2]
        if sum(sp.isreal(a[idx,:])) == 3 and first == 1:
            first = 0
            #if sp.absolute(a[idx,2] - a[idx,1]) < sp.absolute(a[idx,1] - a[idx,0]):
            solns = sp.sort(sp.absolute(a[idx,:]))
            #print(solns)
            if (solns[2] - solns[1]) > (solns[1]-solns[0]):
                ttl = 'Hardening spring'
                softening = False
            else:
                ttl = 'Softening spring'
                softening = True
                #print(solns)
                
            first_bif_index = idx

        if first == 0 and sum(sp.isreal(a[idx,:])) == 1:
            first = 2
            second_bif_index = idx
                
    if softening == True:

        low_sig = sigma[0:second_bif_index]

        low_amp = sp.zeros(second_bif_index)
        low_amp[0:first_bif_index] = sp.absolute(sp.sum(sp.isreal(a[0:first_bif_index,:])*a[0:first_bif_index,:],axis = 1))
        low_amp[first_bif_index:second_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).min(axis = 1)

        med_sig = sigma[first_bif_index:second_bif_index]

        med_amp = sp.sort(sp.absolute(a[first_bif_index:second_bif_index,:]),axis = 1)[:,1]
        
        high_sig = sigma[first_bif_index:]
        high_amp = sp.zeros(sigma.size - first_bif_index)
        high_amp[0:second_bif_index - first_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).max(axis = 1)
        high_amp[second_bif_index - first_bif_index:] = sp.absolute(sp.sum(sp.isreal(a[second_bif_index:,:])*a[second_bif_index:,:],axis = 1))
        
    else:
        
        high_sig = sigma[0:second_bif_index]

        high_amp = sp.zeros(second_bif_index)
        high_amp[0:first_bif_index] = sp.absolute(sp.sum(sp.isreal(a[0:first_bif_index,:])*a[0:first_bif_index,:],axis = 1))
        high_amp[first_bif_index:second_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).max(axis = 1)

        med_sig = sigma[first_bif_index:second_bif_index]

        med_amp = sp.sort(sp.absolute(a[first_bif_index:second_bif_index,:]),axis = 1)[:,1]
        
        low_sig = sigma[first_bif_index:]
        low_amp = sp.zeros(sigma.size - first_bif_index)
        low_amp[0:second_bif_index - first_bif_index] = sp.absolute(a[first_bif_index:second_bif_index,:]).min(axis = 1)
        low_amp[second_bif_index - first_bif_index:] = sp.absolute(sp.sum(sp.isreal(a[second_bif_index:,:])*a[second_bif_index:,:],axis = 1))
        
    plt.plot(low_sig,low_amp,'-b')
    plt.plot(med_sig, med_amp, '--g')
    plt.plot(high_sig,high_amp,'-r')

    plt.title(ttl)
    plt.xlabel('$\sigma$')
    plt.ylabel('a')
    return 
Ejemplo n.º 58
0
def lars_regression_noise(Yp, X, positive, noise,verbose=False):
    
    """
     Run LARS for regression problems with LASSO penalty, with optional positivity constraints
     Author: Andrea Giovannucci. Adapted code from Eftychios Pnevmatikakis
    
    
     Input Parameters:
       Yp:          Yp[:,t] is the observed data at time t
       X:           the regresion problem is Yp=X*W + noise
       maxcomps:    maximum number of active components to allow
       positive:    a flag to enforce positivity
       noise:       the noise of the observation equation. if it is not
                    provided as an argument, the noise is computed from the
                    variance at the end point of the algorithm. The noise is
                    used in the computation of the Cp criterion.
    
    
     Output Parameters:
       Ws: weights from each iteration
       lambdas: lambda_ values at each iteration
       TODO: W_lam, lam, flag
       Cps: C_p estimates
       last_break:     last_break(m) == n means that the last break with m non-zero weights is at Ws(:,:,n)
    """
    #%%
    
    #verbose=true;
    
    
    
    k=1;    
    Yp=np.squeeze(np.asarray(Yp))
    
    Yp=np.expand_dims(Yp,axis=1) #necessary for matrix multiplications
    
    _,T = np.shape(Yp); # of time steps
    _,N = np.shape(X); # of compartments
    
    maxcomps = N;    
    W = np.zeros((N,k));
    active_set = np.zeros((N,k));
    visited_set = np.zeros((N,k));    
    lambdas = [];  
    Ws=[] #=np.zeros((W.shape[0],W.shape[1],maxcomps));  # Just preallocation. Ws may end with more or less than maxcomp columns       
    r = np.expand_dims(np.dot(X.T,Yp.flatten()),axis=1)       # N-dim vector
    M = np.dot(-X.T,X);            # N x N matrix 
    
    #%% begin main loop    
    i = 0;
    flag = 0;
    while 1:       
        if flag == 1:
            W_lam = 0
            break;
    #% calculate new gradient component if necessary    
        if i>0 and new>=0 and visited_set[new] ==0: # AG NOT CLEAR HERE    
            visited_set[new] =1;    #% remember this direction was computed    
 
    #% Compute full gradient of Q     
        dQ = r + np.dot(M,W);
            
    #% Compute new W
        if i == 0:            
            if positive:
                dQa = dQ
            else:
                dQa = np.abs(dQ)            
            lambda_, new = np.max(dQa),np.argmax(dQa)
        
            if lambda_ < 0:
                print 'All negative directions!'
                break                        
        else:
    
            #% calculate vector to travel along                    
            avec, gamma_plus, gamma_minus = calcAvec(new, dQ, W, lambda_, active_set, M, positive)       
            
           # % calculate time of travel and next new direction                   
            if new==-1:                              # % if we just dropped a direction we don't allow it to emerge 
                if dropped_sign == 1:               # % with the same sign
                    gamma_plus[dropped] = np.inf;
                else:
                    gamma_minus[dropped] = np.inf;
    
            gamma_plus[active_set == 1] = np.inf       #% don't consider active components 
            gamma_plus[gamma_plus <= 0] = np.inf       #% or components outside the range [0, lambda_]
            gamma_plus[gamma_plus> lambda_] = np.inf
            gp_min, gp_min_ind = np.min(gamma_plus),np.argmin(gamma_plus)
    
            if positive:
                gm_min = np.inf;                         #% don't consider new directions that would grow negative
            else:
                gamma_minus[active_set == 1] = np.inf            
                gamma_minus[gamma_minus> lambda_] =np.inf
                gamma_minus[gamma_minus <= 0] = np.inf
                gm_min, gm_min_ind = np.min(gamma_minus),np.argmin(gamma_minus)
  
            [g_min, which] = np.min(gp_min),np.argmin(gp_min)
            
            if g_min == np.inf:               #% if there are no possible new components, try move to the end
                g_min = lambda_;            #% This happens when all the components are already active or, if positive==1, when there are no new positive directions 
   
            #% LARS check  (is g_min*avec too large?)
            gamma_zero = -W[active_set == 1]  / np.squeeze(avec);
            gamma_zero_full = np.zeros((N,k));
            gamma_zero_full[active_set == 1] = gamma_zero;
            gamma_zero_full[gamma_zero_full <= 0] = np.inf;
            gz_min, gz_min_ind = np.min(gamma_zero_full),np.argmin(gamma_zero_full)
            
            if gz_min < g_min:       
#                print 'check_here'
                if verbose:
                   print 'DROPPING active weight:' + str(gz_min_ind)
                
                active_set[gz_min_ind] = 0;
                dropped = gz_min_ind;
                dropped_sign = np.sign(W[dropped]);
                W[gz_min_ind] = 0;
                avec = avec[gamma_zero != gz_min];
                g_min = gz_min;
                new=-1 # new = 0;
                
                
            elif g_min < lambda_:            
                if  which == 0:
                    new = gp_min_ind;
                    if verbose:
                        print 'new positive component:' + str(new)
                    
                else:
                    new = gm_min_ind;
                    print 'new negative component:' +  str(new)
                                   
            W[active_set == 1] = W[active_set == 1] + np.dot(g_min,np.squeeze(avec));
            
            if positive:
                if any(W<0):
                    #min(W);
                    flag = 1;
                    #%error('negative W component');
            
            lambda_ = lambda_ - g_min;    
    
    #%  Update weights and lambdas 
            
        lambdas.append(lambda_);    
        Ws.append(W.copy())
        
    #    print Ws
        if len((Yp-np.dot(X,W)).shape)>2:
            res = scipy.linalg.norm(np.squeeze(Yp-np.dot(X,W)),'fro')**2;
        else:
            res = scipy.linalg.norm(Yp-np.dot(X,W),'fro')**2;
        
    #% Check finishing conditions                
        if lambda_ ==0 or (new>=0 and np.sum(active_set) == maxcomps) or (res < noise):
            if verbose:
                print 'end. \n'        
            break
    
        #%   
        if new>=0:        
            active_set[new] = 1
                
        i = i + 1
    
    Ws_old=Ws
    # end main loop 
    
    #%% final calculation of mus
    Ws=np.asarray(np.swapaxes(np.swapaxes(Ws_old,0,1),1,2))
    if flag == 0:
        if i > 0:
            Ws= np.squeeze(Ws[:,:,:len(lambdas)]);
            w_dir = -(Ws[:,i] - Ws[:,i-1])/(lambdas[i]-lambdas[i-1]);
            Aw = np.dot(X,w_dir);
            y_res = np.squeeze(Yp) - np.dot(X,Ws[:,i-1] + w_dir*lambdas[i-1]);
            ld = scipy.roots([scipy.linalg.norm(Aw)**2,-2*np.dot(Aw.T,y_res),np.dot(y_res.T,y_res)-noise]);
            lam = ld[np.intersect1d(np.where(ld>lambdas[i]),np.where(ld<lambdas[i-1]))];
            if len(lam) == 0  or np.any(lam)<0 or np.any(~np.isreal(lam)):
                lam = np.array([lambdas[i]]);
            
            W_lam = Ws[:,i-1] + np.dot(w_dir,lambdas[i-1]-lam[0]);
        else:
            warn('LARS REGRESSION NOT SOLVABLE, USING NN LEAST SQUARE')
            W_lam=scipy.optimize.nnls(X,Yp)
#            problem = picos.Problem(X,Yp)
#            W_lam = problem.add_variable('W_lam', X.shape[1])
#            problem.set_objective('min', 1|W_lam)
#            problem.add_constraint(W_lam >= 0)
#            problem.add_constraint(picos.norm(matrix(Yp.astype(np.float))-matrix(X.astype(np.float))*W_lam,2)<=np.sqrt(noise))
#            sel_solver = []
#            problem.solver_selection()
#            problem.solve(verbose=True)
            
            
    #        cvx_begin quiet
    #            variable W_lam(size(X,2));
    #            minimize(sum(W_lam));
    #            subject to
    #                W_lam >= 0;
    #                norm(Yp-X*W_lam)<= sqrt(noise);
    #        cvx_end
            lam = 10;
        
    else:
        W_lam = 0;
        Ws = 0;
        lambdas = 0; 
        lam = 0;
        
    return Ws, lambdas, W_lam, lam, flag
Ejemplo n.º 59
0
        def find_roots(wl, epsilon, alpha, beta):
            """Find roots of characteristic equation.

            Given a wavelength, a 3x3 tensor epsilon and the tangential components
            of the wavevector k = (alpha,beta,gamma_i), returns the 4 possible
            gamma_i, i = 1,2,3,4 that satisfy the boundary conditions.
            """

            omega = 2.0 * S.pi * c / wl
            K = omega ** 2 * mu0 * epsilon

            k0 = 2.0 * S.pi / wl
            K /= k0 ** 2
            alpha /= k0
            beta /= k0

            alpha2 = alpha ** 2
            alpha3 = alpha ** 3
            alpha4 = alpha ** 4
            beta2 = beta ** 2
            beta3 = beta ** 3
            beta4 = beta ** 4

            coeff = [
                K[2, 2],
                alpha * (K[0, 2] + K[2, 0]) + beta * (K[1, 2] + K[2, 1]),
                alpha2 * (K[0, 0] + K[2, 2])
                + alpha * beta * (K[1, 0] + K[0, 1])
                + beta2 * (K[1, 1] + K[2, 2])
                + (K[0, 2] * K[2, 0] + K[1, 2] * K[2, 1] - K[0, 0] * K[2, 2] - K[1, 1] * K[2, 2]),
                alpha3 * (K[0, 2] + K[2, 0])
                + beta3 * (K[1, 2] + K[2, 1])
                + alpha2 * beta * (K[1, 2] + K[2, 1])
                + alpha * beta2 * (K[0, 2] + K[2, 0])
                + alpha * (K[0, 1] * K[1, 2] + K[1, 0] * K[2, 1] - K[0, 2] * K[1, 1] - K[2, 0] * K[1, 1])
                + beta * (K[0, 1] * K[2, 0] + K[1, 0] * K[0, 2] - K[0, 0] * K[1, 2] - K[0, 0] * K[2, 1]),
                alpha4 * (K[0, 0])
                + beta4 * (K[1, 1])
                + alpha3 * beta * (K[0, 1] + K[1, 0])
                + alpha * beta3 * (K[0, 1] + K[1, 0])
                + alpha2 * beta2 * (K[0, 0] + K[1, 1])
                + alpha2 * (K[0, 1] * K[1, 0] + K[0, 2] * K[2, 0] - K[0, 0] * K[2, 2] - K[0, 0] * K[1, 1])
                + beta2 * (K[0, 1] * K[1, 0] + K[1, 2] * K[2, 1] - K[0, 0] * K[1, 1] - K[1, 1] * K[2, 2])
                + alpha * beta * (K[0, 2] * K[2, 1] + K[2, 0] * K[1, 2] - K[0, 1] * K[2, 2] - K[1, 0] * K[2, 2])
                + K[0, 0] * K[1, 1] * K[2, 2]
                - K[0, 0] * K[1, 2] * K[2, 1]
                - K[1, 0] * K[0, 1] * K[2, 2]
                + K[1, 0] * K[0, 2] * K[2, 1]
                + K[2, 0] * K[0, 1] * K[1, 2]
                - K[2, 0] * K[0, 2] * K[1, 1],
            ]

            gamma = S.roots(coeff)
            tmp = S.sort_complex(gamma)
            gamma = tmp[[3, 0, 2, 1]]  # convention

            k = k0 * S.array([alpha * S.ones(gamma.shape), beta * S.ones(gamma.shape), gamma]).T
            v = S.zeros((4, 3), dtype=complex)

            for i, g in enumerate(gamma):

                H = K + [
                    [-beta2 - g ** 2, alpha * beta, alpha * g],
                    [alpha * beta, -alpha2 - g ** 2, beta * g],
                    [alpha * g, beta * g, -alpha2 - beta2],
                ]
                v[i, :] = [
                    (K[1, 1] - alpha2 - g ** 2) * (K[2, 2] - alpha2 - beta2) - (K[1, 2] + beta * g) ** 2,
                    (K[1, 2] + beta * g) * (K[2, 0] + alpha * g)
                    - (K[0, 1] + alpha * beta) * (K[2, 2] - alpha2 - beta2),
                    (K[0, 1] + alpha * beta) * (K[1, 2] + beta * g)
                    - (K[0, 2] + alpha * g) * (K[1, 1] - alpha2 - g ** 2),
                ]

            p3 = v[0, :]
            p3 /= norm(p3)
            p4 = v[1, :]
            p4 /= norm(p4)
            p1 = S.cross(p3, k[0, :])
            p1 /= norm(p1)
            p2 = S.cross(p4, k[1, :])
            p2 /= norm(p2)

            p = S.array([p1, p2, p3, p4])
            q = wl / (2.0 * S.pi * mu0 * c) * S.cross(k, p)

            return k, p, q