Example #1
0
def trunc_tuple(t, tolerance):
    """

    Apply the purify (trunc) function to a tuple or array.

    """
    return array(tuple([trunc(c, tolerance) for c in t]), Complex)
Example #2
0
    def test_basic_matrix(self):

        """This test is rather monolithic, but at least it implements
        a concrete example that we can compare with our earlier
        computations.  It also tests the mutual-inverse character of
        the equi-to-diag and diag-to-equi transformations."""

        tolerance = 5.0e-15
        eig = self.diag.compute_eigen_system(self.h_2, tolerance)
        self.diag.compute_diagonal_change()

        eq_type = eig.get_equilibrium_type()
        self.assertEquals(eq_type, self.eq_type)

        eigs = [pair.val for pair in eig.get_raw_eigen_value_vector_pairs()]
        for actual, expected in zip(eigs, self.eig_vals):
            self.assert_(abs(actual-expected) < tolerance, (actual, expected))

        mat = self.diag.get_matrix_diag_to_equi()
        assert self.diag.matrix_is_symplectic(mat)

        sub_diag_into_equi = self.diag.matrix_as_vector_of_row_polynomials(mat)
        mat_inv = LinearAlgebra.inverse(MLab.array(mat))
        sub_equi_into_diag = self.diag.matrix_as_vector_of_row_polynomials(mat_inv)
        h_diag_2 = self.h_2.substitute(sub_diag_into_equi)
        h_2_inv = h_diag_2.substitute(sub_equi_into_diag)
        self.assert_(h_2_inv) #non-zero
        self.assert_(not h_2_inv.is_constant())
        self.assert_(self.lie.is_isograde(h_2_inv, 2))
        self.assert_((self.h_2-h_2_inv).l1_norm() < 1.0e-14)
        comp = Complexifier(self.diag.get_lie_algebra(), eq_type)
        sub_complex_into_real = comp.calc_sub_complex_into_real()
        h_comp_2 = h_diag_2.substitute(sub_complex_into_real)
        h_comp_2 = h_comp_2.with_small_coeffs_removed(tolerance)
        self.assert_(self.lie.is_diagonal_polynomial(h_comp_2))
Example #3
0
def trunc_tuple(t, tolerance):
    """

    Apply the purify (trunc) function to a tuple or array.

    """
    return array(tuple([trunc(c, tolerance) for c in t]), Complex)
Example #4
0
def arrow(x0,y0,x1,y1,color=0,ang=45.0,height=6,width=1.5,lc=None):
    """Draw an arrow.

    Description:

      Draw an arrow from (x0,y0) to (x1,y1) in the current coordinate system.

    Inputs:

      x0, y0 -- The beginning point.
      x1, y1 -- Then ending point.
      color -- The color of the arrowhead.  Number represents an index
               in the current palette or a negative number or a spelled
               out basic color.
      lc -- The color of the line (same as color by default).
      ang -- The angle of the arrowhead.
      height -- The height of the arrowhead in points.
      width -- The width of the arrow line in points.
    """
    if lc is None:
        lc = color
    if type(lc) is types.StringType:
        lc = _colornum[lc]
    if type(color) is types.StringType:
        color = _colornum[color]
    vp = gist.viewport()
    plotlims = gist.limits()
    gist.limits(plotlims)
    conv_factorx = (vp[1]-vp[0]) / (plotlims[1]-plotlims[0])
    conv_factory = (vp[3]-vp[2]) / (plotlims[3]-plotlims[2])
    ang = ang*pi/180
    height = height*points
    hypot = height / cos(ang)
    difx = (x1 - x0) * conv_factorx
    dify = (y1 - y0) * conv_factory
    theta = arctan2(dify,difx) + pi
    tha = theta + ang
    thb = theta - ang
    x1a = x1 + hypot*cos(tha) / conv_factorx
    x1b = x1 + hypot*cos(thb) / conv_factorx
    y1a = y1 + hypot*sin(tha) / conv_factory
    y1b = y1 + hypot*sin(thb) / conv_factory
    gist.pldj([x0],[y0],[x1],[y1],color=lc,width=width)
    gist.plfp(array([color],'B'),[y1,y1a,y1b],[x1,x1a,x1b],[3])
    return
