/* TestFMM.java * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README * file for more details. * */ /* * Written by Kimmo Wideroos */ package org.gzigzag.test; import org.gzigzag.map.*; import java.util.*; import junit.framework.*; import java.awt.*; import java.awt.event.*; /** Test FMM. */ public class TestFMM extends TestCase { public TestFMM(String s) { super(s); } float xmin = (float)0.0; float xmax = (float)1.0; float ymin = (float)0.0; float ymax = (float)1.0; public boolean isvalid(int[][] il, int x, int y) { int dx, dy; for(int i=0; i<27; i++) { dx = il[i][0] - x; dy = il[i][1] - y; if(dx*dx+dy*dy < 4 || dx*dx+dy*dy > 18) { System.out.println("dx:"+dx+" dy:"+dy); return false; } } System.out.println("\nx:"+x+" y:"+y+" xo:"+il[0][0]+" yo:"+il[0][1]); for(int j=0; j<27; j++) { System.out.print("X"); if(j==26) continue; if(il[j][1] < il[j+1][1]) System.out.println(""); if(il[j+1][0]-il[j][0] > 2) System.out.print("---"); } return true; } public void checkParticle(FMMParticle fp, float ccx, float ccy, int level) { float fcx = (xmax-xmin) / (1<=0; i-- ) { if((c & b) != 0) sb.setCharAt(i, '1'); else sb.setCharAt(i, '0'); b <<= 1; } return sb.toString(); } public void complex() { Complex t = new Complex((float)-0.1, (float)10.0); Complex t2 = new Complex(t); t.mul(new Complex((float)0.3, (float)-5.0)); t.div(new Complex((float)0.3, (float)-5.0)); assertTrue("Complex mul/div-bug!", t.near(t2, (float)0.001)); } public void keys() { int N = 10; FMMHashTree fms = new FMMHashTree((float)-2.0, (float)6.0, (float)-0.3, (float)12.0, N, (float)0.001); System.out.println("N="+N+" levels in hierarchy="+fms.nLevel()); System.out.println("Keytests:"); String keyStr; int keyA, keyB, keyC, keyD, xkey, ykey; keyA = fms.makeKeyPart((float)1.0, new float[] {(float)-2.0, (float)6.0}); keyStr = binStr(keyA); System.out.println("makeKeyPart((float)1.0, (float)-2.0, (float)6.0) = "+keyStr); keyB = fms.makeKeyPart((float)11.0, new float[] {(float)-0.3, (float)12.0}); keyStr = binStr(keyB); System.out.println("makeKeyPart((float)11.0, (float)-0.3, (float)12.0) = "+keyStr); float[] midp = new float[2]; keyC = fms.makeKey((float)1.0, (float)11.0, midp); keyStr = binStr(keyC); System.out.println("makeKey((float)-2.0, (float)6.0) = "+keyStr); System.out.println("midp["+midp[0]+","+midp[1]+"]"); assertTrue("buildKey", (keyC == (fms.buildKey(keyA, keyB, fms.nLevel()))) ); int[] keystuff = fms.breakKey(keyC); xkey = keystuff[0]; ykey = keystuff[1]; System.out.println("level(breakKey gen): "+keystuff[2]); System.out.println("xkey(true): "+binStr(keyA)); System.out.println("xkey(breakKey gen): "+binStr(xkey)); System.out.println("ykey(true): "+binStr(keyB)); System.out.println("ykey(breakKey gen): "+binStr(ykey)); assertTrue("breakKey", (xkey == keyA) && (ykey == keyB)); keyD = fms.transformKey(keyC, fms.nLevel(), fms.nLevel()-1); System.out.println("key(level="+fms.nLevel()+"): "+binStr(keyC)); System.out.println("key(level="+(fms.nLevel()-1)+"): "+binStr(keyD)); keyD = fms.transformKey(keyC, fms.nLevel(), fms.nLevel()+1); keyD = fms.transformKey(keyD, fms.nLevel()+1, fms.nLevel()); assertTrue("transformKey", keyC == keyD); } public void dumpChildren(FMM.FMMStructure fms, FMMCell fc) { FMMCell[] fccs = fms.getChildren(fc); for(int i=0; i-10) q[j] = 0; if(q[j]<-10) q[j] = -50; } fmsadd(fmss, x, y, q); } } return fmss; } public void structure_validity() { FMM.FMMStructure fmss[] = new FMMHashTree[1]; fmss[0] = new FMMHashTree(xmin, xmax, ymin, ymax, 150, (float)0.01); storeParticles(fmss, 150, 0); FMM.FMMStructure fms = fmss[0]; int level = fms.nLevel(); for(int i=0; i<=level; i++) { FMMCell[] fcs = fms.get(i); for(int j=0; j> fms2("+p2+")!", p1.near(p2, precision*(float)2.0)); } } } class TestView extends Panel { FMM.FMMStructure[] fmss; TestView(FMM.FMMStructure[] fmss) { super(); this.fmss = fmss; addComponentListener(new ComponentAdapter() { public void componentShown(ComponentEvent e) { repaint(); } }); } private Color makeColor(Color b, int i) { float cof = (float)Math.pow(0.9, i); return new Color( (int)(cof*b.getRed()), (int)(cof*b.getGreen()), (int)(cof*b.getBlue()) ); } private float radius(int q) { return (float)(0.01*Math.sqrt(q/Math.PI)); } public void paintNDParticle(Graphics gr, FMMParticle fp) { int rx, r, x, y, dx, dy; Dimension vd = getSize(); r = (int)((radius(fp.q[0])/(ymax-ymin))*vd.height); x = (int)((fp.x/(xmax-xmin))*vd.width) - (r>>1); y = (int)((fp.y/(ymax-ymin))*vd.height) - (r>>1); for(int i=1; i0) gr.setColor(makeColor(Color.red, i<<1)); else gr.setColor(makeColor(Color.blue, i<<1)); gr.fillRect(x, y, rx, r); x += rx; } } public void paintParticle(Graphics gr, FMMParticle fp) { int rx, ry, x, y, dx, dy; if(fp.q.length>2) { paintNDParticle(gr, fp); return; } Dimension vd = getSize(); rx = (int)((radius(fp.q[0])/(xmax-xmin))*vd.width); ry = (int)((radius(fp.q[0])/(ymax-ymin))*vd.height); x = (int)((fp.x/(xmax-xmin))*vd.width); y = (int)((fp.y/(ymax-ymin))*vd.height); if(fp.q[1]>0) gr.setColor(Color.red); else gr.setColor(Color.blue); gr.fillOval(x-(rx>>1), y-(ry>>1), rx, ry); Complex s = new Complex(); s.set(fp.far); s.div(fp.q[0]); dx = (int)((s.r()/(xmax-xmin))*vd.width/100.0); dy = (int)((s.i()/(ymax-ymin))*vd.height/100.0); gr.setColor(Color.cyan); gr.drawLine(x, y, x+dx, y+dy); s.set(fp.near); s.div(fp.q[0]); dx = (int)((s.r()/(xmax-xmin))*vd.width/100.0); dy = (int)((s.i()/(ymax-ymin))*vd.height/100.0); gr.setColor(Color.magenta); gr.drawLine(x, y, x+dx, y+dy); s.set(fp.F); s.div(fp.q[0]); dx = (int)((s.r()/(xmax-xmin))*vd.width/100.0); dy = (int)((s.i()/(ymax-ymin))*vd.height/100.0); gr.setColor(Color.black); gr.drawLine(x, y, x+dx, y+dy); /* if(fms_ref == null) return; // error s.set(fp.F); FMMParticle fp2 = fms_ref.getParticle(fp.x, fp.y); s.sub(fp2.F); s.div(fp.q[0]); dx = (int)((s.r()/(xmax-xmin))*vd.width/100.0); dy = (int)((s.i()/(ymax-ymin))*vd.height/100.0); gr.setColor(Color.cyan); gr.drawLine(x, y, x+dx, y+dy); */ } public void paint(Graphics gr) { for(int i=1; i=xmax) { fp.x = (float)xmax-(xmax-xmin)*(float)0.01; fp.V.neg(); fp.V.mul(borderElasticity); } if(fp.y<=ymin) { fp.y = (float)ymin+(ymax-ymin)*(float)0.01; fp.V.neg(); fp.V.mul(borderElasticity); } if(fp.y>=ymax) { fp.y = (float)ymax-(ymax-ymin)*(float)0.01; fp.V.neg(); fp.V.mul(borderElasticity); } } private int i=0; public void paint(Graphics gr) { if(i==0) { updateField(); i=10;} i--; FMM.FMMStructure fms = fmss[0]; FMMParticle[] fps = fms.getAllParticles(); fms.empty(); for(int j=0; j ymax-ymin) { viewdim = new Dimension(400, (int)(400.0*(ymax-ymin)/(xmax-xmin))); } else { viewdim = new Dimension((int)(400.0*(xmax-xmin)/(ymax-ymin)), 400);; } f.setSize(viewdim); f.add(fv); while(true) { fv.repaint(); f.setVisible(true); } } public void animation(int which) { Dimension viewdim; FMMHashTree[] fmss = new FMMHashTree[1]; fmss[0] = new FMMHashTree(xmin, xmax, ymin, ymax, 16, (float)0.0001); storeParticles(fmss, 10, which); do_algorithm(fmss[0]); TestAnimation fv = new TestAnimation(fmss); Frame f = new Frame("animationtest"); if(xmax-xmin > ymax-ymin) { viewdim = new Dimension(400, (int)(400.0*(ymax-ymin)/(xmax-xmin))); } else { viewdim = new Dimension((int)(400.0*(xmax-xmin)/(ymax-ymin)), 400);; } f.setSize(viewdim); f.add(fv); fv.repaint(); f.setVisible(true); System.out.println("\n\nInput vectors as color vecs. Blue means repulsion force, red attraction power!"); while(true) { fv.repaint(); f.setVisible(true); } } public void isNan(FMM.FMMStructure fms, int l) { FMMCell[] fcs = fms.get(fms.nLevel()); int ibox; for(ibox=0; ibox>3, err); fmss[1] = new FMMHashTree(xmin, xmax, ymin, ymax, 1, err); storeParticles(fmss, card, 0); do_algorithm(fmss[1]); long cur_time = System.currentTimeMillis(); System.out.println("proceed..."); do_algorithm(fmss[0]); long elapsed = System.currentTimeMillis()-cur_time; System.out.println("elapsed(N="+card+",err="+err+"):"+elapsed+" ms"); //algorithm(fms2); compare(fmss[0], fmss[1], err); return elapsed; } public void algorithm_benchmark() { float err = (float)0.001; algorithm(30, err); algorithm(100, err); //algorithm(1000, err); } public void algorithm_details() { //translation (Lemma 2.5) int p=5; FMMCell[] fccs = new FMMCell[] { new FMMCell(0, -1, -1, 0, p), new FMMCell(0, 1, 1, 0, p), new FMMCell(0, 1, -1, 0, p), new FMMCell(0, -1, 1, 0, p) }; FMMCell fc = new FMMCell(0, 0, 0, 0, p); for(int i=0; is2", s1.near(s2, (float)0.001)); } } public void testAll() { //complex(); //keys(); //tree(); //structure_validity(); //algorithm_details(); //algorithm_benchmark(); //visualization(); //animation(4); //animation(5); } }