diff --git a/src/main/java/info/istlab/Zemi01/NumericDemo.java b/src/main/java/info/istlab/Zemi01/NumericDemo.java index 6461861..9dd1a57 100644 --- a/src/main/java/info/istlab/Zemi01/NumericDemo.java +++ b/src/main/java/info/istlab/Zemi01/NumericDemo.java @@ -3,7 +3,7 @@ public class NumericDemo { public static void main(String[] args) { // ランチャーを起動する場合 - String[] opts = { "IEEE754view", "Lagrange", "RegLine", "NormalDistribution","WelchTtest" }; + String[] opts = { "IEEE754view", "Lagrange", "RegLine", "NormalDistribution","WelchTTestGUI", "UTestGUI" }; Launcher.show(opts, "info.istlab.Zemi01.numeric"); } } diff --git a/src/main/java/info/istlab/Zemi01/miuramath/Utest.java b/src/main/java/info/istlab/Zemi01/miuramath/Utest.java index 724ee3b..4407aec 100644 --- a/src/main/java/info/istlab/Zemi01/miuramath/Utest.java +++ b/src/main/java/info/istlab/Zemi01/miuramath/Utest.java @@ -198,6 +198,10 @@ return hensa / (ary.length); } + public static double stddevp(double[] ary){ + return Math.sqrt(varp(ary)); + } + /** * 差の配列 * diff --git a/src/main/java/info/istlab/Zemi01/numeric/UTestGUI.java b/src/main/java/info/istlab/Zemi01/numeric/UTestGUI.java new file mode 100644 index 0000000..c4a5026 --- /dev/null +++ b/src/main/java/info/istlab/Zemi01/numeric/UTestGUI.java @@ -0,0 +1,211 @@ +package info.istlab.Zemi01.numeric; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.Point2D; +import java.util.Random; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import info.istlab.Zemi01.Launcher; +import info.istlab.Zemi01.miuramath.Utest; + +/** + * UTest + */ +public class UTestGUI extends JPanel implements MouseListener, MouseMotionListener, KeyListener { + + private static final long serialVersionUID = -919448575666487391L; + public static JFrame jf; + + /** + * @param args + */ + public static void main(String[] args) { + jf = new JFrame("マン・ホイットニーのU検定"); + jf.getContentPane().add(new UTestGUI()); + jf.pack(); + jf.setVisible(true); + jf.setLocation(Launcher.centerOfScreen(jf.getSize())); + + jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + System.out.println("マン・ホイットニーのU検定 "); + System.out.println("つかいかた:Enterをおすと、アンケート回答がランダムに変化します。"); + System.out.println(""); + } + + Point2D offset; + + double[] d1, d2; + double[] utestary; + Dimension dim; + Font font20; + + public Dimension getPreferredSize() { + return dim; + } + + public UTestGUI() { + offset = new Point2D.Double(0, 100); + + dim = new Dimension(500, 400); + addMouseListener(this); + addMouseMotionListener(this); + addKeyListener(this); + this.setFocusable(true); + this.requestFocusInWindow(); + + font20 = new Font(Font.SANS_SERIF, Font.PLAIN, 20); + + setBackground(Color.white); + setForeground(Color.black); + + newdata(); + + } + + private double[] createRandomData(int mid, int range, int size) { + double[] ret = new double[size]; + Random rand = new Random(); + for (int i = 0; i < size; i++) { + ret[i] = rand.nextInt(range) + mid; + } + return ret; + } + + private void newdata() { + d1 = createRandomData(6, 5, 10); + d2 = createRandomData(5, 5, 10); + + utestary = Utest.utest(d1, d2); + } + + public void paint(Graphics g) { + paintComponent(g); + } + + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHints(rh); + g2d.setFont(font20); + + // g2d.setBackground(Color.white); + // g2d.setColor(Color.black); + g2d.clearRect(0, 0, getWidth(), getHeight()); + + // paintGrid(g2d); + for (int i = 0; i < d1.length; i++) { + g2d.drawString(String.format("%3.0f", d1[i]), 50, i * 23 + 40); + } + + for (int i = 0; i < d1.length; i++) { + g2d.drawString(String.format("%3.0f", d2[i]), 150, i * 23 + 40); + } + + int x1 = 200; + int y1 = 100; + g2d.drawString("参考:平均値", getWidth()-x1, y1-30); + g2d.drawString(String.format("%4.2f", Utest.avg(d1)), getWidth()-x1, y1); + g2d.drawString(String.format("%4.2f", Utest.avg(d2)), getWidth()-x1/2, y1); + + g2d.drawString("参考:標準偏差", getWidth()-x1, y1*2-30); + g2d.drawString(String.format("%4.2f", Utest.stddevp(d1)), getWidth()-x1, y1*2); + g2d.drawString(String.format("%4.2f", Utest.stddevp(d2)), getWidth()-x1/2, y1*2); + + g2d.setColor(Color.gray); + g2d.drawString("Enterキーでデータをランダムに生成", 90, getHeight()-2); + + double U = utestary[0]; + double p = utestary[1]; + if (p < 0.05) { + g2d.setColor(Color.cyan); + } else { + g2d.setColor(Color.YELLOW); + } + for (int i = -2; i < 3; i++) + for (int j = -2; j < 3; j++) { + // g2d.drawRect(10, 50, 100, 10); + g2d.drawString("U = " + String.format("%4.1f", U) + " , p = " + String.format("%5.3f", p), + (int) (getWidth() / 4 + i), + (int) (getHeight() -50 + j)); + } + if (p < 0.05) { + g2d.setColor(Color.blue); + } else { + g2d.setColor(Color.red); + } + g2d.drawString("U = " + String.format("%4.1f", U) + " , p = " + String.format("%5.3f", p), + (int) (getWidth() / 4 + 0), + (int) (getHeight() -50 + 0)); + } + + public Point2D scr2math(Point2D p) { + double x = p.getX(); + double y = p.getY(); + x = x - offset.getX() - getWidth() / 2; + y = y - offset.getY() - getHeight() / 2; + y = -y; + // System.out.println("scr2math "+x+", "+y); + return new Point2D.Double(x, y); + } + + public Point2D math2scr(Point2D p) { + return new Point2D.Double(p.getX(), -p.getY()); + } + + public void mouseClicked(MouseEvent e) { + } + + public void mouseEntered(MouseEvent e) { + } + + public void mouseExited(MouseEvent e) { + } + + public void mousePressed(MouseEvent e) { + } + + public void mouseReleased(MouseEvent e) { + repaint(); + } + + public void mouseDragged(MouseEvent e) { + } + + public void mouseMoved(MouseEvent e) { + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + // System.out.println(e.getKeyCode()); + newdata(); + repaint(); + } + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/info/istlab/Zemi01/numeric/WelchTTestGUI.java b/src/main/java/info/istlab/Zemi01/numeric/WelchTTestGUI.java new file mode 100644 index 0000000..1e92700 --- /dev/null +++ b/src/main/java/info/istlab/Zemi01/numeric/WelchTTestGUI.java @@ -0,0 +1,416 @@ +package info.istlab.Zemi01.numeric; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Random; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import info.istlab.Zemi01.Launcher; +import info.istlab.Zemi01.miuramath.Ttest; + +/** + * 正規分布、ガウス分布 + */ + +public class WelchTTestGUI extends JPanel implements MouseListener, MouseMotionListener, KeyListener { + + private static final long serialVersionUID = -919448575666487391L; + public static JFrame jf; + + /** + * @param args + */ + public static void main(String[] args) { + jf = new JFrame("正規分布、ガウス分布"); + jf.getContentPane().add(new WelchTTestGUI()); + jf.pack(); + jf.setVisible(true); + jf.setLocation(Launcher.centerOfScreen(jf.getSize())); + + jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + System.out.println("正規分布、ガウス分布 "); + System.out.println("つかいかた:(1)右クリックで、点を追加 (2)左ドラッグで、点移動 or グラフ移動 (3) 点の上で右クリックすると、点が消えます。"); + System.out.println("Enterをおすと、ランダムな点を生成します。"); + } + + Point2D offset; + + ND[] normdist = new ND[2]; + Dimension dim; + Point2D pointingPmath; + Point2D pressP; + static int psize = 10; + + public Dimension getPreferredSize() { + return dim; + } + + public WelchTTestGUI() { + offset = new Point2D.Double(0, 100); + + dim = new Dimension(500, 400); + addMouseListener(this); + addMouseMotionListener(this); + addKeyListener(this); + this.setFocusable(true); + this.requestFocusInWindow(); + + normdist[0] = new ND(Color.blue, 0, 0); + normdist[1] = new ND(Color.green, 20, -30); + + setBackground(Color.white); + setForeground(Color.black); + + updateNormDist(); + + } + + public void paint(Graphics g) { + paintComponent(g); + } + + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHints(rh); + + // g2d.setBackground(Color.white); + // g2d.setColor(Color.black); + g2d.clearRect(0, 0, getWidth(), getHeight()); + + paintGrid(g2d); + + if (pointingPmath != null) { + g2d.setColor(Color.red); + paintPoint(g2d, pointingPmath); + } + + for (ND nd : normdist) { + nd.paintND(g2d, this); + } + + if (p2 < 0.05) { + g2d.setColor(Color.cyan); + } else { + g2d.setColor(Color.YELLOW); + } + for (int i = -2; i < 3; i++) + for (int j = -2; j < 3; j++) { + // g2d.drawRect(10, 50, 100, 10); + g2d.drawString("t (" + String.format("%4.2f", df2) + ") = " + String.format("%5.3f", welch_t), + (int) (-getWidth() / 2 + 30 - offset.getX() + i), + (int) (-getHeight() / 2 + 320 - offset.getY()) + j); + g2d.drawString("p = " + String.format("%5.3f", p2), + (int) (-getWidth() / 2 + 30 - offset.getX() + i), + (int) (-getHeight() / 2 + 345 - offset.getY()) + j); + } + if (p2 < 0.05) { + g2d.setColor(Color.blue); + } else { + g2d.setColor(Color.red); + } + // g2d.drawRect(10, 50, 100, 10); + g2d.drawString("t (" + String.format("%4.2f", df2) + ") = " + String.format("%5.3f", welch_t), + (int) (-getWidth() / 2 + 30 - offset.getX()), + (int) (-getHeight() / 2 + 320 - offset.getY())); + g2d.drawString("p = " + String.format("%5.3f", p2), + (int) (-getWidth() / 2 + 30 - offset.getX()), + (int) (-getHeight() / 2 + 345 - offset.getY())); + } + + private void updateNormDist() { + for (ND nd : normdist) { + nd.updateNormDist(); + } + updateTdist(); + } + + double welch_t; + double df2; + double p2; + + private void updateTdist() { + welch_t = Ttest.welch_t(normdist[1].data(), normdist[0].data()); + df2 = Ttest.welch_degree_of_freedom(normdist[1].data(), normdist[0].data()); + p2 = Ttest.tdist(welch_t, df2, 2); + // System.out.println("p2 = "+p2); + } + + public void paintPoint(Graphics2D g2d, Point2D p) { + g2d.setColor(Color.red); + g2d.fillOval((int) (p.getX() - WelchTTestGUI.psize / 2), + (int) (-(p.getY() + WelchTTestGUI.psize / 2)), WelchTTestGUI.psize, WelchTTestGUI.psize); + // g2d.drawString(String.valueOf(num), (int)p.getX()+10, (int)p.getY()); + } + + public void paintGrid(Graphics2D g2d) { + g2d.setColor(new Color(230, 230, 230)); + + g2d.translate(getWidth() / 2 + offset.getX(), getHeight() / 2 + offset.getY()); + // System.out.println(g2d.getTransform().getTranslateX()+" + // "+g2d.getTransform().getTranslateY()); + + for (int i = 0; i < getWidth(); i += 20) { + g2d.drawLine(i, -getHeight(), i, getHeight()); + g2d.drawLine(-i, -getHeight(), -i, getHeight()); + } + for (int i = 0; i < getHeight(); i += 20) { + g2d.drawLine(-getWidth(), i, getWidth(), i); + g2d.drawLine(-getWidth(), -i, getWidth(), -i); + } + g2d.setColor(Color.black); + g2d.drawLine(0, getHeight() * 3, 0, -getHeight() * 3); + g2d.drawLine(-getWidth() * 3, 0, getWidth() * 3, 0); + + // g2d.translate(-(getWidth()/2+offset.getX()), -(getHeight()/2+offset.getY())); + } + + public Point2D scr2math(Point2D p) { + double x = p.getX(); + double y = p.getY(); + x = x - offset.getX() - getWidth() / 2; + y = y - offset.getY() - getHeight() / 2; + y = -y; + // System.out.println("scr2math "+x+", "+y); + return new Point2D.Double(x, y); + } + + public Point2D math2scr(Point2D p) { + return new Point2D.Double(p.getX(), -p.getY()); + } + + public void mouseClicked(MouseEvent e) { + if (e.getButton() == 3) { + Point2D pointing = findPointing(e.getPoint()); + if (pointing == null) + normdist[0].points.add(scr2math(e.getPoint())); + else { + if (normdist[0].points.size() > 2) + normdist[0].points.remove(pointing); + } + updateNormDist(); + repaint(); + } + } + + public void mouseEntered(MouseEvent e) { + } + + public void mouseExited(MouseEvent e) { + } + + public Point2D findPointing(Point2D mp) { + // Point2D nearest = null; + Point2D mPmath = scr2math(mp); + Point2D nP = null; + for (ND n : normdist) { + nP = n.nearestPoint(mPmath); + if (nP != null) + break; + } + return nP; + // pointingPmath = nP; + + // for (Point2D p : points) { + // if (mPmath.distance(p) < 8) { + // nearest = p; + // } + // } + // return nearest; + } + + public void mousePressed(MouseEvent e) { + mouseMoved(e); + } + + public void mouseReleased(MouseEvent e) { + pointingPmath = null; + repaint(); + } + + public void mouseDragged(MouseEvent e) { + if (pointingPmath != null) { + pointingPmath.setLocation(scr2math(e.getPoint())); + updateNormDist(); + repaint(); + } else { + // e.translatePoint((int)offset.getX(), (int)offset.getY()); + offset.setLocation(offset.getX() + (e.getPoint().getX() - pressP.getX()), + offset.getY() + (e.getPoint().getY() - pressP.getY())); + pressP = e.getPoint(); + updateNormDist(); + repaint(); + } + } + + public void mouseMoved(MouseEvent e) { + scr2math(e.getPoint()); + pressP = e.getPoint(); + Point2D pressPmath = scr2math(pressP); + Point2D nP = null; + for (ND n : normdist) { + nP = n.nearestPoint(pressPmath); + if (nP != null) + break; + } + pointingPmath = nP; + updateNormDist(); + repaint(); + } + + @Override + public void keyTyped(KeyEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + // System.out.println(e.getKeyCode()); + + normdist[0] = new ND(Color.blue, 0, 0); + normdist[1] = new ND(Color.green, 20, -30); + updateNormDist(); + repaint(); + } + + } + + @Override + public void keyReleased(KeyEvent e) { + // TODO Auto-generated method stub + + } + +} + +class ND { + ArrayList points; + Color color; + int offsetx = 0; + int offsety = 0; + + public ND(Color c, int _offsetx, int _offsety) { + color = c; + offsetx = _offsetx; + offsety = _offsety; + points = new ArrayList(); + + Random rand = new Random(); + for (int i = 0; i < 7; i++) { + int randx = rand.nextInt(-40 + offsetx, 40 + offsetx); + int randy = rand.nextInt(-10 + offsety, offsety); + points.add(new Point2D.Double(randx, randy)); + } + updateNormDist(); + } + + double[] ddat; + + public double[] data() { + return ddat; + } + + // 平均と分散 + double xavg = 0; + double xvarp = 1; + + /** + * ガウス関数、ただし、μとσ^2は、xavg, xvarp から計算する + * + * @param x + * @return + */ + public double gauss_function(double x) { + double d1 = 1.0 / Math.sqrt(2 * Math.PI * xvarp); + double d2 = Math.exp(-Math.pow(x - xavg, 2) / (2 * xvarp)); + double ret = d1 * d2 * 10000; + // System.out.println(ret); + return ret; + } + + /** + * 点のx座標から、ガウス関数のパラメータ μとσ^2は、xavg, xvarp を更新する + */ + public void updateNormDist() { + ddat = new double[points.size()]; + int i = 0; + for (Point2D p : points) { + ddat[i] = p.getX(); + i++; + } + // 平均値を更新する + xavg = Ttest.avg(ddat); + // 標準偏差を更新する + xvarp = Ttest.varp(ddat); + // System.out.println("μ " + xavg + " σ^2 " + xvarp); + } + + public void paintND(Graphics2D g2d, WelchTTestGUI wtest) { + + g2d.setColor(Color.black); + for (Point2D p : points) { + paintPoint(g2d, p); + } + + Point2D prep = null; + g2d.setColor(color); + for (double x = -wtest.getWidth() / 2 - wtest.offset.getX(); x < wtest.getWidth() / 2 + - wtest.offset.getX(); x += 1.0) { + Point2D p1 = wtest.math2scr(new Point2D.Double(x, gauss_function(x))); + if (prep == null) + prep = p1; + g2d.drawLine((int) p1.getX(), (int) p1.getY(), (int) prep.getX(), (int) prep.getY()); + prep = p1; + } + if (offsetx > 10) { + g2d.drawString("μ = " + String.format("%6.4f", xavg), (int) (wtest.getWidth() / 5 - wtest.offset.getX()), + (int) (-wtest.getHeight() / 2 + 20 - wtest.offset.getY())); + g2d.drawString("σ = " + String.format("%6.4f", Math.sqrt(xvarp)), + (int) (wtest.getWidth() / 5 - wtest.offset.getX()), + (int) (-wtest.getHeight() / 2 + 38 - wtest.offset.getY())); + g2d.drawString("σ^2 = " + String.format("%6.4f", xvarp), (int) (wtest.getWidth() / 5 - wtest.offset.getX()), + (int) (-wtest.getHeight() / 2 + 56 - wtest.offset.getY())); + + } else { + g2d.drawString("μ = " + String.format("%6.4f", xavg), (int) (-wtest.getWidth() / 2 + 10 - wtest.offset.getX()), + (int) (-wtest.getHeight() / 2 + 20 - wtest.offset.getY())); + g2d.drawString("σ = " + String.format("%6.4f", Math.sqrt(xvarp)), + (int) (-wtest.getWidth() / 2 + 10 - wtest.offset.getX()), + (int) (-wtest.getHeight() / 2 + 38 - wtest.offset.getY())); + g2d.drawString("σ^2 = " + String.format("%6.4f", xvarp), (int) (-wtest.getWidth() / 2 + 10 - wtest.offset.getX()), + (int) (-wtest.getHeight() / 2 + 56 - wtest.offset.getY())); + } + + } + + public void paintPoint(Graphics2D g2d, Point2D p) { + g2d.fillOval((int) (p.getX() - WelchTTestGUI.psize / 2), + (int) (-(p.getY() + WelchTTestGUI.psize / 2)), WelchTTestGUI.psize, WelchTTestGUI.psize); + // g2d.drawString(String.valueOf(num), (int)p.getX()+10, (int)p.getY()); + } + + public Point2D nearestPoint(Point2D pressPmath) { + Point2D nearest = null; + for (Point2D p : points) { + if (pressPmath.distance(p) < 8) { + nearest = p; + } + } + return nearest; + } + +} diff --git a/src/main/java/info/istlab/Zemi01/numeric/WelchTtest.java b/src/main/java/info/istlab/Zemi01/numeric/WelchTtest.java deleted file mode 100644 index 4bb3e2c..0000000 --- a/src/main/java/info/istlab/Zemi01/numeric/WelchTtest.java +++ /dev/null @@ -1,416 +0,0 @@ -package info.istlab.Zemi01.numeric; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.geom.Point2D; -import java.util.ArrayList; -import java.util.Random; - -import javax.swing.JFrame; -import javax.swing.JPanel; - -import info.istlab.Zemi01.Launcher; -import info.istlab.Zemi01.miuramath.Ttest; - -/** - * 正規分布、ガウス分布 - */ - -public class WelchTtest extends JPanel implements MouseListener, MouseMotionListener, KeyListener { - - private static final long serialVersionUID = -919448575666487391L; - public static JFrame jf; - - /** - * @param args - */ - public static void main(String[] args) { - jf = new JFrame("正規分布、ガウス分布"); - jf.getContentPane().add(new WelchTtest()); - jf.pack(); - jf.setVisible(true); - jf.setLocation(Launcher.centerOfScreen(jf.getSize())); - - jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - System.out.println("正規分布、ガウス分布 "); - System.out.println("つかいかた:(1)右クリックで、点を追加 (2)左ドラッグで、点移動 or グラフ移動 (3) 点の上で右クリックすると、点が消えます。"); - System.out.println("Enterをおすと、ランダムな点を生成します。"); - } - - Point2D offset; - - ND[] normdist = new ND[2]; - Dimension dim; - Point2D pointingPmath; - Point2D pressP; - static int psize = 10; - - public Dimension getPreferredSize() { - return dim; - } - - public WelchTtest() { - offset = new Point2D.Double(0, 100); - - dim = new Dimension(500, 400); - addMouseListener(this); - addMouseMotionListener(this); - addKeyListener(this); - this.setFocusable(true); - this.requestFocusInWindow(); - - normdist[0] = new ND(Color.blue, 0, 0); - normdist[1] = new ND(Color.green, 20, -30); - - setBackground(Color.white); - setForeground(Color.black); - - updateNormDist(); - - } - - public void paint(Graphics g) { - paintComponent(g); - } - - public void paintComponent(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setRenderingHints(rh); - - // g2d.setBackground(Color.white); - // g2d.setColor(Color.black); - g2d.clearRect(0, 0, getWidth(), getHeight()); - - paintGrid(g2d); - - if (pointingPmath != null) { - g2d.setColor(Color.red); - paintPoint(g2d, pointingPmath); - } - - for (ND nd : normdist) { - nd.paintND(g2d, this); - } - - if (p2 < 0.05) { - g2d.setColor(Color.cyan); - } else { - g2d.setColor(Color.YELLOW); - } - for (int i = -2; i < 3; i++) - for (int j = -2; j < 3; j++) { - // g2d.drawRect(10, 50, 100, 10); - g2d.drawString("t (" + String.format("%4.2f", df2) + ") = " + String.format("%5.3f", welch_t), - (int) (-getWidth() / 2 + 30 - offset.getX() + i), - (int) (-getHeight() / 2 + 320 - offset.getY()) + j); - g2d.drawString("p = " + String.format("%5.3f", p2), - (int) (-getWidth() / 2 + 30 - offset.getX() + i), - (int) (-getHeight() / 2 + 345 - offset.getY()) + j); - } - if (p2 < 0.05) { - g2d.setColor(Color.blue); - } else { - g2d.setColor(Color.red); - } - // g2d.drawRect(10, 50, 100, 10); - g2d.drawString("t (" + String.format("%4.2f", df2) + ") = " + String.format("%5.3f", welch_t), - (int) (-getWidth() / 2 + 30 - offset.getX()), - (int) (-getHeight() / 2 + 320 - offset.getY())); - g2d.drawString("p = " + String.format("%5.3f", p2), - (int) (-getWidth() / 2 + 30 - offset.getX()), - (int) (-getHeight() / 2 + 345 - offset.getY())); - } - - private void updateNormDist() { - for (ND nd : normdist) { - nd.updateNormDist(); - } - updateTdist(); - } - - double welch_t; - double df2; - double p2; - - private void updateTdist() { - welch_t = Ttest.welch_t(normdist[1].data(), normdist[0].data()); - df2 = Ttest.welch_degree_of_freedom(normdist[1].data(), normdist[0].data()); - p2 = Ttest.tdist(welch_t, df2, 2); - // System.out.println("p2 = "+p2); - } - - public void paintPoint(Graphics2D g2d, Point2D p) { - g2d.setColor(Color.red); - g2d.fillOval((int) (p.getX() - WelchTtest.psize / 2), - (int) (-(p.getY() + WelchTtest.psize / 2)), WelchTtest.psize, WelchTtest.psize); - // g2d.drawString(String.valueOf(num), (int)p.getX()+10, (int)p.getY()); - } - - public void paintGrid(Graphics2D g2d) { - g2d.setColor(new Color(230, 230, 230)); - - g2d.translate(getWidth() / 2 + offset.getX(), getHeight() / 2 + offset.getY()); - // System.out.println(g2d.getTransform().getTranslateX()+" - // "+g2d.getTransform().getTranslateY()); - - for (int i = 0; i < getWidth(); i += 20) { - g2d.drawLine(i, -getHeight(), i, getHeight()); - g2d.drawLine(-i, -getHeight(), -i, getHeight()); - } - for (int i = 0; i < getHeight(); i += 20) { - g2d.drawLine(-getWidth(), i, getWidth(), i); - g2d.drawLine(-getWidth(), -i, getWidth(), -i); - } - g2d.setColor(Color.black); - g2d.drawLine(0, getHeight() * 3, 0, -getHeight() * 3); - g2d.drawLine(-getWidth() * 3, 0, getWidth() * 3, 0); - - // g2d.translate(-(getWidth()/2+offset.getX()), -(getHeight()/2+offset.getY())); - } - - public Point2D scr2math(Point2D p) { - double x = p.getX(); - double y = p.getY(); - x = x - offset.getX() - getWidth() / 2; - y = y - offset.getY() - getHeight() / 2; - y = -y; - // System.out.println("scr2math "+x+", "+y); - return new Point2D.Double(x, y); - } - - public Point2D math2scr(Point2D p) { - return new Point2D.Double(p.getX(), -p.getY()); - } - - public void mouseClicked(MouseEvent e) { - if (e.getButton() == 3) { - Point2D pointing = findPointing(e.getPoint()); - if (pointing == null) - normdist[0].points.add(scr2math(e.getPoint())); - else { - if (normdist[0].points.size() > 2) - normdist[0].points.remove(pointing); - } - updateNormDist(); - repaint(); - } - } - - public void mouseEntered(MouseEvent e) { - } - - public void mouseExited(MouseEvent e) { - } - - public Point2D findPointing(Point2D mp) { - // Point2D nearest = null; - Point2D mPmath = scr2math(mp); - Point2D nP = null; - for (ND n : normdist) { - nP = n.nearestPoint(mPmath); - if (nP != null) - break; - } - return nP; - // pointingPmath = nP; - - // for (Point2D p : points) { - // if (mPmath.distance(p) < 8) { - // nearest = p; - // } - // } - // return nearest; - } - - public void mousePressed(MouseEvent e) { - mouseMoved(e); - } - - public void mouseReleased(MouseEvent e) { - pointingPmath = null; - repaint(); - } - - public void mouseDragged(MouseEvent e) { - if (pointingPmath != null) { - pointingPmath.setLocation(scr2math(e.getPoint())); - updateNormDist(); - repaint(); - } else { - // e.translatePoint((int)offset.getX(), (int)offset.getY()); - offset.setLocation(offset.getX() + (e.getPoint().getX() - pressP.getX()), - offset.getY() + (e.getPoint().getY() - pressP.getY())); - pressP = e.getPoint(); - updateNormDist(); - repaint(); - } - } - - public void mouseMoved(MouseEvent e) { - scr2math(e.getPoint()); - pressP = e.getPoint(); - Point2D pressPmath = scr2math(pressP); - Point2D nP = null; - for (ND n : normdist) { - nP = n.nearestPoint(pressPmath); - if (nP != null) - break; - } - pointingPmath = nP; - updateNormDist(); - repaint(); - } - - @Override - public void keyTyped(KeyEvent e) { - // TODO Auto-generated method stub - - } - - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - // System.out.println(e.getKeyCode()); - - normdist[0] = new ND(Color.blue, 0, 0); - normdist[1] = new ND(Color.green, 20, -30); - updateNormDist(); - repaint(); - } - - } - - @Override - public void keyReleased(KeyEvent e) { - // TODO Auto-generated method stub - - } - -} - -class ND { - ArrayList points; - Color color; - int offsetx = 0; - int offsety = 0; - - public ND(Color c, int _offsetx, int _offsety) { - color = c; - offsetx = _offsetx; - offsety = _offsety; - points = new ArrayList(); - - Random rand = new Random(); - for (int i = 0; i < 7; i++) { - int randx = rand.nextInt(-40 + offsetx, 40 + offsetx); - int randy = rand.nextInt(-10 + offsety, offsety); - points.add(new Point2D.Double(randx, randy)); - } - updateNormDist(); - } - - double[] ddat; - - public double[] data() { - return ddat; - } - - // 平均と分散 - double xavg = 0; - double xvarp = 1; - - /** - * ガウス関数、ただし、μとσ^2は、xavg, xvarp から計算する - * - * @param x - * @return - */ - public double gauss_function(double x) { - double d1 = 1.0 / Math.sqrt(2 * Math.PI * xvarp); - double d2 = Math.exp(-Math.pow(x - xavg, 2) / (2 * xvarp)); - double ret = d1 * d2 * 10000; - // System.out.println(ret); - return ret; - } - - /** - * 点のx座標から、ガウス関数のパラメータ μとσ^2は、xavg, xvarp を更新する - */ - public void updateNormDist() { - ddat = new double[points.size()]; - int i = 0; - for (Point2D p : points) { - ddat[i] = p.getX(); - i++; - } - // 平均値を更新する - xavg = Ttest.avg(ddat); - // 標準偏差を更新する - xvarp = Ttest.varp(ddat); - // System.out.println("μ " + xavg + " σ^2 " + xvarp); - } - - public void paintND(Graphics2D g2d, WelchTtest wtest) { - - g2d.setColor(Color.black); - for (Point2D p : points) { - paintPoint(g2d, p); - } - - Point2D prep = null; - g2d.setColor(color); - for (double x = -wtest.getWidth() / 2 - wtest.offset.getX(); x < wtest.getWidth() / 2 - - wtest.offset.getX(); x += 1.0) { - Point2D p1 = wtest.math2scr(new Point2D.Double(x, gauss_function(x))); - if (prep == null) - prep = p1; - g2d.drawLine((int) p1.getX(), (int) p1.getY(), (int) prep.getX(), (int) prep.getY()); - prep = p1; - } - if (offsetx > 10) { - g2d.drawString("μ = " + String.format("%6.4f", xavg), (int) (wtest.getWidth() / 5 - wtest.offset.getX()), - (int) (-wtest.getHeight() / 2 + 20 - wtest.offset.getY())); - g2d.drawString("σ = " + String.format("%6.4f", Math.sqrt(xvarp)), - (int) (wtest.getWidth() / 5 - wtest.offset.getX()), - (int) (-wtest.getHeight() / 2 + 38 - wtest.offset.getY())); - g2d.drawString("σ^2 = " + String.format("%6.4f", xvarp), (int) (wtest.getWidth() / 5 - wtest.offset.getX()), - (int) (-wtest.getHeight() / 2 + 56 - wtest.offset.getY())); - - } else { - g2d.drawString("μ = " + String.format("%6.4f", xavg), (int) (-wtest.getWidth() / 2 + 10 - wtest.offset.getX()), - (int) (-wtest.getHeight() / 2 + 20 - wtest.offset.getY())); - g2d.drawString("σ = " + String.format("%6.4f", Math.sqrt(xvarp)), - (int) (-wtest.getWidth() / 2 + 10 - wtest.offset.getX()), - (int) (-wtest.getHeight() / 2 + 38 - wtest.offset.getY())); - g2d.drawString("σ^2 = " + String.format("%6.4f", xvarp), (int) (-wtest.getWidth() / 2 + 10 - wtest.offset.getX()), - (int) (-wtest.getHeight() / 2 + 56 - wtest.offset.getY())); - } - - } - - public void paintPoint(Graphics2D g2d, Point2D p) { - g2d.fillOval((int) (p.getX() - WelchTtest.psize / 2), - (int) (-(p.getY() + WelchTtest.psize / 2)), WelchTtest.psize, WelchTtest.psize); - // g2d.drawString(String.valueOf(num), (int)p.getX()+10, (int)p.getY()); - } - - public Point2D nearestPoint(Point2D pressPmath) { - Point2D nearest = null; - for (Point2D p : points) { - if (pressPmath.distance(p) < 8) { - nearest = p; - } - } - return nearest; - } - -}