Example #5
0
    def test_basic_matrix(self):
        """This test is rather monolithic, but at least it implements
        a concrete example that we can compare with our earlier
        computations.  It also tests the mutual-inverse character of
        the equi-to-diag and diag-to-equi transformations."""

        tolerance = 5.0e-15
        eig = self.diag.compute_eigen_system(self.h_2, tolerance)
        self.diag.compute_diagonal_change()

        eq_type = eig.get_equilibrium_type()
        self.assertEquals(eq_type, self.eq_type)

        eigs = [pair.val for pair in eig.get_raw_eigen_value_vector_pairs()]
        for actual, expected in zip(eigs, self.eig_vals):
            self.assert_(
                abs(actual - expected) < tolerance, (actual, expected))

        mat = self.diag.get_matrix_diag_to_equi()
        assert self.diag.matrix_is_symplectic(mat)

        sub_diag_into_equi = self.diag.matrix_as_vector_of_row_polynomials(mat)
        mat_inv = LinearAlgebra.inverse(MLab.array(mat))
        sub_equi_into_diag = self.diag.matrix_as_vector_of_row_polynomials(
            mat_inv)
        h_diag_2 = self.h_2.substitute(sub_diag_into_equi)
        h_2_inv = h_diag_2.substitute(sub_equi_into_diag)
        self.assert_(h_2_inv)  #non-zero
        self.assert_(not h_2_inv.is_constant())
        self.assert_(self.lie.is_isograde(h_2_inv, 2))
        self.assert_((self.h_2 - h_2_inv).l1_norm() < 1.0e-14)
        comp = Complexifier(self.diag.get_lie_algebra(), eq_type)
        sub_complex_into_real = comp.calc_sub_complex_into_real()
        h_comp_2 = h_diag_2.substitute(sub_complex_into_real)
        h_comp_2 = h_comp_2.with_small_coeffs_removed(tolerance)
        self.assert_(self.lie.is_diagonal_polynomial(h_comp_2))
Example #6
0
 def compare_matrix(dia, mat1, mat2, comment):
     print dia.matrix_norm(array(mat1, Float) - array(mat2, Float)), comment
Example #7
0
def compare_normal_form(dir_name1, dir_name2, grade=4):
    def compare_matrix(dia, mat1, mat2, comment):
        print dia.matrix_norm(array(mat1, Float) - array(mat2, Float)), comment

    print "Comparing data in Normal form files upto grade %d" % (grade)
    print
    print "Reading python data"

    first = NormalFormData(dir_name1, is_xxpp_format=True, degree=grade)

    ring = PolynomialRing(first.equi_to_tham.n_vars())

    print
    print "Comparing python data with cpp files upto grade %d" % (grade)
    print "l_infinity_norm \t l1_norm \t\t polynomials"
    ringIO = PolynomialRingIO(ring)
    file_istr = open("hill_l1_18--norm_to_diag.vpol", 'r')
    pv_norm_to_diag = ringIO.read_sexp_vector_of_polynomials(file_istr)
    compare_poly_vec(first.norm_to_diag,
                     pv_norm_to_diag,
                     "norm_to_diag",
                     grade=grade - 1)
    file_istr = open("hill_l1_18--diag_to_norm.vpol", 'r')
    pv_diag_to_norm = ringIO.read_sexp_vector_of_polynomials(file_istr)
    compare_poly_vec(first.diag_to_norm,
                     pv_diag_to_norm,
                     "diag_to_norm",
                     grade=grade - 1)
    print
    print "Reading mathematica data"
    n_ints = len(first.ints_to_freq)
    # get the frequencies to find the order of the planes
    order_f = [poly((0.0, ) * n_ints) for poly in first.ints_to_freq]
    second = NormalFormData(dir_name2,
                            order_f=order_f,
                            is_xxpp_format=True,
                            degree=grade)

    from Diagonal import Diagonalizer
    lie = LieAlgebra(n_ints)
    dia = Diagonalizer(lie)
    grade_ints = grade / 2
    dia.matrix_is_symplectic(array(first.diag_to_equi, Float))
    dia.matrix_is_symplectic(array(second.diag_to_equi, Float))
    dia.matrix_is_symplectic(array(first.equi_to_diag, Float))
    dia.matrix_is_symplectic(array(second.equi_to_diag, Float))

    # For the case develloped, Hill, there is a 45deg rotation between the
    # diagonalised coordinates in each of the centre planes. Thus:
    # These matrices are different
    #compare_matrix(dia, first.diag_to_equi, second.diag_to_equi, "diag_to_equi")
    #compare_matrix(dia, first.equi_to_diag, second.equi_to_diag, "equi_to_diag")
    # We neeed to convert between the diagonal planes and back to
    # compare the nonlinear normalisation plolynomials
    # second.diag_to_first.diag = first.diag_in_terms_of_second.diag =
    fd_in_sd = dia.matrix_as_vector_of_row_polynomials(
        matrixmultiply(array(first.equi_to_diag, Float),
                       array(second.diag_to_equi, Float)))
    sd_in_fd = dia.matrix_as_vector_of_row_polynomials(
        matrixmultiply(array(second.equi_to_diag, Float),
                       array(first.diag_to_equi, Float)))

    print
    print "Comparing mathematica data with cpp files upto grade %d" % (grade -
                                                                       1)
    compare_poly_vec(pv_norm_to_diag,
                     poly_vec_substitute(
                         fd_in_sd,
                         poly_vec_substitute(
                             poly_vec_isograde(second.norm_to_diag, grade - 1),
                             sd_in_fd)),
                     "norm_to_diag",
                     grade=grade - 1)
    print "Comparing mathematica data with cpp files upto grade %d" % (grade -
                                                                       1)
    compare_poly_vec(pv_diag_to_norm,
                     poly_vec_substitute(
                         fd_in_sd,
                         poly_vec_substitute(
                             poly_vec_isograde(second.diag_to_norm, grade - 1),
                             sd_in_fd)),
                     "diag_to_norm",
                     grade=grade - 1)

    print
    print "Comparing mathematica data with python upto grade %d" % (grade)

    compare_poly(first.equi_to_tham,
                 second.equi_to_tham,
                 "equi_to_tham",
                 grade=grade)
    compare_poly_vec(first.ints_to_freq,
                     second.ints_to_freq,
                     "ints_to_freq",
                     grade=grade_ints - 1)
    ring_ints = PolynomialRing(second.ints_to_tham.n_vars())
    poly_2 = ring_ints.isograde(second.ints_to_tham, 0, up_to=grade_ints + 1)
    compare_poly(first.ints_to_tham, poly_2, "ints_to_tham")
    compare_poly_vec(first.norm_to_ints,
                     second.norm_to_ints,
                     "norm_to_ints",
                     grade=grade)

    second.diag_to_norm = poly_vec_isograde(second.diag_to_norm, grade)
    second.norm_to_diag = poly_vec_isograde(second.norm_to_diag, grade)
    compare_poly_vec(first.norm_to_diag,
                     poly_vec_substitute(
                         fd_in_sd,
                         poly_vec_substitute(second.norm_to_diag, sd_in_fd)),
                     "norm_to_diag",
                     grade=grade - 1)
    compare_poly_vec(first.diag_to_norm,
                     poly_vec_substitute(
                         fd_in_sd,
                         poly_vec_substitute(second.diag_to_norm, sd_in_fd)),
                     "diag_to_norm",
                     grade=grade - 1)
    compare_poly_vec(first.diag_to_norm,
                     second.diag_to_norm,
                     "diag_to_norm",
                     grade=grade - 1)
    compare_poly_vec(first.diag_to_norm,
                     poly_vec_substitute(
                         fd_in_sd,
                         poly_vec_substitute(second.diag_to_norm, sd_in_fd)),
                     "diag_to_norm",
                     grade=grade)
    compare_poly_vec(first.equi_to_tvec,
                     second.equi_to_tvec,
                     "equi_to_tvec",
                     grade=grade - 1)
 def compare_matrix(dia, mat1, mat2, comment):
     print dia.matrix_norm(array(mat1, Float)-array(mat2, Float)), comment
