/*
 * NewJApplet.java
 *
 * Created on February 26, 2008, 3:26 PM
 */
package javaapplication24;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.text.*;
import java.awt.Graphics2D;
import java.awt.geom.*;



/**
 *
 * @author  root
 */
public class NewJApplet extends javax.swing.JApplet {
  int i, j, n, nx, ierr = 0;
        double DeltaE=0.1;
        double V=-0.5;
        double[][] a;
        double[] d;
        double[] e;
        double[][] z;
        double[] y;
        double s;
        double s4;
        DecimalFormat df;
        
    /** Initializes the applet NewJApplet */
    public void init() {
       

       
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {

                public void run() {
                    initComponents();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        nx=10;
        n = nx*nx;
        a = new double[n][n];
        z = new double[n][n];
        d = new double[n];
        e = new double[n];
        y = new double[n];
        DecimalFormatSymbols unusualSymbols =
        new DecimalFormatSymbols();
        
        unusualSymbols.setDecimalSeparator('.');
        
        df= new DecimalFormat("##0.00",unusualSymbols); 
        DESlider.setValue((int)(100*DeltaE));   
        DELabel.setText("DE="+df.format(DeltaE));
        VSlider.setValue((int)(V*100.0+50.0));
        VLabel.setText("V="+df.format(V));
        
       // test();
    }

    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new myPanel();
        VSlider = new javax.swing.JSlider();
        DESlider = new javax.swing.JSlider();
        VLabel = new javax.swing.JLabel();
        DELabel = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 389, Short.MAX_VALUE)
        );

