/*
 * NewJApplet.java
 *
 * Created on October 17, 2008, 6:20 PM
 */

import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.text.*;

/**
 *
 * @author  root
 */
public class NewJApplet extends javax.swing.JApplet {

    public double[] xcoor,  ycoor,  zcoor,  d,  e;
    public int max_segments = 5000;
    public int number_segments = 10;
    public int window_w;
    public double[][] gyrtens,  zmat;
    public double rgav,  r2av,  rcav,  d1av,  d2av,  d0av;
    public int nav,  ierr;
    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();
        }


        xcoor = new double[max_segments];
        ycoor = new double[max_segments];
        zcoor = new double[max_segments];
        gyrtens = new double[3][3];
        zmat = new double[3][3];
        d = new double[3];
        e = new double[3];

        DecimalFormatSymbols unusualSymbols =
                new DecimalFormatSymbols();

        unusualSymbols.setDecimalSeparator('.');

        df = new DecimalFormat("##0.000", unusualSymbols);
        init_walk();
    }

    public void init_walk() {
        rgav = 0;
        r2av = 0;
        rcav = 0;
        nav = 0;
        d1av = 0;
        d2av = 0;
        d0av = 0;

        window_w = 150 / (int) Math.sqrt(number_segments);
        jLabel18.setText("points:"+number_segments);
    }

    /** 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();
        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        jLabel14 = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        jLabel16 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        jSlider1 = new javax.swing.JSlider();
        jLabel18 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setMaximumSize(new java.awt.Dimension(400, 400));
        jPanel1.setMinimumSize(new java.awt.Dimension(400, 400));
        jPanel1.setPreferredSize(new java.awt.Dimension(400, 400));

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

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

        jLabel1.setText("--");

        jLabel2.setText("--");

        jLabel3.setText("--");

        jLabel4.setText("--");

        jLabel8.setText("--");

        jLabel9.setText("--");

        jButton2.setText("average 1000");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jLabel10.setText("gyration radius^2");

        jLabel11.setText("end to end radius^2");

        jLabel12.setText("center radius ^2");

        jLabel16.setText("--");

        jLabel17.setText("ordered eigenvalues of gyration tensor");

        jSlider1.setMajorTickSpacing(100);
        jSlider1.setMaximum(1000);
        jSlider1.setPaintTicks(true);
        jSlider1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jSlider1MouseDragged(evt);
            }
        });

        jLabel18.setText("jLabel18");

        jLabel19.setText("last shot");

        jLabel20.setText("average");

        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(39, 39, 39)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel20)
                            .addComponent(jLabel19, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(33, 33, 33)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel5)
                                    .addComponent(jLabel13))
                                .addGap(54, 54, 54)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel14)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jLabel15))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel6)
                                        .addGap(58, 58, 58)
                                        .addComponent(jLabel7))))
                            .addComponent(jLabel17))))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel1)
                                .addGap(18, 18, 18)
                                .addComponent(jLabel3))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel8)
                                .addGap(18, 18, 18)
                                .addComponent(jLabel9))
                            .addComponent(jLabel12, javax.swing.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel2)
                                .addGap(18, 18, 18)
                                .addComponent(jLabel4))
                            .addComponent(jLabel11, javax.swing.GroupLayout.DEFAULT_SIZE, 228, Short.MAX_VALUE)
                            .addComponent(jButton2)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(jSlider1, javax.swing.GroupLayout.Alignment.LEADING, 0, 0, Short.MAX_VALUE)
                                .addComponent(jButton1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGap(20, 20, 20))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(46, 46, 46)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel16)
                            .addComponent(jLabel18))
                        .addContainerGap())))
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jButton1, jButton2});

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel13, jLabel14, jLabel15, jLabel5, jLabel6, jLabel7});

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel2, jLabel3, jLabel4, jLabel8, jLabel9});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(58, 58, 58)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel1))
                        .addGap(37, 37, 37)
                        .addComponent(jLabel11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(jLabel4))
                        .addGap(29, 29, 29)
                        .addComponent(jLabel12)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel8)
                            .addComponent(jLabel9))
                        .addGap(39, 39, 39)
                        .addComponent(jButton2)
                        .addGap(18, 18, 18)
                        .addComponent(jButton1)
                        .addGap(27, 27, 27)
                        .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel18))
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(jLabel17)
                        .addGap(1, 1, 1)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel5)
                            .addComponent(jLabel6)
                            .addComponent(jLabel7)
                            .addComponent(jLabel19))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel13)
                            .addComponent(jLabel14)
                            .addComponent(jLabel15)
                            .addComponent(jLabel20)))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel16)))
                .addContainerGap(26, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        walk();
        jPanel1.repaint();// TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        int ilo;
        for (ilo = 0; ilo < 1000; ilo++) {
            walk();
        }
        jPanel1.repaint();
    // TODO add your handling code here:
    }//GEN-LAST:event_jButton2ActionPerformed

private void jSlider1MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider1MouseDragged
    double expo;
    expo=(jSlider1.getValue()/200.0);
    number_segments=(int)Math.pow(10,expo);
    if(number_segments>max_segments)number_segments=max_segments;
    init_walk();
    jLabel18.setText("points:"+number_segments);
    // TODO add your handling code here:
}//GEN-LAST:event_jSlider1MouseDragged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JSlider jSlider1;
    // End of variables declaration//GEN-END:variables

    public void walk() {

        double r,  phi,  theta,  s_t,  c_t,  s_p,  c_p,  xm,  ym,  zm,  x1,  y1,  z1,  rg,  r2,  rc;
        int i,  j,  n2;


        xcoor[0] = 0;
        ycoor[0] = 0;
        zcoor[0] = 0;

        for (i = 1; i < number_segments; i++) {


            r = Math.random();
            phi = r * 2.0 * Math.PI;
            c_p = Math.cos(phi);
            s_p = Math.sin(phi);
            r = 2.0 * (Math.random() - 0.5);
            c_t = r;
            s_t = Math.sqrt(1.0 - c_t * c_t);

            xcoor[i] = xcoor[i - 1] + s_t * c_p;
            ycoor[i] = ycoor[i - 1] + s_t * s_p;
            zcoor[i] = zcoor[i - 1] + c_t;

        }

        xm = 0;
        ym = 0;
        zm = 0;
        for (i = 0; i < number_segments; i++) {

            xm += xcoor[i];
            ym += ycoor[i];
            zm += zcoor[i];


        }

        xm = xm / number_segments;
        ym = ym / number_segments;
        zm = zm / number_segments;


        rc = xm * xm + ym * ym + zm * zm;

        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                gyrtens[i][j] = 0;
            }
        }

        for (i = 1; i < number_segments; i++) {
            x1 = xcoor[i] - xm;
            y1 = ycoor[i] - ym;
            z1 = zcoor[i] - zm;

            gyrtens[0][0] += x1 * x1;
            gyrtens[0][1] += x1 * y1;
            gyrtens[0][2] += x1 * z1;

            gyrtens[1][0] += y1 * x1;
            gyrtens[1][1] += y1 * y1;
            gyrtens[1][2] += y1 * z1;

            gyrtens[2][0] += z1 * x1;
            gyrtens[2][1] += z1 * y1;
            gyrtens[2][2] += z1 * z1;
        }
        n2 = number_segments * number_segments;

        rg = (gyrtens[0][0] + gyrtens[1][1] + gyrtens[2][2]) / n2;

        r2 = xcoor[number_segments - 1] * xcoor[number_segments - 1] +
                ycoor[number_segments - 1] * ycoor[number_segments - 1] +
                zcoor[number_segments - 1] * zcoor[number_segments - 1];
        r2 = r2 / number_segments;
        rc = rc / number_segments;


        rgav += rg;
        r2av += r2;
        rcav += rc;
        nav += 1;
        jLabel1.setText(df.format(rg));
        jLabel2.setText(df.format(r2));
        jLabel3.setText("av:"+df.format(rgav / nav));
        jLabel4.setText("av:"+df.format(r2av / nav));
        jLabel8.setText(df.format(rc));
        jLabel9.setText("av:"+df.format(rcav / nav));

        tred2(3, gyrtens, d, e, zmat);
        tql2(3, d, e, gyrtens, ierr);

        d0av += d[0] / n2;
        d1av += d[1] / n2;
        d2av += d[2] / n2;

        jLabel5.setText(df.format(d[0] / n2));
        jLabel6.setText(df.format(d[1] / n2));
        jLabel7.setText(df.format(d[2] / n2));

        jLabel13.setText(df.format(d0av / nav));
        jLabel14.setText(df.format(d1av / nav));
        jLabel15.setText(df.format(d2av / nav));
        jLabel16.setText("shots:" + nav);
    }

    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;

    }

    class myPanel extends javax.swing.JPanel {

        public void paintComponent(Graphics g) {
            int i,   ix,   iy,   ix1,   iy1;
            super.paintComponent(g);
            for (i = 0; i < number_segments - 1; i++) {
                ix = (int) (xcoor[i] * window_w + 200.0);
                iy = (int) (200.0 - ycoor[i] * window_w);
                ix1 = (int) (xcoor[i + 1] * window_w + 200.0);
                iy1 = (int) (200.0 - ycoor[i + 1] * window_w);

                g.drawLine(ix, iy, ix1, iy1);
            }
            for (i = 0; i < number_segments; i++) {
                ix = (int) (xcoor[i] * window_w + 200.0);
                iy = (int) (200.0 - ycoor[i] * window_w);
                if (i == number_segments - 1) {
                    g.setColor(Color.red);
                }
                g.drawOval(ix - 5, iy - 5, 10, 10);
            }
        }
    }
}