def compare_normal_form(dir_name1, dir_name2, grade=4):
    def compare_matrix(dia, mat1, mat2, comment):
        print dia.matrix_norm(array(mat1, Float)-array(mat2, Float)), comment

    print "Comparing data in Normal form files upto grade %d" %(grade)
    print
    print "Reading python data"

    first = NormalFormData(dir_name1, is_xxpp_format=True, degree=grade)

    ring = PolynomialRing(first.equi_to_tham.n_vars())
    
    print
    print "Comparing python data with cpp files upto grade %d" %(grade)
    print "l_infinity_norm \t l1_norm \t\t polynomials"
    ringIO = PolynomialRingIO(ring)
    file_istr = open("hill_l1_18--norm_to_diag.vpol", 'r')
    pv_norm_to_diag = ringIO.read_sexp_vector_of_polynomials(file_istr)
    compare_poly_vec(first.norm_to_diag, 
                     pv_norm_to_diag, "norm_to_diag", grade=grade-1)
    file_istr = open("hill_l1_18--diag_to_norm.vpol", 'r')
    pv_diag_to_norm = ringIO.read_sexp_vector_of_polynomials(file_istr)
    compare_poly_vec(first.diag_to_norm,
                     pv_diag_to_norm, "diag_to_norm", grade=grade-1)
    print
    print "Reading mathematica data"
    n_ints = len(first.ints_to_freq)
    # get the frequencies to find the order of the planes
    order_f=[poly((0.0,)*n_ints) for poly in first.ints_to_freq]
    second = NormalFormData(dir_name2, order_f=order_f,
                            is_xxpp_format=True, degree=grade)
    
    from Diagonal import Diagonalizer
    lie = LieAlgebra(n_ints)
    dia = Diagonalizer(lie)
    grade_ints = grade / 2
    dia.matrix_is_symplectic(array(first.diag_to_equi, Float))
    dia.matrix_is_symplectic(array(second.diag_to_equi, Float))
    dia.matrix_is_symplectic(array(first.equi_to_diag, Float))
    dia.matrix_is_symplectic(array(second.equi_to_diag, Float))

    # For the case develloped, Hill, there is a 45deg rotation between the
    # diagonalised coordinates in each of the centre planes. Thus:
    # These matrices are different
    #compare_matrix(dia, first.diag_to_equi, second.diag_to_equi, "diag_to_equi")
    #compare_matrix(dia, first.equi_to_diag, second.equi_to_diag, "equi_to_diag")
    # We neeed to convert between the diagonal planes and back to
    # compare the nonlinear normalisation plolynomials
    # second.diag_to_first.diag = first.diag_in_terms_of_second.diag =
    fd_in_sd = dia.matrix_as_vector_of_row_polynomials(matrixmultiply(
        array(first.equi_to_diag, Float),array(second.diag_to_equi, Float)))
    sd_in_fd = dia.matrix_as_vector_of_row_polynomials(matrixmultiply(
        array(second.equi_to_diag, Float),array(first.diag_to_equi, Float)))

    print
    print "Comparing mathematica data with cpp files upto grade %d" %(grade-1)
    compare_poly_vec(pv_norm_to_diag,
                     poly_vec_substitute(fd_in_sd, poly_vec_substitute(
        poly_vec_isograde(second.norm_to_diag, grade-1), sd_in_fd)),
                     "norm_to_diag", grade=grade-1)
    print "Comparing mathematica data with cpp files upto grade %d" %(grade-1)
    compare_poly_vec(pv_diag_to_norm,
                     poly_vec_substitute(fd_in_sd, poly_vec_substitute(
        poly_vec_isograde(second.diag_to_norm, grade-1), sd_in_fd)),
                     "diag_to_norm", grade=grade-1)

    print
    print "Comparing mathematica data with python upto grade %d" %(grade)

    compare_poly(first.equi_to_tham, second.equi_to_tham,
                 "equi_to_tham", grade=grade)
    compare_poly_vec(first.ints_to_freq , second.ints_to_freq , "ints_to_freq",
                     grade=grade_ints-1)
    ring_ints = PolynomialRing(second.ints_to_tham.n_vars())
    poly_2 = ring_ints.isograde(second.ints_to_tham, 0, up_to=grade_ints+1)
    compare_poly(first.ints_to_tham , poly_2 , "ints_to_tham")
    compare_poly_vec(first.norm_to_ints , second.norm_to_ints ,
                     "norm_to_ints", grade=grade)

    second.diag_to_norm = poly_vec_isograde(second.diag_to_norm, grade)
    second.norm_to_diag = poly_vec_isograde(second.norm_to_diag, grade)
    compare_poly_vec(first.norm_to_diag, 
                     poly_vec_substitute(fd_in_sd, poly_vec_substitute(
        second.norm_to_diag, sd_in_fd)), "norm_to_diag", grade=grade-1)
    compare_poly_vec(first.diag_to_norm,
                     poly_vec_substitute(fd_in_sd, poly_vec_substitute(
        second.diag_to_norm, sd_in_fd)), "diag_to_norm", grade=grade-1)
    compare_poly_vec(first.diag_to_norm,
                     second.diag_to_norm,"diag_to_norm", grade=grade-1)
    compare_poly_vec(first.diag_to_norm,
                     poly_vec_substitute(fd_in_sd, poly_vec_substitute(
        second.diag_to_norm, sd_in_fd)), "diag_to_norm", grade=grade)
    compare_poly_vec(first.equi_to_tvec,
                     second.equi_to_tvec,"equi_to_tvec", grade=grade-1)
