/*
 * NewJApplet.java
 *
 * Created on February 13, 2008, 6:36 PM
 */

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 {

    double[][] RealC, ImagC, RealC2, ImagC2, RealC3, ImagC3, RealC4, ImagC4;
    double[][] RealF1, ImagF1, RealF2, ImagF2, RealF3, ImagF3, RealF4, ImagF4;
    int nstates = 2;
    double V = 1.0;
    double DeltaE = 2.0;
    double tstep = 0.0005;
    double freq = 0.0;
    double tp = 1.0;
    double tp1=10.0;
    double t1r = 0.0;
    double t2r = 0.0;
    double t0 = 10.0;
    double t01 = 10.0;
    boolean twopulses = false;
    boolean lock=true;
    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();
        }

        RealC = new double[nstates][nstates];
        ImagC = new double[nstates][nstates];
        RealC2 = new double[nstates][nstates];
        ImagC2 = new double[nstates][nstates];
        RealC3 = new double[nstates][nstates];
        ImagC3 = new double[nstates][nstates];
        RealC4 = new double[nstates][nstates];
        ImagC4 = new double[nstates][nstates];
        RealF1 = new double[nstates][nstates];
        ImagF1 = new double[nstates][nstates];
        RealF2 = new double[nstates][nstates];
        ImagF2 = new double[nstates][nstates];
        RealF3 = new double[nstates][nstates];
        ImagF3 = new double[nstates][nstates];
        RealF4 = new double[nstates][nstates];
        ImagF4 = new double[nstates][nstates];

        df = new DecimalFormat("##0.000");

        VS.setValue((int) (V * 20.0));
        DES.setValue((int) (DeltaE * 20.0));
        freqS.setValue((int) (freq * 20.0));
        tpslider.setValue((int) (tp * 20.0));
        t1rslider.setValue((int) (t1r * 100.0));
        t2rslider.setValue((int) (t2r * 100.0));
        tzslider.setValue((int) (t0 * 10));
        

        VL.setText("V=" + df.format(V));
        DEL.setText("Energy gap=" + df.format(DeltaE));
        freqL.setText("frequency=" + df.format(freq));
        tplab.setText("tp=" + df.format(tp));
        t1rlab.setText("1/t1=" + df.format(t1r));
        t2rlab.setText("1/t2=" + df.format(t2r));
        tzlab.setText("t0=" + df.format(t0));
        
    }

    /**
     * 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();
        VS = new javax.swing.JSlider();
        DES = new javax.swing.JSlider();
        freqL = new javax.swing.JLabel();
        DEL = new javax.swing.JLabel();
        freqS = new javax.swing.JSlider();
        VL = new javax.swing.JLabel();
        tpslider = new javax.swing.JSlider();
        t1rlab = new javax.swing.JLabel();
        t1rslider = new javax.swing.JSlider();
        t2rslider = new javax.swing.JSlider();
        tplab = new javax.swing.JLabel();
        t2rlab = new javax.swing.JLabel();
        tzslider = new javax.swing.JSlider();
        tzlab = new javax.swing.JLabel();
        jToggleButton1 = new javax.swing.JToggleButton();

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

        VS.setMaximum(200);
        VS.setToolTipText("magnitude of the perturbation");
        VS.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                VSMouseDragged(evt);
            }
        });

        DES.setMaximum(200);
        DES.setToolTipText("energy gap of the two states");
        DES.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                DESMouseDragged(evt);
            }
        });

        freqL.setText("freq  ");

        DEL.setText("DeltaE ");

        freqS.setMaximum(200);
        freqS.setToolTipText("frequency of the perturbation");
        freqS.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                freqSMouseDragged(evt);
            }
        });

        VL.setText("V          ");

        tpslider.setMaximum(200);
        tpslider.setToolTipText("pulse duration");
        tpslider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                tpsliderMouseDragged(evt);
            }
        });

        t1rlab.setText("1/T1");

        t1rslider.setMaximum(400);
        t1rslider.setToolTipText("relaxation time t1");
        t1rslider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                t1rsliderMouseDragged(evt);
            }
        });

        t2rslider.setMaximum(200);
        t2rslider.setToolTipText("relaxation time t2");
        t2rslider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                t2rsliderMouseDragged(evt);
            }
        });

        tplab.setText("tp");

        t2rlab.setText("1/T2");

        tzslider.setMaximum(200);
        tzslider.setToolTipText("time of second pulse ");
        tzslider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                tzsliderMouseDragged(evt);
            }
        });

        tzlab.setText("t0");

        jToggleButton1.setSelected(true);
        jToggleButton1.setText("lock T1=T2");
        jToggleButton1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jToggleButton1StateChanged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .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()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(freqS, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(VS, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(DES, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(t1rslider, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(t2rslider, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(tzslider, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(46, 46, 46)
                                .addComponent(VL))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(40, 40, 40)
                                .addComponent(freqL))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(40, 40, 40)
                                .addComponent(DEL))))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(65, 65, 65)
                        .addComponent(tplab))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(tpslider, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(71, 71, 71)
                        .addComponent(tzlab))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(66, 66, 66)
                        .addComponent(t1rlab))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(64, 64, 64)
                        .addComponent(t2rlab))
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jToggleButton1)))
                .addContainerGap(161, 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()
                        .addContainerGap()
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(60, 60, 60)
                        .addComponent(freqL)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(freqS, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(30, 30, 30)
                        .addComponent(VL)
                        .addGap(18, 18, 18)
                        .addComponent(VS, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(46, 46, 46)
                        .addComponent(DEL)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(DES, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(27, 27, 27)
                        .addComponent(tplab)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(tpslider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(29, 29, 29)
                        .addComponent(tzlab)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(tzslider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(46, 46, 46)
                        .addComponent(t1rlab)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(t1rslider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(t2rlab)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(t2rslider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jToggleButton1)
                        .addGap(0, 116, Short.MAX_VALUE)))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void VSMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_VSMouseDragged
        // TODO add your handling code here:
        V = VS.getValue() * 0.05;
        VL.setText("V=" + df.format(V));
        jPanel1.repaint();
}//GEN-LAST:event_VSMouseDragged

    private void DESMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_DESMouseDragged

        DeltaE = DES.getValue() * 0.05;
        DEL.setText("Energy gap=" + df.format(DeltaE));
        jPanel1.repaint();// TODO add your handling code here:
}//GEN-LAST:event_DESMouseDragged

    private void freqSMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_freqSMouseDragged
        freq = freqS.getValue() * 0.05;
        freqL.setText("frequency=" + df.format(freq));
        jPanel1.repaint();
        // TODO add your handling code here:
}//GEN-LAST:event_freqSMouseDragged

    private void tpsliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tpsliderMouseDragged
        // TODO add your handling code here:
        tp = tpslider.getValue() * 0.05;
        tplab.setText("tp=" + df.format(tp));
        jPanel1.repaint();
}//GEN-LAST:event_tpsliderMouseDragged

    private void t1rsliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_t1rsliderMouseDragged
        // TODO add your handling code here:
        t1r = t1rslider.getValue() * 0.001;
        if(lock) {t2r=0.5*t1r;
         t2rlab.setText("1/t2=" + df.format(t2r));
          t2rslider.setValue((int) (t2r * 1000.0));
        }
        t1rlab.setText("1/t1=" + df.format(t1r));
        jPanel1.repaint();

}//GEN-LAST:event_t1rsliderMouseDragged

    private void t2rsliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_t2rsliderMouseDragged
        // TODO add your handling code here:
        t2r = t2rslider.getValue() * 0.001;
        if(lock){
         t1r=t2r*2.0;
         t1rlab.setText("1/T1=" + df.format(t1r)); 
         t1rslider.setValue((int) (t1r * 1000.0));
        }
        t2rlab.setText("1/T2=" + df.format(t2r));
        jPanel1.repaint();
}//GEN-LAST:event_t2rsliderMouseDragged

    private void tzsliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tzsliderMouseDragged
        // TODO add your handling code here:
        t0 = tzslider.getValue() * 0.1;
        tzlab.setText("t0=" + df.format(t0));
        jPanel1.repaint();

}//GEN-LAST:event_tzsliderMouseDragged

    private void jToggleButton1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jToggleButton1StateChanged
       lock=jToggleButton1.isSelected();
        jPanel1.repaint();
        // TODO add your handling code here:
    }//GEN-LAST:event_jToggleButton1StateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel DEL;
    private javax.swing.JSlider DES;
    private javax.swing.JLabel VL;
    private javax.swing.JSlider VS;
    private javax.swing.JLabel freqL;
    private javax.swing.JSlider freqS;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JToggleButton jToggleButton1;
    private javax.swing.JLabel t1rlab;
    private javax.swing.JSlider t1rslider;
    private javax.swing.JLabel t2rlab;
    private javax.swing.JSlider t2rslider;
    private javax.swing.JLabel tplab;
    private javax.swing.JSlider tpslider;
    private javax.swing.JLabel tzlab;
    private javax.swing.JSlider tzslider;
    // End of variables declaration//GEN-END:variables

    double pulse(double t) {
        double arg;
        arg = (t - t0) / tp;

        return Math.cos(freq * t) * Math.exp(-arg * arg);

    }

    double pulse2(double t) {
        double arg;
        arg = (t - t01) / tp1;

        return Math.cos(freq * t) * Math.exp(-arg * arg);

    }

    void grad(double[][] RC, double[][] IC, double[][] RF, double[][] IF, double t) {
        double Vt, arg;

        arg = (t - 10.0) / tp;



        Vt = V * pulse(t);
        if (twopulses) {
            Vt = Vt + V * pulse2(t);
        }

        RF[0][0] = Vt * (IC[1][0] - IC[0][1]) - t1r * (RC[0][0] - 1.0);
        RF[1][1] = Vt * (IC[0][1] - IC[1][0]) - t1r * (RC[1][1]);

        RF[0][1] = Vt * (IC[1][1] - IC[0][0]) - DeltaE * IC[0][1] - t2r * RC[0][1];
        RF[1][0] = Vt * (IC[0][0] - IC[1][1]) + DeltaE * IC[1][0] - t2r * RC[1][0];


        IF[0][0] = -Vt * (RC[1][0] - RC[0][1]) - t1r * IC[0][0];
        IF[1][1] = -Vt * (RC[0][1] - RC[1][0]) - t1r * IC[1][1];

        IF[0][1] = -Vt * (RC[1][1] - RC[0][0]) + DeltaE * RC[0][1] - t2r * IC[0][1];
        IF[1][0] = -Vt * (RC[0][0] - RC[1][1]) - DeltaE * RC[1][0] - t2r * IC[1][0];




    }

    void advance(double[][] RC, double[][] IC, double[][] RF, double[][] IF,
            double[][] RC1, double[][] IC1, double step) {
        int i, j;

        for (i = 0; i < nstates; i++) {
            for (j = 0; j < nstates; j++) {
                RC1[i][j] = RC[i][j] + RF[i][j] * step;
                IC1[i][j] = IC[i][j] + IF[i][j] * step;

            }
        }

    }

    void rk4(double t) {
        int i, j;
        grad(RealC, ImagC, RealF1, ImagF1, t);
        advance(RealC, ImagC, RealF1, ImagF1, RealC2, ImagC2, tstep * 0.5);
        grad(RealC2, ImagC2, RealF2, ImagF2, t + tstep * 0.5);
        advance(RealC, ImagC, RealF2, ImagF2, RealC3, ImagC3, tstep * 0.5);
        grad(RealC3, ImagC3, RealF3, ImagF3, t + tstep * 0.5);
        advance(RealC, ImagC, RealF3, ImagF3, RealC4, ImagC4, tstep);
        grad(RealC4, ImagC4, RealF4, ImagF4, t + tstep);

        for (i = 0; i < nstates; i++) {
            for (j = 0; j < nstates; j++) {

                RealC[i][j] = RealC[i][j] + tstep * (RealF1[i][j] + 2.0 * RealF2[i][j] + 2.0 * RealF3[i][j] + RealF4[i][j]) / 6.0;
                ImagC[i][j] = ImagC[i][j] + tstep * (ImagF1[i][j] + 2.0 * ImagF2[i][j] + 2.0 * ImagF3[i][j] + ImagF4[i][j]) / 6.0;

            }
        }

    }

    public class myPanel extends javax.swing.JPanel {

        int iy0, iy1, i, ix0, ix1, i1, iz0, iz1, ip0, ip1;
        int blx0,blx1,blz0,blz1;

        void iterate() {
        }

        public double cabs(double x, double y) {
            double r;
            r = Math.sqrt(x * x + y * y);
            return r;

        }

        public void paintComponent(Graphics g) {
            double t, psum, psum1;
           

            super.paintComponent(g);

            RealC[0][0] = 1.0;
            ImagC[0][0] = 0.0;
            RealC[1][0] = 0.0;
            ImagC[1][0] = 0.0;
            RealC[0][1] = 0.0;
            ImagC[0][1] = 0.0;
            RealC[1][1] = 0.0;
            ImagC[1][1] = 0.0;

            iy0 = 62;
            ix0 = 0;
            iz0 = 0;
            
            blz0=iy0-ix0;
            blx0=0;

            t = 0.0;

            g.drawString("Bloch sphere",10,500);
            g.drawOval(200-93, 500-62, 187, 125);
            for (i = 0; i < 400; i++) {
                for (i1 = 0; i1 < 100; i1++) {
                    t += tstep;
                    rk4(t);
                }
              
                
                
                g.setColor(Color.black);
                g.drawRect(0, 50, 400, 250);
                g.drawRect(0, 300, 400, 100);
                
                g.drawString("blue=rho(1,1) red=rho(2,2) green=|rho(1,2)|",10,10);
                

                iy1 = (int) (cabs(RealC[0][0], ImagC[0][0]) * 250.0);
                ix1 = (int) (cabs(RealC[1][1], ImagC[1][1]) * 250.0);
                iz1 = (int) (cabs(RealC[0][1], ImagC[0][1]) * 250.0);
                
                blz1=(iy1-ix1)/4;
                blx1=(int)(RealC[0][1]*187.0);
                

                g.setColor(Color.blue);
                g.drawLine(i, 300 - iy0, i + 1, 300 - iy1);
                iy0 = iy1;

                g.setColor(Color.red);
                g.drawLine(i, 300 - ix0, i + 1, 300 - ix1);
                ix0 = ix1;

                g.setColor(Color.green);
                g.drawLine(i, 300 - iz0, i + 1, 300 - iz1);
                iz0 = iz1;
                g.setColor(Color.black);
                g.drawString("time ", 200, 420);


                psum = pulse(i * 100.0 * tstep);
                psum1 = pulse((i+1) * 100.0 * tstep);
                if (twopulses) {
                    psum = psum + pulse2(i  * 100.0 * tstep);
                    psum1 = psum1 + pulse2((i + 1) * 100.0 * tstep);

                }

                ip0 = (int) (psum * 50.0);
                ip1 = (int) (psum1 * 50.0);
                g.drawLine(i, 350 - ip0, i + 1, 350 - ip1);
                g.setColor(Color.red);
                
                g.drawLine(200+blx0,500+blz0,200+blx1,500+blz1);
                blx0=blx1;
                blz0=blz1;
            }

        }
    }
}
