import java.awt.*; import java.awt.image.*; /* We need only four types of fits -- y = a + bx, y = a + b ln x, y = a e^(bx), and y = a x^b. In the last three cases, we can use linear regression by first "linearizing the data". E.g., in the case of y = a + b ln x you would do a linear fit to the (ln x, y) data, in the case of y = a e^(bx) you would do a linear fit to the (x, ln y) data, and in the case of y = y = a x^b you would do a linear fit to the (ln x, ln y) data. The coefficients for the desired fits would then be derived from the coefficients for the fits to the linearized data by appropriate transformations. */ public class fit { plot p; int id; int h[], v[]; double ymin, ymax; double x[], y[]; double a, b; double r; boolean active = true; public fit(plot p, int id) { this.p = p; this.id = id; recalc(); } public void draw(Graphics g, int h, int v) { // draw curve switch (id) { case 0: g.setColor(Color.red); break; case 1: g.setColor(Color.green); break; case 2: g.setColor(Color.blue); break; case 3: g.setColor(Color.magenta); break; } if (active) for (int i = 0; i < this.h.length - 1; i ++) //g.drawLine(this.h[i], this.v[i], this.h[i + 1], this.v[i + 1]); drawThickLine(g, this.h[i], this.v[i], this.h[i + 1], this.v[i + 1]); // draw stats v += 15; g.drawString(eqn(), h, v); g.setColor(Color.black); v += 15; if (active) g.drawString("a = " + p.format_num(a, 6), h, v); else g.drawString("a = ---", h, v); v += 15; if (active) g.drawString("b = " + p.format_num(b, 6), h, v); else g.drawString("b = ---", h, v); v += 15; if (active) g.drawString("r = " + p.format_num(r, 6), h, v); else g.drawString("r = ---", h, v); v += 15; } void recalc() { do_fit(); if (!active) return; int pts = 250; x = new double[pts]; y = new double[pts]; double dx = (p.xmax - p.xmin) / (pts - 1); x[0] = p.xmin; x[pts - 1] = p.xmax; for (int i = 1; i < pts - 1; i ++) x[i] = p.xmin + i * dx; for (int i = 0; i < pts; i ++) y[i] = eval(x[i]); ymin = y[0]; ymax = y[0]; for (int i = 0; i < pts; i ++) if (y[i] > ymax) ymax = y[i]; else if (y[i] < ymin) ymin = y[i]; if (ymin == ymax) { ymin -= 1; ymax += 1; } h = new int[pts]; double dxdh = (p.r.width - 1) / (p.xmax - p.xmin); for (int i = 0; i < pts; i ++) h[i] = (int) (p.r.x + (x[i] - p.xmin) * dxdh); } void do_fit() { } public double eval(double x) { return x + id; } public void adjust_scale() { if (!active) return; if (ymax > p.ymax) p.ymax = ymax; if (ymin < p.ymin) p.ymin = ymin; } public void calc_v() { if (!active) return; v = new int[h.length]; double dydv = (p.r.height - 1) / (p.ymax - p.ymin); for (int i = 0; i < h.length; i ++) v[i] = (int) (p.r.y + p.r.height - 1 - (y[i] - p.ymin) * dydv); } public String eqn() { return new String("y = x + id"); } void drawThickLine(Graphics g, int x0, int y0, int x1, int y1) { g.drawLine(x0, y0, x1, y1); g.drawLine(x0 + 1, y0, x1 + 1, y1); g.drawLine(x0, y0 + 1, x1, y1 + 1); g.drawLine(x0 + 1, y0 + 1, x1 + 1, y1 + 1); } }