Example #10
0
def imag_part_of_vector(vec):
    """Extract pure imaginary part of complex vector."""
    return array(tuple([imag_part_of_scalar(elt) for elt in vec]), Float)
Example #11
0
def real_part_of_vector(vec):
    """Extract real vector part of complex vector."""
    return array(tuple([real_part_of_scalar(elt) for elt in vec]), Float)
Example #12
0
    def _compute_symplectic_matrix_diag_to_equi(self):
        """

        Construct the change of coordinates between the equilibrium
        and real-diagonal coordinates.

        Using the (generally complex) eigenvectors, corresponding to
        the quadratic part of the Hamiltonian, we build a real
        symplectic linear coordinate transformation on the phase space
        (expressed as a matrix), under which the quadratic part is
        transformed into real normal form.

        It is important to note that any non-zero multiple of an
        eigenvector is also an eigenvector.  Therefore, although
        certain eigenvalues (those corresponding to centres) will come
        in pure imaginary complex conjugate pairs, the assocaited
        eigenvectors need not be complex conjugate pairs --- although,
        we could express them as such by multiplication by suitable
        complex scale factors --- instead, we may have any complex
        (including pure-imaginary) multiple of the complex conjugate
        eigenvector.

        Care must therefore be taken in the choice of the eigenvectors
        for the symplectic matrix, especially in the case where the
        original system already contains subsystems that are in real
        normal form.

        To cope with the above, we use the following scheme:

         1. In the case of a saddle (pure real +/- eigenvalues, $(+e,
         -e)$) we simply use whatever eigenvectors, $(v_0, v_1)$, we
         are given and scale (via a real scale factor) these suitably
         to give a real symplectic subsystem.

         2. In the case of a centre (pure imaginary complex conjugate
            pair of eigenvalues), we denote the given eigenvectors by
            $v_0,v_1$.  We then use $v_0':=\re(v_0)$ and
            $v_1':=\im(v_0)$, i.e., we only use one of the complex
            eigenvectors, taking its real and imaginary parts.  Again,
            this choice of real vectors will be suitably scaled so as
            to give a symplectic subsystem.

        It can be confirmed that the action of the linearised version
        of Hamilton's equations on the above choice of real vectors
        spans the same two-dimensional subspace as on the original
        complex ones.

        The chosen vectors form the columns of a matrix $M$.  Given a
        vector in the real diagonal coordinate system, $x_{dr}$, one
        can then compute the equilibrium coordinate system vector from
        $Mx_{dr}=x_{er}$.  So the matrix is the transformation from
        DIAG to EQUI.

        todo: In the case of pairs of zero eigenvalues, perhaps we should
        emit an error, insisting that the user first projects (via a
        momentum-independent projector) to a subspace of the non-null
        space?

        """
        logger.info('Constructing symplectic change:')
        pm_val_vec_pairs = self._eig.plus_minus_pairs
        rearranged_pairs = []
        columns = []
        for i in xrange(0, self.dof()):
            i0 = 2 * i
            i1 = i0 + 1
            plus, minus = pm_val_vec_pairs[i]
            if self._eig.equilibrium_type[i] == 's':
                logger.info('Saddle-type eigenvalues')
                a = real_part_of_vector(plus.vec)  #real anyway
                b = real_part_of_vector(minus.vec)  #real anyway
            else:
                if self._eig.equilibrium_type[i] == 'c':
                    logger.info('Centre-type eigenvalues')
                    a = real_part_of_vector(plus.vec)
                    b = imag_part_of_vector(plus.vec)  #N.B. *same* vector!
                else:
                    logger.info('Zero-type eigenvalues')
                    assert (self._eig.equilibrium_type[i] == '0')
                    #todo: assert imag part is close to zero
                    #todo: assert plus close to minus
                    assert 0, 'do something clever to original hamiltonian, please'
            #logger.info('Original eigenvectors:')
            #logger.info(plus.vec)
            #logger.info(minus.vec)
            #logger.info('Choice of real vectors spanning real subspace:')
            #logger.info(a)
            #logger.info(b)
            c = 0.0
            for k in xrange(0, self.dof()):
                k0 = 2 * k
                k1 = k0 + 1
                c += (a[k0] * b[k1] - a[k1] * b[k0])
            if (abs(c) < 1.0e-12):
                assert (self._eig.equilibrium_type[i] == '0')
                assert 0, 'do something clever to original hamiltonian, please'
            else:
                if c < 0.0:
                    if self._eig.equilibrium_type[i] == 's':
                        a_final = a
                        b_final = -b
                        c_final = -c  #ADB!
                        logger.info('Negative Multiplier in saddle: %s',
                                    c_final)
                        logger.info('Negating second vector')
                    else:
                        #Swapping pairs to make symplectic matrix:
                        rearranged_pairs.append((minus, plus))
                        a_final = b
                        b_final = a
                        c_final = -c  #ADB!
                        logger.info('Negative Multiplier in centre: %s',
                                    c_final)
                        logger.info('NEGATIVE EIGENVALUE, Swap two vectors')
                else:
                    rearranged_pairs.append((plus, minus))
                    a_final = a
                    b_final = b
                    c_final = +c  #ADB!
            logger.info('Multiplier present in eigenvector matrix: %s',
                        c_final)
            scale = +pow(1.0 / c_final, 0.5)  #+/- #ADB!
            logger.info('Scale factor to produce symplectic matrix: %s', scale)
            columns.append(scale * a_final)
            columns.append(scale * b_final)
        self.final_pairs = rearranged_pairs
        #we must transpose the result, since arrays are created row-wise:
        mat = transpose(array(columns, Float))
        #logger.info('Candidate symplectic matrix')
        #logger.info(mat)
        assert self.matrix_is_symplectic(mat)
        self.matrix_diag_to_equi = mat