        VSlider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                VSliderMouseDragged(evt);
            }
        });

        DESlider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                DESliderMouseDragged(evt);
            }
        });

        VLabel.setText("jLabel1");

        DELabel.setText("jLabel2");

        jButton1.setText("Go");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel1.setText("jLabel1");
        jLabel1.setMaximumSize(new java.awt.Dimension(100, 16));
        jLabel1.setMinimumSize(new java.awt.Dimension(100, 16));
        jLabel1.setPreferredSize(new java.awt.Dimension(100, 16));

        jLabel2.setText("circles show the amplitude of the wavefunction at different sites");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(45, 45, 45)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(VSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(DESlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(91, 91, 91)
                        .addComponent(VLabel))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(92, 92, 92)
                        .addComponent(DELabel))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(69, 69, 69)
                        .addComponent(jButton1))
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(119, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(49, 49, 49)
                        .addComponent(VLabel)
                        .addGap(18, 18, 18)
                        .addComponent(VSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(58, 58, 58)
                        .addComponent(DELabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(DESlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(62, 62, 62)
                        .addComponent(jButton1)
                        .addGap(27, 27, 27)
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(37, 37, 37)
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel2)
                .addContainerGap(30, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void VSliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_VSliderMouseDragged
    V=(VSlider.getValue()-50)*0.01;  
    VLabel.setText("V="+df.format(V));// TODO add your handling code here:
    test();
    jPanel1.repaint();
    }//GEN-LAST:event_VSliderMouseDragged

    private void DESliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_DESliderMouseDragged
    DeltaE=(DESlider.getValue()*0.01);   
    DELabel.setText("DE="+df.format(DeltaE));
     test();
    jPanel1.repaint();
    // TODO add your handling code here:
    }//GEN-LAST:event_DESliderMouseDragged

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
      test();
    jPanel1.repaint();  // TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel DELabel;
    private javax.swing.JSlider DESlider;
    private javax.swing.JLabel VLabel;
    private javax.swing.JSlider VSlider;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration//GEN-END:variables
     public double randgauss()
{
double  x,r,phi,rho;

      r = Math.random();
      phi = 2.0*Math.PI*r;

      r = Math.random();
      rho=Math.sqrt(-Math.log(1-r));

      x = rho*Math.cos(phi)*Math.sqrt(2.0);



      return x;
}

    public void test() {
       int ix1,iy1,ix2,iy2,ind1,ind2;

        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                a[i][j]=0.0; }}
                
           
        
        
        for (ix1=0;ix1<nx;ix1++)for(iy1=0;iy1<nx;iy1++)
        {
        ind1=ix1*nx+iy1;
        a[ind1][ind1] = randgauss()*DeltaE; 
        
        if(ix1>0) { ix2=ix1-1; ind2=ix2*nx+iy1; 
        a[ind1][ind2]=V; a[ind2][ind1]=V;}
        
        //if(ix1<nx-1) { ix2=ix1+1; ind2=ix2*nx+iy1; 
        //a[ind1][ind2]=V; a[ind2][ind1]=V;}
        
        if(iy1>0) { iy2=iy1-1; ind2=ix1*nx+iy2; 
        a[ind1][ind2]=V; a[ind2][ind1]=V;}
        
        //if(iy1<nx-1) { iy2=iy1+1; ind2=ix1*nx+iy2; 
        //a[ind1][ind2]=V; a[ind2][ind1]=V;}
        }

       

        tred2(n, a, d, e, z);
         
        tql2(n, d, e, a, ierr);
        
       
        s4=0.0;
        for(ix1=0;ix1<n;ix1++) s4=s4+Math.pow(a[ix1][1],4);
        jLabel1.setText("sum(C**4)="+df.format(s4));
      


    }

    public void tql2(int n, double d[], double e[], double a[][], int ierr) {
        int i, j, k, l, m, ii, l1, l2, nm, mml, count;
/*
c     this subroutine is a translation of the algol procedure tql2,
c     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
c     wilkinson.
c     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
c
c     this subroutine finds the eigenvalues and eigenvectors
c     of a symmetric tridiagonal matrix by the ql method.
c     the eigenvectors of a full symmetric matrix can also
c     be found if  tred2  has been used to reduce this
c     full matrix to tridiagonal form.
c
c     on input
c
c       
c
c        n is the order of the matrix.
c
c        d contains the diagonal elements of the input matrix.
c
c        e contains the subdiagonal elements of the input matrix
c          in its last n-1 positions.  e(1) is arbitrary.
c
c        a contains the transformation matrix produced in the
c          reduction by  tred2, if performed.  if the eigenvectors
c          of the tridiagonal matrix are desired, a must contain
c          the identity matrix.
c
c      on output
c
c        d contains the eigenvalues in ascending order.  if an
c          error exit is made, the eigenvalues are correct but
c          unordered for indices 1,2,...,ierr-1.
c
c        e has been destroyed.
c
c        a contains orthonormal eigenvectors of the symmetric
c          tridiagonal (or full) matrix.  if an error exit is made,
c          a contains the eigenvectors associated with the stored
c          eigenvalues.
c
c        ierr is set to
c          zero       for normal return,
c          j          if the j-th eigenvalue has not been
c                     determined after 30 iterations.
c
c     calls pythag for  sqrt(a*a + b*b) .
c
c     questions and comments should be directed to burton s. garbow,
c     mathematics and computer science div, argonne national laboratory
c
c     this version dated august 1983.
c
c     ------------------------------------------------------------------
*/
        double c, c2, c3, dl1, el1, f, g, h, p, r, s, s2, tst1, tst2;
        boolean iterate;

        ierr = 0;
        if (n > 1) {

            for (i = 1; i < n; i++) {
                e[i - 1] = e[i];
            }

            f = 0.0;
            tst1 = 0.0;
            e[n - 1] = 0.0;

            for (l = 0; l < n; l++) {
                
                count = 0;
                h = Math.abs(d[l]) + Math.abs(e[l]);
                if (tst1 < h) {
                    tst1 = h;
                }




//.......... look for small sub-diagonal element ..........



                m = l;
                iterate = true;
                
                
                do {

                    tst2 = tst1 + Math.abs(e[m]);
                    
                    if (tst2 == tst1) {
                        iterate = false;
                    }
                    
                    if (m>=n-1) iterate=false;
                    if (iterate &&(m < n - 1)) m++;
                    

                } while (iterate);
                
             

                if (m > l) {
                    count = 0;
                    iterate = true;
                    do {
                        count++;
                        //     .......... form shift ..........
                        g = d[l];
                        p = (d[l + 1] - g) / (2.0 * e[l]);
                        r = pythag(p, 1.0);

                        d[l] = e[l] / (p + Math.copySign(r, p));
                        d[l + 1] = e[l] * (p + Math.copySign(r, p));
                        dl1 = d[l + 1];
                        h = g - d[l];
                        for (i = l + 2; i < n; i++) {
                            d[i] -= h;
                        }
                        f = f + h;
                        //     .......... ql transformation .......... 


                        p = d[m];
                        c = 1.0;
                        c2 = c;
                        c3 = c;
                        el1 = e[l + 1];
                        s = 0.0;
                        s2 = 0.0;

                        for (i = m - 1; i >= l; i--) {
                            c3 = c2;
                            c2 = c;
                            s2 = s;
                            g = c * e[i];
                            h = c * p;
                            r = pythag(p, e[i]);
                            e[i + 1] = s * r;
                            s = e[i] / r;
                            c = p / r;
                            p = c * d[i] - s * g;
                            d[i + 1] = h + s * (c * g + s * d[i]);

                            //.......... form vector ..........

                            for (k = 0; k < n; k++) {
                                h = a[k][i + 1];
                                a[k][i + 1] = s * a[k][i] + c * h;
                                a[k][i] = c * a[k][i] - s * h;
                            }
                        }

                        p = -s * s2 * c3 * el1 * e[l] / dl1;
                        e[l] = s * p;
                        d[l] = c * p;

                        tst2 = tst1 + Math.abs(e[l]);
                        if (tst2 <= tst1) {
                            iterate = false;
                        }
                        if (count >= 30) {
                            iterate = false;
                        }

                    } while (iterate);

                    if (count >= 30) {
                        ierr = l;
                        break;
                    }
                }


                d[l] = d[l] + f;
                e[l] = 0.0;
            }

            //    .......... order eigenvalues and eigenvectors ..........

            for (i = 0; i < n - 1; i++) {
                k = i;
                p = d[i];
                for (j = i + 1; j < n; j++) {
                    if (d[j] < p) {
                        k = j;
                        p = d[j];
                    }
                }

                if (k != i) {
                    d[k] = d[i];
                    d[i] = p;
                    for (j = 0; j < n; j++) {
                        p = a[j][i];
                        a[j][i] = a[j][k];
                        a[j][k] = p;
                    }
                }
            }
        }
    }

    private double pythag(double x, double y) {
        double r;
        r = Math.sqrt(x * x + y * y);
        return r;
    }

    public void tred2(int n, double a[][], double d[], double e[], double z[][]) {
        int i, j, k, l, jp1;
        double f, g, h, hh, scale;

        /*
        c     this subroutine is a translation of the algol procedure tred2,
        c     num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson.
        c     handbook for auto. comp., vol.ii-linear algebra, 212-226(1971).
        c
        c     this subroutine reduces a real symmetric matrix to a
        c     symmetric tridiagonal matrix using and accumulating
        c     orthogonal similarity transformations.
        c
        c     on input
        c
        c        n is the order of the matrix.
        c
        c        a contains the real symmetric input matrix.  
        c
        c     on output
        c
        c        d contains the diagonal elements of the tridiagonal matrix.
        c
        c        e contains the subdiagonal elements of the tridiagonal
        c          matrix in its last n-1 positions.  e[0] is set to zero.
        c
        c        z contains the orthogonal transformation matrix
        c          produced in the reduction.
         */
        for (i = 0; i < n; i++) {
            d[i] = a[n - 1][i];
        }

        if (n > 1) {
            for (i = n - 1; i > 0; i--) {
                h = 0.0;
                scale = 0.0;
//     .......... scale row (algol tol then not needed) ..........
                for (k = 0; k < i; k++) {
                    scale = scale + Math.abs(d[k]);
                }

                if (scale == 0.0) {
                    e[i] = d[i - 1];
                    for (j = 0; j < i; j++) {
                        d[j] = a[i - 1][j];
                        a[i][j] = 0.0;
                        a[j][i] = 0.0;
                    }
                } else {

                    for (k = 0; k < i; k++) {
                        d[k] = d[k] / scale;
                        h = h + d[k] * d[k];

                    }

                    f = d[i - 1];
                    g = Math.sqrt(h);
                    if (f > 0) {
                        g = -g;
                    }
                    e[i] = scale * g;
                    h = h - f * g;
                    d[i - 1] = f - g;

//     .......... form a*u ..........

                    for (j = 0; j < i; j++) {
                        e[j] = 0.0;
                    }


                    for (j = 0; j < i; j++) {
                        f = d[j];
                        a[j][i] = f;
                        g = e[j] + a[j][j] * f;


                        for (k = j + 1; k < i; k++) {
                            g = g + a[k][j] * d[k];
                            e[k] = e[k] + a[k][j] * f;

                        }




                        e[j] = g;
                    }


//     .......... form p ..........

                    f = 0.0;
                    for (j = 0; j < i; j++) {

                        e[j] = e[j] / h;
                        f = f + e[j] * d[j];

                    }
                    hh = f / (h + h);



//     .......... form q ..........



                    for (j = 0; j < i; j++) {
                        e[j] = e[j] - hh * d[j];
                    }



//     .......... form reduced a ..........



                    for (j = 0; j < i; j++) {
                        f = d[j];
                        g = e[j];
                        for (k = j; k < i; k++) {
                            a[k][j] = a[k][j] - f * e[k] - g * d[k];
                        }
                        d[j] = a[i - 1][j];
                        a[i][j] = 0.0;
                    }


                }
                d[i] = h;
            }

//.......... accumulation of transformation matrices ..........



            for (i = 0; i < n - 1; i++) {


                a[n - 1][i] = a[i][i];
                a[i][i] = 1.0;
                h = d[i + 1];
                if (h != 0.0) {
                    for (k = 0; k <= i; k++) {
                        d[k] = a[k][i + 1] / h;
                    }

                    for (j = 0; j <= i; j++) {
                        g = 0.0;
                        for (k = 0; k <= i; k++) {
                            g = g + a[k][i + 1] * a[k][j];
                        }

                        for (k = 0; k <= i; k++) {
                            a[k][j] = a[k][j] - g * d[k];
                        }
                    }

                }



                for (k = 0; k <= i; k++) {
                    a[k][i + 1] = 0.0;
                }

            }


        }


        for (i = 0; i < n; i++) {
            d[i] = a[n - 1][i];
            a[n - 1][i] = 0.0;
        }

        a[n - 1][n - 1] = 1.0;
        e[0] = 0.0;


    }


    public class myPanel extends javax.swing.JPanel{
       
    int ir,iy0,iy1,i,ix0,ix1;
   
    public void paintComponent(Graphics g)
{        
    
     super.paintComponent(g);  
     test();
     
     for(ix0=0;ix0<nx;ix0++)
         for(iy0=0;iy0<nx;iy0++)
     { i=ix0*nx+iy0;
       ir=(int)(Math.abs(a[i][0])*50);
       if(a[i][0]>0) g.setColor(Color.red); else g.setColor(Color.blue);
       
       g.drawOval(50+ix0*30-ir/2,300-iy0*30-ir/2,ir,ir);
     }    
    }
    }
    
}

