// QuantumCirc.java (C) 2001 by Paul Falstad, www.falstad.com
import java.io.InputStream;
import java.awt.*;
import java.awt.image.ImageProducer;
import java.applet.Applet;
import java.applet.AudioClip;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.File;
import java.net.URL;
import java.util.Random;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.awt.image.*;
import java.lang.Math;
import java.awt.event.*;
class QuantumCircCanvas extends Canvas {
QuantumCircFrame pg;
QuantumCircCanvas(QuantumCircFrame p) {
pg = p;
}
public Dimension getPreferredSize() {
return new Dimension(300,400);
}
public void update(Graphics g) {
pg.updateQuantumCirc(g);
}
public void paint(Graphics g) {
pg.updateQuantumCirc(g);
}
};
class QuantumCircLayout implements LayoutManager {
public QuantumCircLayout() {}
public void addLayoutComponent(String name, Component c) {}
public void removeLayoutComponent(Component c) {}
public Dimension preferredLayoutSize(Container target) {
return new Dimension(500, 500);
}
public Dimension minimumLayoutSize(Container target) {
return new Dimension(100,100);
}
public void layoutContainer(Container target) {
Insets insets = target.insets();
int targetw = target.size().width - insets.left - insets.right;
int cw = targetw* 7/10;
int targeth = target.size().height - (insets.top+insets.bottom);
target.getComponent(0).move(insets.left, insets.top);
target.getComponent(0).resize(cw, targeth);
int barwidth = targetw - cw;
cw += insets.left;
int i;
int h = insets.top;
for (i = 1; i < target.getComponentCount(); i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
if (m instanceof Scrollbar)
d.width = barwidth;
if (m instanceof Choice)
d.width = barwidth;
if (m instanceof Label) {
h += d.height/5;
d.width = barwidth;
}
m.move(cw, h);
m.resize(d.width, d.height);
h += d.height;
}
}
}
};
public class QuantumCirc extends Applet implements ComponentListener {
static QuantumCircFrame ogf;
void destroyFrame() {
if (ogf != null)
ogf.dispose();
ogf = null;
repaint();
}
boolean started = false;
public void init() {
addComponentListener(this);
}
public static void main(String args[]) {
ogf = new QuantumCircFrame(null);
ogf.init();
}
void showFrame() {
if (ogf == null) {
started = true;
ogf = new QuantumCircFrame(this);
ogf.init();
repaint();
}
}
public void paint(Graphics g) {
String s = "Applet is open in a separate window.";
if (!started)
s = "Applet is starting.";
else if (ogf == null)
s = "Applet is finished.";
else
ogf.show();
g.drawString(s, 10, 30);
}
public void componentHidden(ComponentEvent e){}
public void componentMoved(ComponentEvent e){}
public void componentShown(ComponentEvent e) { showFrame(); }
public void componentResized(ComponentEvent e) {}
public void destroy() {
if (ogf != null)
ogf.dispose();
ogf = null;
repaint();
}
};
class QuantumCircFrame extends Frame
implements ComponentListener, ActionListener, AdjustmentListener,
MouseMotionListener, MouseListener, ItemListener {
Thread engine = null;
Dimension winSize;
Image dbimage;
Random random;
int maxSampleCount = 70;
int maxDispPhasorsR = 10;
int maxDispPhasorsTh = 21;
int sampleCountR, sampleCountTh;
int modeCountR, modeCountTh, modeCountM;
FFT fftTh;
public static final double epsilon = .00001;
public static final double epsilon2 = .003;
static final int panePad = 4;
public String getAppletInfo() {
return "QuantumCirc Series by Paul Falstad";
}
Button groundButton;
Button blankButton;
Button normalizeButton;
Button maximizeButton;
Checkbox stoppedCheck;
CheckboxMenuItem eCheckItem;
CheckboxMenuItem xCheckItem;
CheckboxMenuItem pCheckItem;
CheckboxMenuItem lCheckItem;
CheckboxMenuItem statesCheckItem;
CheckboxMenuItem expectCheckItem;
CheckboxMenuItem uncertaintyCheckItem;
CheckboxMenuItem probCheckItem;
CheckboxMenuItem probPhaseCheckItem;
CheckboxMenuItem magPhaseCheckItem;
CheckboxMenuItem alwaysNormItem;
CheckboxMenuItem alwaysMaxItem;
Menu waveFunctionMenu;
MenuItem measureEItem;
MenuItem measureLItem;
MenuItem exitItem;
Choice mouseChooser;
Checkbox colorCheck;
Scrollbar brightnessBar;
Scrollbar speedBar;
Scrollbar forceBar;
Scrollbar resBar;
Scrollbar phasorBar;
Scrollbar pZoomBar;
int pZoomBarValue;
View viewPotential, viewX, viewP, viewStates,
viewXMap, viewPMap, viewStatesMap, viewL;
View viewList[];
int viewCount;
boolean editingFunc;
boolean dragStop;
double magcoef[][];
double phasecoef[][];
double phasecoefcos[][];
double phasecoefsin[][];
double phasecoefadj[][];
double angle1SinTab[];
double angle1CosTab[];
double angle2SinTab[];
double angle2CosTab[];
double elevels[][];
double xformbuf[];
double lzspectrum[];
static final double pi = 3.14159265358979323846;
double step;
double func[][];
double funci[][];
double pfunc[][];
double pfunci[][];
PhaseColor phaseColors[][];
PhaseColor whitePhaseColor;
Color grayLevels[];
static final int phaseColorCount = 50;
int xpoints[];
int ypoints[];
int floorValues[];
double xStates[][][];
double pStates[][][];
int selectedCoefX, selectedCoefY;
double selectedGridX, selectedGridY;
int selectedPaneHandle;
static final int SEL_NONE = 0;
static final int SEL_POTENTIAL = 1;
static final int SEL_X = 2;
static final int SEL_STATES = 3;
static final int SEL_L = 4;
static final int SEL_HANDLE = 5;
static final int MOUSE_GAUSS = 0;
static final int MOUSE_GAUSSP = 1;
static final int MOUSE_ROTATE = 2;
int selection;
int dragX, dragY;
int dragStartX, dragStartY;
boolean dragSet, dragClear;
double viewZoom = 1, viewZoomDragStart;
double scaleHeight = 6;
double viewHeight = -14, viewHeightDragStart;
double viewDistance;
double magDragStart;
boolean dragging;
double t;
int pause;
double scalex, scaley;
int centerX3d;
int centerY3d;
double topz = 3;
double brightmult;
int getrand(int x) {
int q = random.nextInt();
if (q < 0) q = -q;
return q % x;
}
QuantumCircCanvas cv;
QuantumCirc applet;
QuantumCircFrame(QuantumCirc a) {
super("Quantum Circular Box Applet v1.5a");
applet = a;
}
boolean useBufferedImage = false;
public void init() {
String jv = System.getProperty("java.class.version");
double jvf = new Double(jv).doubleValue();
if (jvf >= 48)
useBufferedImage = true;
selectedCoefX = selectedCoefY = -1;
setLayout(new QuantumCircLayout());
cv = new QuantumCircCanvas(this);
cv.addComponentListener(this);
cv.addMouseMotionListener(this);
cv.addMouseListener(this);
add(cv);
MenuBar mb = new MenuBar();
Menu m = new Menu("File");
mb.add(m);
m.add(exitItem = getMenuItem("Exit"));
m = new Menu("View");
mb.add(m);
m.add(eCheckItem = getCheckItem("Energy"));
eCheckItem.setState(true);
m.add(xCheckItem = getCheckItem("Position"));
xCheckItem.setState(true);
xCheckItem.disable();
m.add(pCheckItem = getCheckItem("Linear Momentum"));
m.add(lCheckItem = getCheckItem("Angular Momentum"));
m.add(statesCheckItem = getCheckItem("State Phasors"));
statesCheckItem.setState(true);
m.addSeparator();
m.add(expectCheckItem = getCheckItem("Expectation Values"));
m.add(uncertaintyCheckItem = getCheckItem("Uncertainties"));
Menu m2 = waveFunctionMenu = new Menu("Wave Function");
m.add(m2);
m2.add(probCheckItem = getCheckItem("Probability"));
m2.add(probPhaseCheckItem = getCheckItem("Probability + Phase"));
m2.add(magPhaseCheckItem = getCheckItem("Magnitude + Phase"));
magPhaseCheckItem.setState(true);
m = new Menu("Measure");
mb.add(m);
m.add(measureEItem = getMenuItem("Measure Energy"));
m.add(measureLItem = getMenuItem("Measure Angular Momentum"));
setMenuBar(mb);
m = new Menu("Options");
mb.add(m);
m.add(alwaysNormItem = getCheckItem("Always Normalize"));
m.add(alwaysMaxItem = getCheckItem("Always Maximize"));
alwaysMaxItem.setState(true);
setMenuBar(mb);
mouseChooser = new Choice();
mouseChooser.add("Mouse = Create Gaussian");
mouseChooser.add("Mouse = Gaussian w/ Momentum");
mouseChooser.add("Mouse = Rotate Function");
mouseChooser.addItemListener(this);
add(mouseChooser);
mouseChooser.select(MOUSE_GAUSS);
add(blankButton = new Button("Clear"));
blankButton.addActionListener(this);
add(normalizeButton = new Button("Normalize"));
normalizeButton.addActionListener(this);
add(maximizeButton = new Button("Maximize"));
maximizeButton.addActionListener(this);
add(groundButton = new Button("Ground State"));
groundButton.addActionListener(this);
stoppedCheck = new Checkbox("Stopped");
stoppedCheck.addItemListener(this);
add(stoppedCheck);
add(new Label("Simulation Speed", Label.CENTER));
add(speedBar = new Scrollbar(Scrollbar.HORIZONTAL, 105, 1, 1, 300));
speedBar.addAdjustmentListener(this);
add(new Label("Brightness", Label.CENTER));
add(brightnessBar =
new Scrollbar(Scrollbar.HORIZONTAL, 980, 1, 700, 2000));
brightnessBar.addAdjustmentListener(this);
add(new Label("Resolution", Label.CENTER));
add(resBar = new Scrollbar(Scrollbar.HORIZONTAL,
16, 1, 2, maxSampleCount/2));
resBar.addAdjustmentListener(this);
add(new Label("Momentum Zoom", Label.CENTER));
add(pZoomBar = new Scrollbar(Scrollbar.HORIZONTAL,
166, 1, 45, 260));
pZoomBar.addAdjustmentListener(this);
add(new Label("Phasor Count", Label.CENTER));
add(phasorBar = new Scrollbar(Scrollbar.HORIZONTAL,
10, 1, 5, maxSampleCount/2));
phasorBar.addAdjustmentListener(this);
setResolution();
try {
String param = applet.getParameter("PAUSE");
if (param != null)
pause = Integer.parseInt(param);
} catch (Exception e) { }
int i, j;
phaseColors = new PhaseColor[8][phaseColorCount+1];
for (i = 0; i != 8; i++)
for (j = 0; j <= phaseColorCount; j++) {
double ang = java.lang.Math.atan(j/(double) phaseColorCount);
phaseColors[i][j] = genPhaseColor(i, ang);
}
whitePhaseColor = new PhaseColor(1, 1, 1);
grayLevels = new Color[256];
for (i = 0; i != 256; i++)
grayLevels[i] = new Color(i, i, i);
random = new Random();
reinit();
cv.setBackground(Color.black);
cv.setForeground(Color.lightGray);
resize(640, 600);
handleResize();
Dimension x = getSize();
Dimension screen = getToolkit().getScreenSize();
setLocation((screen.width - x.width)/2,
(screen.height - x.height)/2);
show();
}
MenuItem getMenuItem(String s) {
MenuItem mi = new MenuItem(s);
mi.addActionListener(this);
return mi;
}
CheckboxMenuItem getCheckItem(String s) {
CheckboxMenuItem mi = new CheckboxMenuItem(s);
mi.addItemListener(this);
return mi;
}
PhaseColor genPhaseColor(int sec, double ang) {
// convert to 0 .. 2*pi angle
ang += sec*pi/4;
// convert to 0 .. 6
ang *= 3/pi;
int hsec = (int) ang;
double a2 = ang % 1;
double a3 = 1.-a2;
PhaseColor c = null;
switch (hsec) {
case 6:
case 0: c = new PhaseColor(1, a2, 0); break;
case 1: c = new PhaseColor(a3, 1, 0); break;
case 2: c = new PhaseColor(0, 1, a2); break;
case 3: c = new PhaseColor(0, a3, 1); break;
case 4: c = new PhaseColor(a2, 0, 1); break;
case 5: c = new PhaseColor(1, 0, a3); break;
}
return c;
}
void reinit() {
doBlank();
magcoef[1][0] = 1;
}
void handleResize() {
Dimension d = winSize = cv.getSize();
if (winSize.width == 0)
return;
dbimage = createImage(d.width, d.height);
setupDisplay();
}
void setupDisplay() {
if (winSize == null)
return;
int potsize = (viewPotential == null) ? 50 : viewPotential.height;
int statesize = (viewStates == null) ? 150 : viewStates.height;
viewX = viewL = viewP = viewPotential = viewStates = null;
viewList = new View[10];
int i = 0;
if (eCheckItem.getState())
viewList[i++] = viewPotential = new View();
if (xCheckItem.getState())
viewList[i++] = viewX = new View();
if (pCheckItem.getState())
viewList[i++] = viewP = new View();
if (lCheckItem.getState())
viewList[i++] = viewL = new View();
if (statesCheckItem.getState())
viewList[i++] = viewStates = new View();
viewCount = i;
int sizenum = viewCount;
int toth = winSize.height;
// preserve size of potential and state panes if possible
if (potsize > 0 && viewPotential != null) {
sizenum--;
toth -= potsize;
}
if (statesize > 0 && viewStates != null) {
sizenum--;
toth -= statesize;
}
toth -= panePad*2*(viewCount-1);
int cury = 0;
for (i = 0; i != viewCount; i++) {
View v = viewList[i];
int h = toth/sizenum;
if (v == viewPotential && potsize > 0)
h = potsize;
else if (v == viewStates && statesize > 0)
h = statesize;
v.paneY = cury;
if (cury > 0)
cury += panePad;
v.x = 0;
v.width = winSize.width;
v.y = cury;
v.height = h;
cury += h+panePad;
}
setSubViews();
}
void setSubViews() {
viewXMap = null;
viewStatesMap = null;
if (viewStates != null) {
viewStatesMap = new View(viewStates);
double a = viewStates.width / (double) viewStates.height;
double a2 = modeCountTh / (double) modeCountR;
int w, h;
if (a2 > a)
w = viewStates.width-2;
else
w = (int) ((viewStates.height-2)*a2);
viewStatesMap.x += (viewStatesMap.width -w)/2 + 1;
viewStatesMap.width = w;
}
if (viewX != null) {
viewXMap = new View(viewX);
processMap(viewXMap);
}
if (viewP != null) {
viewPMap = new View(viewP);
processMap(viewPMap);
}
if (viewL != null) {
View v = viewL;
v.mid_y = v.y + v.height/2;
v.ymult = .90*v.height/2;
v.lower_y = (int) (v.mid_y+v.ymult);
v.ymult2 = v.ymult*2;
}
floorValues = null;
}
void processMap(View v) {
double a = v.width / (double) v.height;
int w, h;
if (1 > a)
w = h = v.width-2;
else
w = h = v.height-2;
v.x += (v.width -w)/2 + 1;
v.y += (v.height-h)/2 + 1;
v.width = w;
v.height = h;
if (useBufferedImage) {
try {
/* simulate the following code using reflection:
dbimage = new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_RGB);
DataBuffer db = (DataBuffer)(((BufferedImage)memimage).
getRaster().getDataBuffer());
DataBufferInt dbi = (DataBufferInt) db;
pixels = dbi.getData();
*/
Class biclass = Class.forName("java.awt.image.BufferedImage");
Class dbiclass = Class.forName("java.awt.image.DataBufferInt");
Class rasclass = Class.forName("java.awt.image.Raster");
Constructor cstr = biclass.getConstructor(
new Class[] { int.class, int.class, int.class });
v.memimage = (Image) cstr.newInstance(new Object[] {
new Integer(v.width), new Integer(v.height),
new Integer(1)}); // BufferedImage.TYPE_INT_RGB)});
Method m = biclass.getMethod("getRaster", null);
Object ras = m.invoke(v.memimage, null);
Object db = rasclass.getMethod("getDataBuffer", null).
invoke(ras, null);
v.pixels = (int[])
dbiclass.getMethod("getData", null).invoke(db, null);
} catch (Exception ee) {
// ee.printStackTrace();
System.out.println("BufferedImage failed");
}
}
if (v.pixels == null) {
v.pixels = new int[v.width*v.height];
int i;
for (i = 0; i != v.width*v.height; i++)
v.pixels[i] = 0xFF000000;
v.imageSource = new MemoryImageSource(v.width, v.height,
v.pixels, 0, v.width);
v.imageSource.setAnimated(true);
v.imageSource.setFullBufferUpdates(true);
v.memimage = cv.createImage(v.imageSource);
}
}
int min(int x, int y) { return (x < y) ? x : y; }
/*if (viewFreq != null) {
viewFreq.x = (winSize.width-viewFreq.height)/2;
viewFreq.width -= viewFreq.x*2;
int tw = getTermWidth();
int h = tw*(modeCountR+1);
int pad = viewFreq.height-h;
if (pad > 0) {
viewFreq.y += pad;
viewFreq.height -= pad;
if (view3d != null)
view3d.height += pad;
if (view2d != null)
view2d.height += pad;
}
}*/
void doGround() {
doBlank();
magcoef[0][0] = 1;
t = 0;
}
void normalize() {
double norm = 0;
int i, j;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
norm += magcoef[i][j]*magcoef[i][j];
if (norm == 0)
return;
double normmult = 1/java.lang.Math.sqrt(norm);
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
magcoef[i][j] *= normmult;
cv.repaint(pause);
}
void maximize() {
int i, j;
double maxm = 0;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
if (java.lang.Math.abs(magcoef[i][j]) > maxm)
maxm = java.lang.Math.abs(magcoef[i][j]);
if (maxm == 0)
return;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
magcoef[i][j] *= 1/maxm;
cv.repaint(pause);
}
void measureE() {
normalize();
double n = random.nextDouble();
int i = 0, j = 0;
int picki = -1;
int pickj = -1;
for (i = 0; i < modeCountTh; i++)
for (j = 0; j < modeCountR; j++) {
double m = magcoef[i][j]*magcoef[i][j];
n -= m;
if (n < 0) {
picki = i;
pickj = j;
i = j = 10000;
break;
}
}
if (picki == -1)
return;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
if (elevels[i][j] != elevels[picki][pickj])
magcoef[i][j] = 0;
if (alwaysNormItem.getState())
normalize();
else
maximize();
}
final int lspacing = 3;
void calcLSpectrum() {
int lzcount = modeCountTh*lspacing;
if (lzspectrum == null)
lzspectrum = new double[lzcount];
int i, j;
for (i = 0; i != lzcount; i++)
lzspectrum[i] = 0;
int lc = (lzcount/2);
for (i = 0; i != modeCountTh; i++) {
int m = ((i % 2) == 0) ?
(i/2*lspacing+lc) :
(lc-lspacing*(i+1)/2);
for (j = 0; j != modeCountR; j++)
lzspectrum[m] += magcoef[i][j]*magcoef[i][j];
}
}
void measureL() {
normalize();
calcLSpectrum();
double n = random.nextDouble();
int i = 0;
int picki = -1;
int lzcount = modeCountTh*lspacing;
for (i = 0; i != lzcount; i++) {
double m = lzspectrum[i];
n -= m;
if (n < 0) {
picki = i;
i = lzcount;
break;
}
}
if (picki == -1)
return;
int lc = (lzcount/2);
int j;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++) {
int m = ((i % 2) == 0) ?
(i/2*lspacing+lc) :
(lc-lspacing*(i+1)/2);
if (m != picki)
magcoef[i][j] = 0;
}
if (alwaysNormItem.getState())
normalize();
else
maximize();
}
void doBlank() {
int x, y;
for (x = 0; x != modeCountTh; x++)
for (y = 0; y != modeCountR; y++)
magcoef[x][y] = 0;
}
int getPanelHeight() { return winSize.height / 3; }
void centerString(Graphics g, String s, int y) {
FontMetrics fm = g.getFontMetrics();
g.drawString(s, (winSize.width-fm.stringWidth(s))/2, y);
}
public void paint(Graphics g) {
cv.repaint();
}
long lastTime;
public void updateQuantumCirc(Graphics realg) {
Graphics g = dbimage.getGraphics();
if (winSize == null || winSize.width == 0 || dbimage == null)
return;
boolean allQuiet = true;
if (!stoppedCheck.getState() && !dragging) {
int val = speedBar.getValue();
double tadd = java.lang.Math.exp(val/20.)*(.1/5);
long sysTime = System.currentTimeMillis();
if (lastTime == 0)
lastTime = sysTime;
tadd *= (sysTime-lastTime)*(1/170.);
t += tadd;
lastTime = sysTime;
allQuiet = false;
} else
lastTime = 0;
Color gray1 = new Color(76, 76, 76);
Color gray2 = new Color(127, 127, 127);
g.setColor(cv.getBackground());
g.fillRect(0, 0, winSize.width, winSize.height);
g.setColor(cv.getForeground());
int i, j;
for (i = 1; i != viewCount; i++) {
g.setColor(i == selectedPaneHandle ? Color.yellow : Color.gray);
g.drawLine(0, viewList[i].paneY,
winSize.width, viewList[i].paneY);
}
int x, y;
if (dragStop)
t = 0;
double norm = 0;
double normmult = 0, normmult2 = 0;
if (!editingFunc) {
// update phases
for (i = 0; i != modeCountTh; i++) {
for (j = 0; j != modeCountR; j++) {
if (magcoef[i][j] < epsilon && magcoef[i][j] > -epsilon) {
magcoef[i][j] = phasecoef[i][j] =
phasecoefadj[i][j] = 0;
continue;
}
allQuiet = false;
phasecoef[i][j] =
(-elevels[i][j]*t+phasecoefadj[i][j]) % (2*pi);
phasecoefcos[i][j] = java.lang.Math.cos(phasecoef[i][j]);
phasecoefsin[i][j] = java.lang.Math.sin(phasecoef[i][j]);
norm += magcoef[i][j]*magcoef[i][j];
}
}
normmult2 = 1/norm;
if (norm == 0)
normmult2 = 0;
normmult = java.lang.Math.sqrt(normmult2);
genFunc(normmult, true);
}
brightmult =
java.lang.Math.exp(brightnessBar.getValue()/200.-5);
if (norm == 0)
normmult = normmult2 = 0;
int half = sampleCountTh/2;
xpoints = new int[4];
ypoints = new int[4];
if (viewPotential != null) {
int floory = viewPotential.y + viewPotential.height - 5;
double ymult = 200;
if (floorValues == null)
floorValues = new int[floory+1];
for (i = 0; i <= floory; i++)
floorValues[i] = 0;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++) {
double dy = elevels[i][j];
double m = magcoef[i][j]*magcoef[i][j];
int mc = (int) ((256-32)*m)+1;
y = floory - (int) (ymult * dy);
if (y >= 0 && y <= floory)
floorValues[y] += mc;
}
for (i = 0; i <= floory; i++) {
if (floorValues[i] == 0)
continue;
int mc = floorValues[i]+32;
if (mc > 255)
mc = 255;
g.setColor(grayLevels[mc]);
g.drawLine(0, i, winSize.width, i);
}
g.setColor(Color.white);
g.drawLine(viewXMap.x, 0, viewXMap.x, floory);
int x0 = viewXMap.x+viewXMap.width;
g.drawLine(x0, 0, x0, floory);
g.drawLine(viewXMap.x, floory, x0, floory);
// calculate expectation value of E
if (norm != 0 && (expectCheckItem.getState() ||
uncertaintyCheckItem.getState())) {
double expecte = 0;
double expecte2 = 0;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++) {
double prob = magcoef[i][j]*magcoef[i][j]*normmult2;
expecte += prob*elevels[i][j];
expecte2 += prob*elevels[i][j]*elevels[i][j];
}
double uncert = java.lang.Math.sqrt(expecte2-expecte*expecte);
if (uncertaintyCheckItem.getState()) {
if (!(uncert >= 0))
uncert = 0;
g.setColor(Color.blue);
y = floory - (int) (ymult * (expecte+uncert));
g.drawLine(0, y, winSize.width, y);
y = floory - (int) (ymult * (expecte-uncert));
if (expecte-uncert >= 0)
g.drawLine(0, y, winSize.width, y);
}
if (expectCheckItem.getState()) {
y = floory - (int) (ymult * expecte);
g.setColor(Color.red);
g.drawLine(0, y, winSize.width, y);
}
}
if (selectedCoefX != -1 && !dragging) {
g.setColor(Color.yellow);
y = floory - (int) (ymult * elevels[selectedCoefX][selectedCoefY]);
g.drawLine(0, y, winSize.width, y);
}
}
if (viewX != null)
drawRadial(g, viewXMap, func, funci);
if (viewP != null) {
genFunc(normmult, false);
drawRadial(g, viewPMap, pfunc, pfunci);
}
if (viewL != null) {
int lzcount = modeCountTh*lspacing;
calcLSpectrum();
for (i = 0; i != lzcount; i++)
lzspectrum[i] = java.lang.Math.sqrt(lzspectrum[i]);
drawFunction(g, viewL, lzspectrum, null, lzcount, 0);
}
if (viewStatesMap != null) {
// draw frequency grid
int termWidth = getTermWidth();
int stateSize = termWidth;
int ss2 = termWidth/2;
for (i = 0; i < modeCountTh && i < maxDispPhasorsTh; i++)
for (j = 0; j < modeCountR && j < maxDispPhasorsR; j++) {
x = viewStatesMap.x + i*termWidth + ss2;
y = viewStatesMap.y + j*termWidth + ss2;
boolean yel = (selectedCoefX != -1 &&
elevels[selectedCoefX][selectedCoefY] == elevels[i][j]);
g.setColor(yel ? Color.yellow :
(magcoef[i][j] == 0) ? gray2 : Color.white);
g.drawOval(x-ss2, y-ss2, stateSize, stateSize);
int xa = (int) (magcoef[i][j]*phasecoefcos[i][j]*ss2);
int ya = (int) (-magcoef[i][j]*phasecoefsin[i][j]*ss2);
g.drawLine(x, y, x+xa, y+ya);
g.drawLine(x+xa-1, y+ya, x+xa+1, y+ya);
g.drawLine(x+xa, y+ya-1, x+xa, y+ya+1);
}
g.setColor(Color.white);
}
if (selectedCoefX != -1) {
g.setColor(Color.yellow);
int m = (selectedCoefX+1)/2;
if ((selectedCoefX & 1) != 0)
m = -m;
if (viewStatesMap != null && viewX != null)
centerString(g, "nr = " + selectedCoefY + ", m = " + m,
viewX.y+viewX.height-10);
if (viewL != null) {
int lzcount = modeCountTh*lspacing; // XXX
int mx = m * lspacing + lzcount/2;
x = viewL.width*mx/(lzcount-1);
g.drawLine(x, viewL.y, x, viewL.y+viewL.height);
}
}
realg.drawImage(dbimage, 0, 0, this);
if (dragStop)
allQuiet = true;
if (!stoppedCheck.getState() && !allQuiet)
cv.repaint(pause);
}
void drawRadial(Graphics g, View view, double fr[][], double fi[][]) {
int rcol = 0x00010000;
int gcol = 0x00000100;
int cx = view.width/2;
int cy = view.height/2;
int cr = view.width/2;
int x, y;
double mx = 0;
double expectx = 0, expectx2 = 0;
double expecty = 0, expecty2 = 0;
double tot = 0;
for (y = 0; y <= sampleCountR; y++) {
for (x = 0; x != sampleCountTh; x++) {
double ar = fr[x][y];
double ai = fi[x][y];
double fv = (ar*ar+ai*ai);
double xv = y*angle1CosTab[x];
double yv = y*angle1SinTab[x];
expectx += fv*y*xv;
expecty += fv*y*yv;
expectx2 += fv*y*xv*xv;
expecty2 += fv*y*yv*yv;
tot += fv*y;
if (magPhaseCheckItem.getState())
fv = java.lang.Math.sqrt(fv);
if (fv > mx)
mx = fv;
}
}
expectx /= tot;
expecty /= tot;
expectx2 /= tot;
expecty2 /= tot;
double mult = 255*brightmult/mx;
double rscale = -cr/(double) sampleCountR;
for (y = 0; y != sampleCountR; y++) {
double r1 = rscale*y;
double r2 = rscale*(y+1);
xpoints[0] = (int) (cx+r1);
ypoints[0] = cy;
xpoints[3] = (int) (cx+r2);
ypoints[3] = cy;
for (x = 0; x != sampleCountTh; x++) {
double ar = fr[x][y];
double ai = fi[x][y];
double fv = (ar*ar+ai*ai);
if (magPhaseCheckItem.getState())
fv = java.lang.Math.sqrt(fv);
fv *= mult;
PhaseColor c = getPhaseColor(ar, ai);
if (fv > 255)
fv = 255;
int clr = (int) (c.r * fv);
int clg = (int) (c.g * fv);
int clb = (int) (c.b * fv);
int col = (255<<24) | (clr<<16) | (clg<<8) | clb;
g.setColor(new Color(col));
xpoints[1] = (int) (cx+r1*angle2CosTab[x]);
ypoints[1] = (int) (cy-r1*angle2SinTab[x]);
xpoints[2] = (int) (cx+r2*angle2CosTab[x]);
ypoints[2] = (int) (cy-r2*angle2SinTab[x]);
fillTriangle(view, xpoints[0], ypoints[0], xpoints[1], ypoints[1],
xpoints[2], ypoints[2], col);
fillTriangle(view, xpoints[0], ypoints[0], xpoints[2], ypoints[2],
xpoints[3], ypoints[3], col);
xpoints[0] = xpoints[1];
ypoints[0] = ypoints[1];
xpoints[3] = xpoints[2];
ypoints[3] = ypoints[2];
}
}
if (view.imageSource != null)
view.imageSource.newPixels();
g.drawImage(view.memimage, view.x, view.y, null);
cx += view.x;
cy += view.y;
if (expectCheckItem.getState()) {
x = (int) (cx+expectx*rscale);
y = (int) (cy-expecty*rscale);
g.setColor(Color.red);
g.drawLine(x, view.y, x, view.y+view.height);
g.drawLine(view.x, y, view.x+view.width, y);
}
if (uncertaintyCheckItem.getState()) {
double uncertx = java.lang.Math.sqrt(expectx2-expectx*expectx);
double uncerty = java.lang.Math.sqrt(expecty2-expecty*expecty);
int xx1 = (int) (cx+(expectx+uncertx)*rscale);
int xx2 = (int) (cx+(expectx-uncertx)*rscale);
int yy1 = (int) (cy-(expecty-uncerty)*rscale);
int yy2 = (int) (cy-(expecty+uncerty)*rscale);
g.setColor(Color.blue);
g.drawRect(xx1, yy1, xx2-xx1, yy2-yy1);
}
g.setColor(Color.white);
g.drawOval(view.x, view.y, view.width, view.height);
}
void fillTriangle(View view, int x1, int y1, int x2, int y2, int x3, int y3,
int col) {
if (x1 > x2) {
if (x2 > x3) {
// x1 > x2 > x3
int ay = interp(x1, y1, x3, y3, x2);
fillTriangle1(view, x3, y3, x2, y2, ay, col);
fillTriangle1(view, x1, y1, x2, y2, ay, col);
} else if (x1 > x3) {
// x1 > x3 > x2
int ay = interp(x1, y1, x2, y2, x3);
fillTriangle1(view, x2, y2, x3, y3, ay, col);
fillTriangle1(view, x1, y1, x3, y3, ay, col);
} else {
// x3 > x1 > x2
int ay = interp(x3, y3, x2, y2, x1);
fillTriangle1(view, x2, y2, x1, y1, ay, col);
fillTriangle1(view, x3, y3, x1, y1, ay, col);
}
} else {
if (x1 > x3) {
// x2 > x1 > x3
int ay = interp(x2, y2, x3, y3, x1);
fillTriangle1(view, x3, y3, x1, y1, ay, col);
fillTriangle1(view, x2, y2, x1, y1, ay, col);
} else if (x2 > x3) {
// x2 > x3 > x1
int ay = interp(x2, y2, x1, y1, x3);
fillTriangle1(view, x1, y1, x3, y3, ay, col);
fillTriangle1(view, x2, y2, x3, y3, ay, col);
} else {
// x3 > x2 > x1
int ay = interp(x3, y3, x1, y1, x2);
fillTriangle1(view, x1, y1, x2, y2, ay, col);
fillTriangle1(view, x3, y3, x2, y2, ay, col);
}
}
}
int interp(int x1, int y1, int x2, int y2, int x) {
if (x1 == x2)
return y1;
if (x < x1 && x < x2 || x > x1 && x > x2)
System.out.print("interp out of bounds\n");
return (int) (y1+((double) x-x1)*(y2-y1)/(x2-x1));
}
void fillTriangle1(View v, int x1, int y1, int x2, int y2, int y3, int col) {
// x2 == x3
int dir = (x1 > x2) ? -1 : 1;
int x = x1;
if (x < 0) {
x = 0;
if (x2 < 0)
return;
}
if (x >= v.width) {
x = v.width-1;
if (x2 >= v.width)
return;
}
if (y2 > y3) {
int q = y2;
y2 = y3; y3 = q;
}
// y2 < y3
while (x != x2+dir) {
// XXX this could be speeded up
int ya = interp(x1, y1, x2, y2, x);
int yb = interp(x1, y1, x2, y3, x);
if (ya < 0)
ya = 0;
if (yb >= v.height)
yb = v.height-1;
int p1 = x+ya*v.width;
int p2 = x+yb*v.width;
for (; p1 <= p2; p1 += v.width)
v.pixels[p1] = col;
x += dir;
if (x < 0 || x >= v.width)
return;
}
}
void drawFunction(Graphics g, View view, double fr[], double fi[],
int count, int offset) {
int i;
double expectx = 0;
double expectx2 = 0;
double maxsq = 0;
double tot = 0;
int zero = winSize.width/2;
for (i = 0; i != count; i++) {
int x = winSize.width * i / (count-1);
int ii = i+offset;
double dr = fr[ii];
double di = (fi == null) ? 0 : fi[ii];
double dy = dr*dr+di*di;
if (dy > maxsq)
maxsq = dy;
int dev = x-zero;
expectx += dy*dev;
expectx2 += dy*dev*dev;
tot += dy;
}
expectx /= tot;
expectx2 /= tot;
double maxnm = java.lang.Math.sqrt(maxsq);
double uncert = java.lang.Math.sqrt(expectx2-expectx*expectx);
int ox = -1, oy = 0;
double bestscale = 0;
if (fi != null &&
(probCheckItem.getState() || probPhaseCheckItem.getState()))
bestscale = 1/maxsq;
else
bestscale = 1/maxnm;
view.scale = bestscale;
if (view.scale > 1e8)
view.scale = 1e8;
g.setColor(Color.gray);
int mid_x = winSize.width * (count/2) / (count-1);
g.drawLine(mid_x, view.y, mid_x, view.y+view.height);
int mid_y = view.lower_y;
double mult = view.ymult2*view.scale;
if (fi != null) {
g.setColor(Color.blue);
for (i = 0; i != count; i++) {
int x = winSize.width * i / (count-1);
int ii = i+offset;
int y = mid_y - (int) (mult * fi[ii]);
if (ox != -1)
g.drawLine(ox, oy, x, y);
ox = x;
oy = y;
}
}
g.setColor(Color.white);
ox = -1;
for (i = 0; i != count; i++) {
int x = winSize.width * i / (count-1);
int ii = i+offset;
int y = mid_y - (int) (mult * fr[ii]);
if (ox != -1)
g.drawLine(ox, oy, x, y);
ox = x;
oy = y;
}
if (maxsq > 0) {
expectx += zero;
if (uncertaintyCheckItem.getState()) {
g.setColor(Color.blue);
g.drawLine((int) (expectx-uncert), view.y,
(int) (expectx-uncert), view.y+view.height);
g.drawLine((int) (expectx+uncert), view.y,
(int) (expectx+uncert), view.y+view.height);
}
if (expectCheckItem.getState()) {
g.setColor(Color.red);
g.drawLine((int) expectx, view.y,
(int) expectx, view.y+view.height);
}
}
}
Color computeColor(int x, int y, double c) {
double h = func[x][y];
if (!colorCheck.getState()) {
h = 0;
}
if (c < 0)
c = 0;
if (c > 1)
c = 1;
c = .5 + c * .5;
double redness = (h < 0) ? -h : 0;
double grnness = (h > 0) ? h : 0;
if (redness > 1)
redness = 1;
if (grnness > 1)
grnness = 1;
if (grnness < 0)
grnness = 0;
if (redness < 0)
redness = 0;
double grayness = (1-(redness+grnness))*c;
double gray = .6;
return new Color((int) ((c*redness+gray*grayness)*255),
(int) ((c*grnness+gray*grayness)*255),
(int) ((gray*grayness)*255));
}
void genFunc(double normmult, boolean do_x) {
int i, j, th, r;
int wc = sampleCountTh*2;
int wm = wc - 1;
double states[][][] = (do_x) ? xStates : pStates;
double outr[][] = (do_x) ? func : pfunc;
double outi[][] = (do_x) ? funci : pfunci;
// step through each value of r and use inverse fft to calculate
// values for all theta
for (r = 0; r <= sampleCountR; r++) {
for (i = 0; i != wc; i++)
xformbuf[i] = 0;
// calculate contribution from modes with m=0
double d0r = 0;
double d0i = 0;
for (j = 0; j != modeCountR; j++) {
d0r += states[0][j][r]*magcoef[0][j]*phasecoefcos[0][j];
d0i += states[0][j][r]*magcoef[0][j]*phasecoefsin[0][j];
}
xformbuf[0] = d0r;
xformbuf[1] = d0i;
// calculate contributions from modes with m>0
for (i = 1; i < modeCountTh; i += 2) {
double d1r = 0, d2r = 0, d1i = 0, d2i = 0;
int ii = (i+1)/2;
for (j = 0; j != modeCountR; j++) {
d1r += states[ii][j][r]*magcoef[i][j]*
phasecoefcos[i][j];
d1i += states[ii][j][r]*magcoef[i][j]*
phasecoefsin[i][j];
d2r += states[ii][j][r]*magcoef[i+1][j]*
phasecoefcos[i+1][j];
d2i += states[ii][j][r]*magcoef[i+1][j]*
phasecoefsin[i+1][j];
}
if (!do_x) {
double adj = pi/2 * ii;
double acos = java.lang.Math.cos(adj);
double asin = java.lang.Math.sin(adj);
double q1 = d1r;
double q2 = d1i;
d1r = q1 * acos + q2 * asin;
d1i = -q1 * asin + q2 * acos;
q1 = d2r;
q2 = d2i;
d2r = q1 * acos + q2 * asin;
d2i = -q1 * asin + q2 * acos;
}
xformbuf[ii*2] = d2r;
xformbuf[ii*2+1] = d2i;
xformbuf[wm & (wc-ii*2)] = d1r;
xformbuf[wm & (wc-ii*2+1)] = d1i;
}
// take fft
fftTh.transform(xformbuf);
for (i = 0; i != sampleCountTh; i++) {
outr[i][r] = xformbuf[i*2] *normmult;
outi[i][r] = xformbuf[i*2+1]*normmult;
}
outr[sampleCountTh][r] = outr[0][r];
outi[sampleCountTh][r] = outi[0][r];
}
}
PhaseColor getPhaseColor(double x, double y) {
int sector = 0;
double val = 0;
if (probCheckItem.getState())
return whitePhaseColor;
if (x == 0 && y == 0)
return phaseColors[0][0];
if (y >= 0) {
if (x >= 0) {
if (x >= y) {
sector = 0;
val = y/x;
} else {
sector = 1;
val = 1-x/y;
}
} else {
if (-x <= y) {
sector = 2;
val = -x/y;
} else {
sector = 3;
val = 1+y/x;
}
}
} else {
if (x <= 0) {
if (y >= x) {
sector = 4;
val = y/x;
} else {
sector = 5;
val = 1-x/y;
}
} else {
if (-y >= x) {
sector = 6;
val = -x/y;
} else {
sector = 7;
val = 1+y/x;
}
}
}
return phaseColors[sector][(int) (val*phaseColorCount)];
}
int getTermWidth() {
int termWidth1 = viewStatesMap.width / min(modeCountTh, maxDispPhasorsTh);
int termWidth2 = viewStatesMap.height / min(modeCountR, maxDispPhasorsR);
return (termWidth1 < termWidth2) ? termWidth1 : termWidth2;
}
void edit(MouseEvent e) {
if (selection == SEL_NONE)
return;
int x = e.getX();
int y = e.getY();
switch (selection) {
case SEL_HANDLE: editHandle(y); break;
case SEL_STATES: editMag(x, y); break;
case SEL_POTENTIAL:
findStateByEnergy(y);
enterSelectedState();
break;
case SEL_X: editX(x, y); break;
case SEL_L: editL(x, y); break;
}
}
void editHandle(int y) {
int dy = y-viewList[selectedPaneHandle].paneY;
View upper = viewList[selectedPaneHandle-1];
View lower = viewList[selectedPaneHandle];
int minheight = 10;
if (upper.height+dy < minheight || lower.height-dy < minheight)
return;
upper.height += dy;
lower.height -= dy;
lower.y += dy;
lower.paneY += dy;
cv.repaint(pause);
setSubViews();
}
void editMag(int x, int y) {
if (selectedCoefX == -1)
return;
int stateSize = getTermWidth(); // XXX
int ss2 = stateSize/2;
int x0 = stateSize*selectedCoefX+ss2 + viewStatesMap.x;
int y0 = stateSize*selectedCoefY+ss2 + viewStatesMap.y;
x -= x0;
y -= y0;
double mag = java.lang.Math.sqrt(x*x+y*y)/ss2;
double ang = java.lang.Math.atan2(-y, x);
double ang0 = (-elevels[selectedCoefX][selectedCoefY]*t) % (2*pi);
if (mag > 10)
mag = 0;
if (mag > 1)
mag = 1;
magcoef[selectedCoefX][selectedCoefY] = mag;
phasecoefadj[selectedCoefX][selectedCoefY] = (ang-ang0) % (2*pi);
if (phasecoefadj[selectedCoefX][selectedCoefY] > pi)
phasecoefadj[selectedCoefX][selectedCoefY] -= 2*pi;
if (alwaysNormItem.getState())
normalize();
cv.repaint(pause);
}
void editMagClick() {
if (selectedCoefX == -1)
return;
if (magDragStart < .5)
magcoef[selectedCoefX][selectedCoefY] = 1;
else
magcoef[selectedCoefX][selectedCoefY] = 0;
phasecoefadj[selectedCoefX][selectedCoefY] = 0;
cv.repaint(pause);
}
void editX(int x, int y) {
switch (mouseChooser.getSelectedIndex()) {
case MOUSE_GAUSS:
editXGauss(x, y);
return;
case MOUSE_GAUSSP:
editXGaussP(x, y);
return;
case MOUSE_ROTATE:
editRotate(x, y);
return;
}
}
void editL(int x, int y) {
int xi = x * modeCountTh / winSize.width;
int m = xi - modeCountTh/2;
int r, th;
for (r = 0; r <= sampleCountR; r++)
for (th = 0; th <= sampleCountTh; th++) {
if (r == 0 && m != 0)
func[th][0] = funci[th][0] = 0;
else {
double thr = th*2*pi/sampleCountTh;
func [th][r] = java.lang.Math.cos(thr*m);
funci[th][r] = java.lang.Math.sin(thr*m);
}
}
transform();
cv.repaint(pause);
}
double lastGaussWx = -8, lastGaussWy = -8;
void editXGauss(int x, int y) {
int i, j;
int gx = x-dragX + 8;
int gy = y-dragY + 8;
double wx = 1/(abs(gx)+.0001);
double wy = 1/(abs(gy)+.0001);
wx = -wx*wx*2000;
wy = -wy*wy*2000;
lastGaussWx = wx;
lastGaussWy = wy;
for (x = 0; x != sampleCountR; x++) {
for (y = 0; y != sampleCountTh; y++) {
double th = y*2*pi/sampleCountTh;
double xx = -java.lang.Math.cos(th)*x/sampleCountR
- selectedGridX;
double yy = -java.lang.Math.sin(th)*x/sampleCountR
- selectedGridY;
double rfunc = java.lang.Math.exp(wx*xx*xx +
wy*yy*yy);
func[y][x] = rfunc;
funci[y][x] = 0;
}
}
transform();
cv.repaint(pause);
}
void editXGaussP(int x, int y) {
int i, j;
double wx = lastGaussWx;
double wy = lastGaussWy;
double momentumX = (x-dragX) * .1;
double momentumY = -(y-dragY) * .1;
for (x = 0; x != sampleCountR; x++) {
for (y = 0; y != sampleCountTh; y++) {
double th = y*2*pi/sampleCountTh;
double xx = -java.lang.Math.cos(th)*x/sampleCountR
- selectedGridX;
double yy = -java.lang.Math.sin(th)*x/sampleCountR
- selectedGridY;
double cx = java.lang.Math.cos(momentumX*xx);
double cy = java.lang.Math.cos(momentumY*yy);
double sx = java.lang.Math.sin(momentumX*xx);
double sy = java.lang.Math.sin(momentumY*yy);
double rfunc = java.lang.Math.exp(wx*xx*xx +
wy*yy*yy);
func[y][x] = rfunc*(cx*cy - sx*sy);
funci[y][x] = rfunc*(cx*sy + cy*sx);
}
}
transform();
cv.repaint(pause);
}
void editRotate(int x, int y) {
int cx = viewXMap.x + viewXMap.width/2;
int cy = viewXMap.y + viewXMap.height/2;
double angle1 = java.lang.Math.atan2(-(dragY-cy), dragX-cx);
double angle2 = java.lang.Math.atan2(-(y-cy), x-cx);
double ad = angle2-angle1;
int i, j;
for (i = 1; i < modeCountTh; i++)
for (j = 0; j < modeCountR; j++) {
int m = (i+1)/2;
if ((i % 2) == 0)
m = -m;
phasecoefadj[i][j] += ad*m;
}
dragX = x;
dragY = y;
cv.repaint(pause);
}
void transform() {
t = 0;
int i, j;
// zero out arrays. phasecoefcos and phasecoefsin are
// the real and imaginary parts of the state coefficients.
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
phasecoefcos[i][j] = phasecoefsin[i][j] = 0;
int r, th;
// integrate the function func[][] with each mode times r (since the
// modes are only orthogonal with a weighting function of r) and also
// integrate each mode with itself times r to get the norm.
for (r = 0; r <= sampleCountR; r++) {
// fft each set of samples at constant r
for (th = 0; th != sampleCountTh*2; th++)
xformbuf[th] = 0;
for (th = 0; th != sampleCountTh; th++) {
xformbuf[th*2] = func[th][r]*r;
xformbuf[th*2+1] = funci[th][r]*r;
}
fftTh.transform(xformbuf);
// perform integration step for each m=0 mode
for (j = 0; j != modeCountR; j++) {
phasecoefcos[0][j] += xStates[0][j][r]*xformbuf[0];
phasecoefsin[0][j] += xStates[0][j][r]*xformbuf[1];
}
// perform integration step with each m>0 mode
int wc = sampleCountTh*2;
int wm = wc - 1;
for (i = 1; i < modeCountTh; i += 2) {
for (j = 0; j != modeCountR; j++) {
int ii = i+1;
int m = ii/2;
phasecoefcos[i][j] += xStates[m][j][r]*
xformbuf[ii];
phasecoefsin[i][j] += xStates[m][j][r]*
xformbuf[ii+1];
phasecoefcos[i+1][j] += xStates[m][j][r]*
xformbuf[wm & -ii];
phasecoefsin[i+1][j] += xStates[m][j][r]*
xformbuf[wm & (-ii+1)];
}
}
}
// finish up by dividing out the norms and moving the results
// to magcoef and phasecoefadj
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++) {
double a = phasecoefcos[i][j];
double b = phasecoefsin[i][j];
if (a < epsilon && a > -epsilon) a = 0;
if (b < epsilon && b > -epsilon) b = 0;
magcoef[i][j] = java.lang.Math.sqrt(a*a+b*b);
phasecoefadj[i][j] = java.lang.Math.atan2(b, a);
}
if (alwaysNormItem.getState())
normalize();
else if (alwaysMaxItem.getState())
maximize();
}
int sign(int x) {
return (x < 0) ? -1 : (x == 0) ? 0 : 1;
}
int abs(int x) {
return x < 0 ? -x : x;
}
public void componentHidden(ComponentEvent e){}
public void componentMoved(ComponentEvent e){}
public void componentShown(ComponentEvent e) {
cv.repaint(pause);
}
public void componentResized(ComponentEvent e) {
handleResize();
cv.repaint(pause);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == exitItem) {
applet.destroyFrame();
return;
}
cv.repaint();
if (e.getSource() == groundButton)
doGround();
if (e.getSource() == blankButton)
doBlank();
if (e.getSource() == normalizeButton)
normalize();
if (e.getSource() == maximizeButton)
maximize();
if (e.getSource() == measureEItem)
measureE();
if (e.getSource() == measureLItem)
measureL();
}
public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.print(((Scrollbar) e.getSource()).getValue() + "\n");
if (e.getSource() == resBar) {
if (resBar.getValue() != modeCountR)
setResolution();
}
if (e.getSource() == pZoomBar)
calcPStates();
if (e.getSource() == phasorBar) {
maxDispPhasorsR = phasorBar.getValue();
maxDispPhasorsTh = maxDispPhasorsR*2+1;
}
cv.repaint(pause);
}
public boolean handleEvent(Event ev) {
if (ev.id == Event.WINDOW_DESTROY) {
applet.destroyFrame();
return true;
}
return super.handleEvent(ev);
}
void setResolution() {
int oldCountTh = modeCountTh;
int oldCountR = modeCountR;
// calculate number of samples in R and theta directions.
// number of theta samples must be power of 2 (for fft)
modeCountR = sampleCountR = resBar.getValue();
sampleCountR *= 4;
int sth = resBar.getValue() * 2;
sampleCountTh = 1;
while (sampleCountTh < sth)
sampleCountTh *= 2;
modeCountTh = sampleCountTh+1;
modeCountM = sampleCountTh/2 + 1;
sampleCountTh *= 2;
fftTh = new FFT(sampleCountTh);
double oldmagcoef[][] = magcoef;
magcoef = new double[modeCountTh][modeCountR];
phasecoef = new double[modeCountTh][modeCountR];
phasecoefcos = new double[modeCountTh][modeCountR];
phasecoefsin = new double[modeCountTh][modeCountR];
phasecoefadj = new double[modeCountTh][modeCountR];
xformbuf = new double[sampleCountTh*2];
func = new double[sampleCountTh+1][sampleCountR+1];
funci = new double[sampleCountTh+1][sampleCountR+1];
pfunc = new double[sampleCountTh+1][sampleCountR+1];
pfunci = new double[sampleCountTh+1][sampleCountR+1];
lzspectrum = null;
System.out.print("grid: " + sampleCountTh + " " +
sampleCountR + " " +
sampleCountTh * sampleCountR + "\n");
scaleHeight = 6;
step = pi/sampleCountTh;
viewDistance = 50;
int m, n;
elevels = new double[modeCountTh][modeCountR];
double angstep = step*2;
// m = angular modes
// n = radial modes
System.out.print("calc omegas...\n");
for (m = 0; m != modeCountTh; m++)
for (n = 0; n != modeCountR; n++) {
int realm = (m+1)/2;
elevels[m][n] = zeroj(realm, n+1)/sampleCountR;
}
System.out.print("calc omegas...done\n");
double jj[] = new double[modeCountM+1];
int x, y;
// x = th, y = r
xStates = new double[modeCountM][modeCountR][sampleCountR+1];
System.out.print("calc modes...\n");
for (m = 0; m != modeCountM; m++) {
for (n = 0; n != modeCountR; n++) {
double max = 0;
double nm = 0;
for (y = 0; y <= sampleCountR; y++) {
// work around bess() bug at x=0
if (y == 0)
jj[m+1] = (m == 0) ? 1 : 0;
else
bess(m, y*elevels[m*2][n], jj);
double q = xStates[m][n][y] = jj[m+1];
if (q > max)
max = q;
if (q < -max)
max = -q;
nm += q*q*y;
}
nm = java.lang.Math.sqrt(nm);
for (y = 0; y <= sampleCountR; y++)
xStates[m][n][y] /= nm;
}
}
double mult = .01/(elevels[0][0]*elevels[0][0]);
int i, j;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
elevels[i][j] *= elevels[i][j]*mult;
System.out.print("calc modes...done\n");
if (oldmagcoef != null) {
for (i = 0; i != oldCountTh && i != modeCountTh; i++)
for (j = 0; j != oldCountR && j != modeCountR; j++)
magcoef[i][j] = oldmagcoef[i][j];
}
pZoomBarValue = -1;
calcPStates();
angle1SinTab = new double[sampleCountTh+1];
angle1CosTab = new double[sampleCountTh+1];
angle2SinTab = new double[sampleCountTh+1];
angle2CosTab = new double[sampleCountTh+1];
for (i = 0; i <= sampleCountTh; i++) {
double th1 = 2*pi*i/sampleCountTh;
double th2 = 2*pi*(i+1)/sampleCountTh + .001;
angle1SinTab[i] = java.lang.Math.sin(th1);
angle1CosTab[i] = java.lang.Math.cos(th1);
angle2SinTab[i] = java.lang.Math.sin(th2);
angle2CosTab[i] = java.lang.Math.cos(th2);
}
}
void calcPStates() {
if (pZoomBar.getValue() == pZoomBarValue)
return;
pZoomBarValue = pZoomBar.getValue();
double pmult = pZoomBar.getValue() / (5.*sampleCountR);
double jj[] = new double[modeCountM+1];
double jz[] = new double[modeCountM+1];
int i, j, x, y, realm;
System.out.print("calc pstates\n");
pStates = new double[modeCountM][modeCountR][sampleCountR+1];
for (realm = 0; realm != modeCountM; realm++) {
int bessm = (realm == 0) ? 1 : realm;
for (j = 0; j != modeCountR; j++) {
double z0 = zeroj(realm, j+1);
bess(bessm, z0, jz);
jz[0] = -jz[2];
for (x = 0; x != sampleCountR; x++) {
// work around bess() bug at x=0
double x0 = pmult*x;
if (x == 0) {
if (realm == 0) {
jj[1] = 1;
jj[0] = 0;
} else {
jj[realm+1] = 0;
jj[realm] = (realm == 1) ? 1 : 0;
}
} else {
// calculate bessel functions of order 0
// through bessm and store in jj[1..bessm+1].
bess(bessm, x0, jj);
// We store J(-1, x) in jj[0]. It's just -J(1, x)
jj[0] = -jj[2];
}
pStates[realm][j][x] =
(z0*jz[realm]*jj[realm+1])/(x0*x0-z0*z0);
}
}
}
System.out.print("calc pstates, done\n");
}
// this routine not tested for m_order > 64 or n_zero > 34 !!
double zeroj( int m_order, int n_zero) {
// Zeros of the Bessel function J(x)
// Inputs
// m_order Order of the Bessel function
// n_zero Index of the zero (first, second, etc.)
// Output
// z The "n_zero"th zero of the Bessel function
if (m_order >= 48 && n_zero == 1) {
switch (m_order) {
case 48: return 55.0283;
case 49: return 56.0729;
case 50: return 57.1169;
case 51: return 58.1603;
case 52: return 59.2032;
case 53: return 60.2456;
case 54: return 61.2875;
case 55: return 62.3288;
case 56: return 63.3697;
case 57: return 64.4102;
case 58: return 65.4501;
case 59: return 66.4897;
case 60: return 67.5288;
case 61: return 68.5675;
case 62: return 69.6058;
case 63: return 70.6437;
case 64: return 71.6812;
}
}
if (m_order >= 62 && n_zero == 2) {
switch (m_order) {
case 62: return 75.6376;
case 63: return 76.7021;
case 64: return 77.7659;
}
}
//* Use asymtotic formula for initial guess
double beta = (n_zero + 0.5*m_order - 0.25)*(3.141592654);
double mu = 4*m_order*m_order;
double beta8 = 8*beta;
double beta82 = beta8*beta8;
double beta84 = beta82*beta82;
double z = beta - (mu-1)/beta8
- 4*(mu-1)*(7*mu-31)/(3*beta82*beta8);
z -= 32*(mu-1)*(83*mu*mu-982*mu+3779)/(15*beta84*beta8);
z -= 64*(mu-1)*(6949*mu*mu*mu-153855*mu*mu+1585743*mu-6277237)/
(105*beta84*beta82*beta8);
//* Use Newton's method to locate the root
double jj[] = new double[m_order+3];
int i; double deriv;
for( i=1; i<=5; i++ ) {
bess( m_order+1, z, jj ); // Remember j(1) is J_0(z)
// Use the recursion relation to evaluate derivative
deriv = -jj[m_order+2] + m_order/z * jj[m_order+1];
z -= jj[m_order+1]/deriv; // Newton's root finding
}
return(z);
}
void bess( int m_max, double x, double jj[] ) {
// Bessel function
// Inputs
// m_max Largest desired order
// x = Value at which Bessel function J(x) is evaluated
// Output
// jj = Vector of J(x) for order m = 0, 1, ..., m_max
//* Perform downward recursion from initial guess
int maxmx = (m_max > x) ? m_max : ((int)x); // Max(m,x)
// Recursion is downward from m_top (which is even)
int m_top = 2*((int)( (maxmx+15)/2 + 1 ));
double j[] = new double[m_top+2];
j[m_top+1] = 0.0;
j[m_top] = 1.0;
double tinyNumber = 1e-16;
int m;
for( m=m_top-2; m>=0; m--) // Downward recursion
j[m+1] = 2*(m+1)/(x+tinyNumber)*j[m+2] - j[m+3];
//* Normalize using identity and return requested values
double norm = j[1]; // NOTE: Be careful, m=0,1,... but
for( m=2; m<=m_top; m+=2 ) // vector goes j(1),j(2),...
norm += 2*j[m+1];
for( m=0; m<=m_max; m++ ) // Send back only the values for
jj[m+1] = j[m+1]/norm; // m=0,...,m_max and discard values
} // for m=m_max+1,...,m_top
void findGridPoint2D(View v, int mx, int my) {
int cx = v.x + v.width/2;
int cy = v.y + v.height/2;
int cr = v.width/2;
selectedGridX = (mx-cx)/(double) cr;
selectedGridY = -(my-cy)/(double) cr;
double r = java.lang.Math.sqrt(selectedGridX*selectedGridX +
selectedGridY*selectedGridY);
if (r > 1) {
selectedGridX /= r;
selectedGridY /= r;
}
}
public void mouseDragged(MouseEvent e) {
dragging = true;
edit(e);
}
public void mouseMoved(MouseEvent e) {
if (dragging)
return;
int x = e.getX();
int y = e.getY();
dragX = x; dragY = y;
int panelHeight = getPanelHeight();
int oldCoefX = selectedCoefX;
int oldCoefY = selectedCoefY;
selectedCoefX = -1;
selectedCoefY = -1;
selectedPaneHandle = -1;
selection = 0;
int i;
for (i = 1; i != viewCount; i++) {
int dy = y-viewList[i].paneY;
if (dy >= -3 && dy <= 3) {
selectedPaneHandle = i;
selection = SEL_HANDLE;
}
}
if (viewXMap != null && viewXMap.inside(x, y))
selection = SEL_X;
else if (viewPotential != null && viewPotential.contains(x, y)) {
selection = SEL_POTENTIAL;
findStateByEnergy(y);
} else if (viewStatesMap != null && viewStatesMap.inside(x, y)) {
int termWidth = getTermWidth();
selectedCoefX = (x-viewStatesMap.x)/termWidth;
selectedCoefY = (y-viewStatesMap.y)/termWidth;
if (selectedCoefX >= modeCountTh || selectedCoefX >= maxDispPhasorsTh)
selectedCoefX = selectedCoefY = -1;
if (selectedCoefY >= modeCountR || selectedCoefY >= maxDispPhasorsR)
selectedCoefX = selectedCoefY = -1;
if (selectedCoefX < 0 || selectedCoefY < 0)
selectedCoefX = selectedCoefY = -1;
if (selectedCoefX != -1 && selectedCoefY != -1)
selection = SEL_STATES;
} else if (viewL != null && viewL.contains(x, y))
selection = SEL_L;
if (selectedCoefX != oldCoefX || selectedCoefY != oldCoefY)
cv.repaint(pause);
}
void findStateByEnergy(int y) {
int i, j;
int floory = viewPotential.y + viewPotential.height - 5;
double ymult = 200;
double dist = 100;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++) {
int yy = floory - (int) (ymult * elevels[i][j]);
double d = java.lang.Math.abs(y-yy);
if (d < dist) {
dist = d;
selectedCoefX = i;
selectedCoefY = j;
}
}
}
public void mouseClicked(MouseEvent e) {
if (selection == SEL_STATES)
editMagClick();
if (e.getClickCount() == 2 && selectedCoefX != -1)
enterSelectedState();
}
void enterSelectedState() {
int i, j;
for (i = 0; i != modeCountTh; i++)
for (j = 0; j != modeCountR; j++)
if (selectedCoefX != i || selectedCoefY != j)
magcoef[i][j] = 0;
magcoef[selectedCoefX][selectedCoefY] = 1;
cv.repaint(pause);
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
if (!dragging) {
if (selectedCoefX != -1) {
selectedCoefX = selectedCoefY = -1;
cv.repaint(pause);
}
if (selectedPaneHandle != -1) {
selectedPaneHandle = -1;
cv.repaint(pause);
}
}
}
public void mousePressed(MouseEvent e) {
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) == 0)
return;
mouseMoved(e);
if (selection == SEL_X)
findGridPoint2D(viewXMap, e.getX(), e.getY());
dragStartX = e.getX();
dragStartY = e.getY();
if (selectedCoefX != -1)
magDragStart = magcoef[selectedCoefX][selectedCoefY];
dragging = true;
edit(e);
}
public void mouseReleased(MouseEvent e) {
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) == 0)
return;
dragging = editingFunc = dragStop = false;
dragSet = dragClear = false;
mouseMoved(e);
cv.repaint(pause);
}
public void itemStateChanged(ItemEvent e) {
if (e.getItemSelectable() == stoppedCheck) {
cv.repaint(pause);
return;
}
if (e.getItemSelectable() == xCheckItem ||
e.getItemSelectable() == pCheckItem ||
e.getItemSelectable() == lCheckItem ||
e.getItemSelectable() == eCheckItem ||
e.getItemSelectable() == statesCheckItem) {
handleResize();
cv.repaint(pause);
}
if (e.getItemSelectable() == alwaysNormItem &&
alwaysNormItem.getState()) {
normalize();
alwaysMaxItem.setState(false);
cv.repaint(pause);
}
if (e.getItemSelectable() == alwaysMaxItem &&
alwaysMaxItem.getState()) {
maximize();
alwaysNormItem.setState(false);
cv.repaint(pause);
}
int i;
for (i = 0; i != waveFunctionMenu.countItems(); i++)
if (e.getItemSelectable() == waveFunctionMenu.getItem(i)) {
int j;
((CheckboxMenuItem) waveFunctionMenu.getItem(i))
.setState(true);
for (j = 0; j != waveFunctionMenu.countItems(); j++)
if (i != j)
((CheckboxMenuItem) waveFunctionMenu.getItem(j))
.setState(false);
}
}
class FFT {
double wtab[];
int size;
FFT(int sz) {
size = sz;
if ((size & (size-1)) != 0)
System.out.println("size must be power of two!");
calcWTable();
}
void calcWTable() {
// calculate table of powers of w
wtab = new double[size];
int i;
for (i = 0; i != size; i += 2) {
double th = pi*i/size;
wtab[i ] = Math.cos(th);
wtab[i+1] = Math.sin(th);
}
}
void transform(double data[]) {
int i;
int j = 0;
int size2 = size*2;
// bit-reversal
for (i = 0; i != size2; i += 2) {
if (i > j) {
double q = data[i]; data[i] = data[j]; data[j] = q;
q = data[i+1]; data[i+1] = data[j+1]; data[j+1] = q;
}
// increment j by one, from the left side (bit-reversed)
int bit = size;
while ((bit & j) != 0) {
j &= ~bit;
bit >>= 1;
}
j |= bit;
}
// amount to skip through w table
int tabskip = size2;
int skip1;
for (skip1 = 4; skip1 <= size2; skip1 <<= 1) {
// skip2 = length of subarrays we are combining
// skip1 = length of subarray after combination
int skip2 = skip1 >> 1;
tabskip >>= 1;
// for each subarray
for (i = 0; i < size2; i += skip1) {
int ix = 0;
// for each pair of complex numbers (one in each subarray)
for (j = i; j != i+skip2; j += 2, ix += tabskip) {
double wr = wtab[ix];
double wi = wtab[ix+1];
double d1r = data[j];
double d1i = data[j+1];
int j2 = j+skip2;
double d2r = data[j2];
double d2i = data[j2+1];
double d2wr = d2r*wr - d2i*wi;
double d2wi = d2r*wi + d2i*wr;
data[j] = d1r+d2wr;
data[j+1] = d1i+d2wi;
data[j2 ] = d1r-d2wr;
data[j2+1] = d1i-d2wi;
};
}
}
}
}
class PhaseColor {
public double r, g, b;
PhaseColor(double rr, double gg, double bb) {
r = rr; g = gg; b = bb;
}
Color getColor() { return new Color((int) (r*255),
(int) (g*255),
(int) (b*255)); } // XXX
}
class View extends Rectangle {
View() { }
View(View v) { super(v); }
double ymult, ymult2, scale;
int mid_y, lower_y;
int paneY;
MemoryImageSource imageSource;
Image memimage;
int pixels[];
}
};
A far higher place must be assigned to Judaism among the competitors for the allegiance of Europe. The cosmopolitan importance at one time assumed by this religion has been considerably obscured, owing to the subsequent devolution of its part to Christianity. It is, however, by no means impossible that, but for the diversion created by the Gospel, and the disastrous consequences of their revolt against Rome, the Jews might have won the world to a purified form of their own monotheism. A few significant circumstances are recorded showing how much influence they had acquired, even in Rome, before the first preaching of Christianity. The first of these is to be found in Cicero¡¯s defence of Flaccus. The latter was accused of appropriating part of the annual contributions sent to the temple at Jerusalem; and, in dealing with this charge, Cicero speaks of the Jews, who were naturally prejudiced against his client, as a powerful faction the hostility of which he is anxious not to provoke.330 Some twenty years later, a great advance has been made. Not only must the material interests of the Jews be respected, but a certain conformity to their religious prescriptions is considered a mark of good breeding, In one of his most amusing satires, Horace tells us how, being anxious to shake off a bore, he appeals for help to his friend Aristius Fuscus, and reminds him of217 some private business which they had to discuss together. Fuscus sees his object, and being mischievously determined to defeat it, answers: ¡®Yes, I remember perfectly, but we must wait for some better opportunity; this is the thirtieth Sabbath, do you wish to insult the circumcised Jews?¡¯ ¡®I have no scruples on that point,¡® replies the impatient poet. ¡®But I have,¡¯ rejoins Fuscus,¡ª¡®a little weak-minded, one of the many, you know¡ªexcuse me, another time.¡®331 Nor were the Jews content with the countenance thus freely accorded them. The same poet elsewhere intimates that whenever they found themselves in a majority, they took advantage of their superior strength to make proselytes by force.¡¯332 And they pursued the good work to such purpose that a couple of generations later we find Seneca bitterly complaining that the vanquished had given laws to the victors, and that the customs of this abominable race were established over the whole earth.333 Evidence to the same effect is given by Philo Judaeus and Josephus, who inform us that the Jewish laws and customs were admired, imitated, and obeyed over the whole earth.334 Such assertions might be suspected of exaggeration, were they not, to a certain extent, confirmed by the references already quoted, to which others of the same kind may be added from later writers showing that it was a common practice among the Romans to abstain from work on the Sabbath, and even to celebrate it by praying, fasting, and lighting lamps, to visit the synagogues, to study the law of Moses, and to pay the yearly contribution of two drachmas to the temple at Jerusalem.335 Jeff¡¯s hand was quietly coming down. ¡°What happened to you?¡± begged Sandy. ¡°Something new has come up, sir. I was waiting there by my ship a good while back, and I heard another one cruising and spiraling, shooting the field, I guess, because he came in and set down. My crate, just the way you ordered, was down by the grove, not in plain sight in the middle of the course. But Jeff set his ship down, left the engine running, and went off. I stayed hid to see what would happen, but when he didn¡¯t come back, I thought I¡¯d better go and find you¡ªand see if it meant anything to you.¡± She stood alone, with the sticky, wet knife in her hand, catching her breath, coming out of the madness. Then she stooped, and pushing the branches aside felt about for her pistol. It lay at the root of a tree, and[Pg 80] when she had picked it up and put it back in the holster, there occurred to her for the first time the thought that the shot in the dead stillness must have roused the camp. And now she was sincerely frightened. If she were found here, it would be more than disagreeable for Landor. They must not find her. She started at a swift, long-limbed run, making a wide detour, to avoid the sentries, bending low, and flying silently among the bushes and across the shadowy sands. The year 1756 opened with menaces to England of the most serious nature. The imbecility of the Ministry was beginning to tell in the neglect of its colonies and its defences. France threatened to invade us, and a navy of fifty thousand men was suddenly voted, and an army of thirty-four thousand two hundred and sixty-three of native troops; but as these were not ready, it was agreed to bring over eight thousand Hessians and Hanoverians. To pay for all this it was necessary to grant excessive supplies, and lay on new duties and taxes. In presenting the money bills in the month of May, Speaker Onslow could not avoid remarking that there were two circumstances which tended to create alarm¡ªforeign subsidies and foreign troops introduced, and nothing but their confidence in his Majesty could allay their fears, or give them confidence that their burdens would be soon reduced. There was, in fact, no chance for any such reduction, for wars, troubles, and disgraces were gathering around from various quarters. The first reverse came from the Mediterranean. MUCH to their amazement, the boys waked up the next morning in Nashville, and found that they had passed through the "dark and bloody ground" of Kentucky absolutely without adventure. After drawing and dividing the rations and cartridges. Si gave the boys the necessary instruction about having their things ready so that they could get them in the dark the next morning, and ordered them to disregard the bonfires and mirth-making, and lie down to get all the sleep they could, in preparation for the hard work of the next day. Then, like the rest of the experienced men, who saw that the campaign was at length really on, and this would be the last opportunity for an indefinite while to write, he sat down to write short letters to his mother and to Annabel. "Bully for the Wild Wanderers of the Wabash," Shorty joined in. "They're the boss regiment in the army o' the Cumberland, and the Army o' the Cumberland's the boss army on earth. Hooray for US Co. Le's have a speech. Where's Monty Scruggs?" "Bring a light, do¡ªI can't abide this dark." Albert suddenly began to look uneasy. After all he was not really drunk, only a little fuddled. He walked straight, and his roll was natural to him, while though he was exceedingly cheerful, and often burst into song, his words were not jumbled, and he generally seemed to have a fair idea of what he was saying. "But I heard what the doctor said to you." "A purty accident¡ªwud them stacks no more dry than a ditch. 'Twas a clear case of 'bustion¡ªfireman said so to me; as wicked and tedious a bit o' wark as ever I met in my life." Calverley stept from the shadow of the cliff, and beheld a meteor in the sky, brightening and expanding, as the clouds opened, until it assumed the appearance of a brilliant star, of astonishing magnitude, encircled by dazzling rays, which, in a singular manner, were all inclined in one direction, and pointing to that part of the horizon where lay the rival of England¡ªFrance. The foreman's face assumed a deeper hue than usual: he looked fiercely at the galleyman, but there was a determination in the weather-beaten face that made him pause ere he spoke. "Galleyman," he at length said, "you knew the business before you came: if you be so fond of saving old witches' lives, why didn't you say so, that I might not now be in this dilemma?" "No, no, not the boy," replied Merritt, rather impatiently. HoMEÁíÀàС˵ߣɫ
ENTER NUMBET 0017
sumni.com.cn
www.bdjc.com.cn
ptal.com.cn
www.putongla.com.cn
www.yeqi6.net.cn
laosu9.net.cn
www.getbig.com.cn
www.qunya2.com.cn
jiata1.net.cn
taqiu8.net.cn