Example #13
0
def subplot(Numy,Numx,win=0,pw=None,ph=None,hsep=100,vsep=100,color='black',frame=0,fontsize=8,font=None,ticks=1,land=0):
    # Use gist.plsys to change coordinate systems

    # all inputs (except fontsize) given as pixels, gist wants
    #  things in normalized device
    #  coordinate.  Window is brought up with center of window at
    #  center of 8.5 x 11 inch page: in landscape mode (5.25, 4.25)
    #  or at position (4.25,6.75) for portrait mode
    msg = 1
    if pw is None:
        pw = Numx*300
        msg = 0
    if ph is None:
        ph = Numy*300
        msg = 0
    if land:
        maxwidth=min(_maxwidth,11*_dpi)
        maxheight=min(_maxheight,8.5*_dpi)
    else:
        maxwidth=min(_maxwidth,8.5*_dpi)
        maxheight=min(_maxheight,11*_dpi)

    printit = 0
    if ph > maxheight:
        ph = maxheight
        printit = 1
    if pw > maxwidth:
        pw = maxwidth
        printit = 1

    if _dpi != 100:
        fontsize = 12
    conv = inches *1.0 / _dpi  # multiply by this factor to convert pixels to
                              # NDC

    if printit and msg:
        message = "Warning: Requested height and width too large.\n"
        message +="Changing to %d x %d" % (pw,ph)
        print message

    # Now we've got a suitable height and width

    if land:
        cntr = array([5.5,4.25])*_dpi  # landscape
    else:
        if sys.platform == 'win32':
            cntr = array([4.25,6.75])*_dpi  # portrait
        else:
            cntr = array([4.25,5.5])*_dpi

    Yspace = ph/float(Numy)*conv
    Xspace = pw/float(Numx)*conv

    hsep = hsep * conv
    vsep = vsep * conv
    ytop = (cntr[1]+ph/2.0)*conv
    xleft = (cntr[0]-pw/2.0)*conv

    if type(color) is types.StringType:
        color = _colornum[color]
    systems=[]
    ind = -1
    for nY in range(Numy):
        ystart = ytop - (nY+1)*Yspace
        for nX in range(Numx):
            xstart = xleft + nX*Xspace
            systems.append({})
            systems[-1]['viewport'] = [xstart+hsep/2.0,xstart+Xspace-hsep/2.0,ystart+vsep/2.0,ystart+Yspace-vsep/2.0]
            if font is not None or fontsize is not None:
                _chng_font(systems[-1],font,fontsize)
            if color != -3 or frame != 0:
                _add_color(systems[-1],color,frame=frame)
            if ticks != 1:
                _remove_ticks(systems[-1])
    _current_style=os.path.join(_user_path,"subplot%s.gs" % win)
    fid = open(_current_style,'w')
    fid.write(write_style.style2string(systems,landscape=land))
    fid.close()
    gist.winkill(win)
    gist.window(win,style=_current_style,width=int(pw),height=int(ph))
Example #14
0
def twoplane(DATA,slice1,slice2,dx=[1,1,1],cmin=None,cmax=None,xb=None,xe=None,
             xlab="",ylab="",zlab="",clab="",titl="",
             totalheight=0.5,space=0.02, medfilt=5,
             font='helvetica',fontsize=16,color='black',lcolor='white',
             fcolor='black',  cb=1, line=1, palette=None):
    """ Visualize a 3d volume as a two connected slices.  The slices are
    given in the 2-tuple slice1 and slice2.

    These give the dimension and corresponding slice numbers to plot.
    The unchosen slice is the common dimension in the images.

    twoplane(img3d,(0,12),(2,60)) plots two images with a common "x"-axis
    as the first dimension.  The lower plot is img3d[12,:,:] with a line
    through row 60 corresponding to the slice transpose(img3d[:,:,60])
    plotted above this first plot.
    """
    if xb is None:
        xb = [0,0,0]
    if xe is None:
        xe = DATA.shape
    # get two image slices
    # make special style file so that pixels are square
    getdx = array([1,1,1])
    imgsl1 = [slice(None,None),slice(None,None),slice(None,None)]
    imgsl1[slice1[0]] = slice1[1]
    img1 = DATA[imgsl1]
    getdx1 = getdx.__copy__()
    getdx1[slice1[0]] = 0
    dx1 = compress(getdx1,dx,axis=-1)
    xb1 = compress(getdx1,xb,axis=-1)
    xe1 = compress(getdx1,xe,axis=-1)

    imgsl2 = [slice(None,None),slice(None,None),slice(None,None)]
    imgsl2[slice2[0]] = slice2[1]
    img2 = DATA[imgsl2]
    getdx2 = getdx.__copy__()
    getdx2[slice2[0]] = 0
    dx2 = compress(getdx2,dx,axis=-1)
    xb2 = compress(getdx2,xb,axis=-1)
    xe2 = compress(getdx2,xe,axis=-1)


    if (slice1[0] == slice2[0]):
        raise ValueError, "Same slice dimension.."

    for k in range(3):
        if k not in [slice1[0],slice2[0]]:
            samedim = k
            break
    if samedim == 2:
        pass
    elif samedim == 1:
        if samedim > slice1[0]:
            img1 = transpose(img1)
            dx1 = dx1[::-1]
            xb1 = xb1[::-1]
            xe1 = xe1[::-1]
        if samedim > slice2[0]:
            img2 = transpose(img2)
            dx2 = dx2[::-1]
            xb2 = xb2[::-1]
            xe2 = xe2[::-1]
    else:
        img1 = transpose(img1)
        dx1 = dx1[::-1]
        xb1 = xb1[::-1]
        xe1 = xe1[::-1]
        img2 = transpose(img2)
        dx2 = dx2[::-1]
        xb2 = xb2[::-1]
        xe2 = xe2[::-1]



    assert(img1.shape[1] == img2.shape[1])
    units = totalheight - space
    totaldist = img1.shape[0]*dx1[0] + img2.shape[0]*dx2[0]
    convfactor = units / float(totaldist)
    height1 = img1.shape[0]*dx1[0] * convfactor
    xwidth = img1.shape[1]*dx1[1]*convfactor
    if xwidth > 0.6:
        rescale = 0.6 / xwidth
        xwidth = rescale * xwidth
        height1 = rescale * height1
        totalheight = totalheight * rescale
        print xwidth, height1
    else:
        print xwidth
    ystart = 0.5 - totalheight / 2
    ypos1 = [ystart, ystart+height1]
    ypos2 = [ystart+height1+space,ystart+totalheight]
    xpos = [0.395-xwidth/2.0, 0.395+xwidth/2.0]

    systems = []
    system = write_style.getsys(hticpos='', vticpos='left')
    system['viewport'] = [xpos[0],xpos[1],ypos2[0],ypos2[1]]
    if fcolor not in ['black',None]:
        _add_color(system, _colornum[color])
    systems.append(system)
    system = write_style.getsys(hticpos='below', vticpos='left')
    system['viewport'] = [xpos[0],xpos[1],ypos1[0],ypos1[1]]
    if fcolor not in ['black',None]:
        _add_color(system, _colornum[color])
    systems.append(system)

    the_style = os.path.join(_user_path,"two-plane.gs")
    write_style.writestyle(the_style,systems)

    gist.window(style=the_style)
    _current_style = the_style
    change_palette(palette)
    gist.plsys(1)
    if medfilt > 1:
        img1 = signal.medfilt(img1,[medfilt,medfilt])
        img2 = signal.medfilt(img2,[medfilt,medfilt])
    if cmax is None:
        cmax = max(max(ravel(img1)),max(ravel(img2)))
    if cmin is None:
        cmin = min(min(ravel(img1)),min(ravel(img2)))
    cmax = float(cmax)
    cmin = float(cmin)
    byteimage = gist.bytscl(img2,cmin=cmin,cmax=cmax)
    gist.pli(byteimage,xb2[1],xb2[0],xe2[1],xe2[0])
    ylabel(zlab,color=color)
    if titl != "":
        title(titl,color=color)
    if line:
        xstart = xb2[1]
        xstop = xe2[1]
        yval = slice1[1]*(xe2[0] - xb2[0])/(img2.shape[0]) + xb2[0]
        gist.pldj([xstart],[yval],[xstop],[yval],type='dash',width=2,color='white')


    gist.plsys(2)
    ylabel(ylab,color=color)
    xlabel(xlab,color=color)
    byteimage = gist.bytscl(img1,cmin=cmin,cmax=cmax)
    gist.pli(byteimage,xb1[1],xb1[0],xe1[1],xe1[0])
    if line:
        xstart = xb1[1]
        xstop = xe1[1]
        yval = slice2[1]*(xe1[0] - xb1[0])/(img1.shape[0]) + xb1[0]
        gist.pldj([xstart],[yval],[xstop],[yval],type='dash',width=2,color='white')

    if cb:
        colorbar.color_bar(cmin,cmax,ncol=240,zlabel=clab,font=font,fontsize=fontsize,color=color,ymin=ystart,ymax=ystart+totalheight,xmin0=xpos[1]+0.02,xmax0=xpos[1]+0.04)
Example #15
0
    def _compute_symplectic_matrix_diag_to_equi(self):
        """

        Construct the change of coordinates between the equilibrium
        and real-diagonal coordinates.

        Using the (generally complex) eigenvectors, corresponding to
        the quadratic part of the Hamiltonian, we build a real
        symplectic linear coordinate transformation on the phase space
        (expressed as a matrix), under which the quadratic part is
        transformed into real normal form.

        It is important to note that any non-zero multiple of an
        eigenvector is also an eigenvector.  Therefore, although
        certain eigenvalues (those corresponding to centres) will come
        in pure imaginary complex conjugate pairs, the assocaited
        eigenvectors need not be complex conjugate pairs --- although,
        we could express them as such by multiplication by suitable
        complex scale factors --- instead, we may have any complex
        (including pure-imaginary) multiple of the complex conjugate
        eigenvector.

        Care must therefore be taken in the choice of the eigenvectors
        for the symplectic matrix, especially in the case where the
        original system already contains subsystems that are in real
        normal form.

        To cope with the above, we use the following scheme:

         1. In the case of a saddle (pure real +/- eigenvalues, $(+e,
         -e)$) we simply use whatever eigenvectors, $(v_0, v_1)$, we
         are given and scale (via a real scale factor) these suitably
         to give a real symplectic subsystem.

         2. In the case of a centre (pure imaginary complex conjugate
            pair of eigenvalues), we denote the given eigenvectors by
            $v_0,v_1$.  We then use $v_0':=\re(v_0)$ and
            $v_1':=\im(v_0)$, i.e., we only use one of the complex
            eigenvectors, taking its real and imaginary parts.  Again,
            this choice of real vectors will be suitably scaled so as
            to give a symplectic subsystem.

        It can be confirmed that the action of the linearised version
        of Hamilton's equations on the above choice of real vectors
        spans the same two-dimensional subspace as on the original
        complex ones.

        The chosen vectors form the columns of a matrix $M$.  Given a
        vector in the real diagonal coordinate system, $x_{dr}$, one
        can then compute the equilibrium coordinate system vector from
        $Mx_{dr}=x_{er}$.  So the matrix is the transformation from
        DIAG to EQUI.

        todo: In the case of pairs of zero eigenvalues, perhaps we should
        emit an error, insisting that the user first projects (via a
        momentum-independent projector) to a subspace of the non-null
        space?

        """
        logger.info('Constructing symplectic change:')
        pm_val_vec_pairs = self._eig.plus_minus_pairs
        rearranged_pairs = []
        columns = []
        for i in xrange(0, self.dof()):
            i0 = 2*i
            i1 = i0+1
            plus, minus = pm_val_vec_pairs[i]
            if self._eig.equilibrium_type[i] == 's':
                logger.info('Saddle-type eigenvalues')
                a = real_part_of_vector(plus.vec) #real anyway
                b = real_part_of_vector(minus.vec) #real anyway
            else:
                if self._eig.equilibrium_type[i] == 'c':
                    logger.info('Centre-type eigenvalues')
                    a = real_part_of_vector(plus.vec)
                    b = imag_part_of_vector(plus.vec) #N.B. *same* vector!
                else:
                    logger.info('Zero-type eigenvalues')
                    assert (self._eig.equilibrium_type[i] == '0')
                    #todo: assert imag part is close to zero
                    #todo: assert plus close to minus
                    assert 0, 'do something clever to original hamiltonian, please'
            #logger.info('Original eigenvectors:')
            #logger.info(plus.vec)
            #logger.info(minus.vec)
            #logger.info('Choice of real vectors spanning real subspace:')
            #logger.info(a)
            #logger.info(b)
            c = 0.0
            for k in xrange(0, self.dof()):
                k0 = 2*k
                k1 = k0+1
                c += (a[k0]*b[k1] - a[k1]*b[k0])
            if (abs(c) < 1.0e-12):
                assert (self._eig.equilibrium_type[i] == '0')
                assert 0, 'do something clever to original hamiltonian, please'
            else:
                if c < 0.0:
                    if self._eig.equilibrium_type[i] == 's':
                        a_final = a
                        b_final = -b
                        c_final = -c #ADB!                        
                        logger.info('Negative Multiplier in saddle: %s', c_final)
                        logger.info('Negating second vector')
                    else:
                        #Swapping pairs to make symplectic matrix:
                        rearranged_pairs.append((minus, plus))
                        a_final = b
                        b_final = a
                        c_final = -c #ADB!
                        logger.info('Negative Multiplier in centre: %s', c_final)
                        logger.info('NEGATIVE EIGENVALUE, Swap two vectors')
                else:
                    rearranged_pairs.append((plus, minus))
                    a_final = a
                    b_final = b
                    c_final = +c #ADB!
            logger.info('Multiplier present in eigenvector matrix: %s', c_final)
            scale = +pow(1.0/c_final, 0.5) #+/- #ADB!
            logger.info('Scale factor to produce symplectic matrix: %s', scale)
            columns.append(scale*a_final)
            columns.append(scale*b_final)
        self.final_pairs = rearranged_pairs
        #we must transpose the result, since arrays are created row-wise:
        mat = transpose(array(columns, Float))
        #logger.info('Candidate symplectic matrix')
        #logger.info(mat)
        assert self.matrix_is_symplectic(mat)
        self.matrix_diag_to_equi = mat