Least-squares line fitting: Difference between revisions
From JSXGraph Wiki
A WASSERMANN (talk | contribs) No edit summary  | 
				A WASSERMANN (talk | contribs) No edit summary  | 
				||
| Line 6: | Line 6: | ||
<jsxgraph width="600" height="600">  | <jsxgraph width="600" height="600">  | ||
var brd = JXG.JSXGraph.initBoard('jxgbox',{boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true});  | var brd = JXG.JSXGraph.initBoard('jxgbox',{boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true});  | ||
var i  | brd.suspendUpdate();  | ||
if (true) {  | |||
    var i, p = [], angle, xr, yr, delta = 0.1;  | |||
// Random points are constructed which lie roughly on a line  |     // Random points are constructed which lie roughly on a line  | ||
// defined by y = 0.3*x+1.  |     // defined by y = 0.3*x+1.  | ||
// delta*0.5 is the maximal distance in y-direction of the random  |     // delta*0.5 is the maximal distance in y-direction of the random  | ||
// points from the line.  |     // points from the line.  | ||
brd.suspendUpdate();  |     brd.suspendUpdate();  | ||
for (i=0;i<  |     for (i=0;i<100;i++) {  | ||
        yr = 10*(Math.random()-0.5);  | |||
        xr = 0.*yr+delta*(Math.random()-0.5);  | |||
        p.push(brd.create('point',[xr, yr], {withLabel:false}));  | |||
    }  | |||
} else {  | |||
    var i, p = [], angle, co, si, delta = 0.2;  | |||
    // Random points are constructed which lie roughly on a circle  | |||
    // of radius 4 having the origin as center.  | |||
    // delta*0.5 is the maximal distance in x- and y- direction of the random  | |||
    // points from the circle line.  | |||
    for (i=0;i<100;i++) {  | |||
        angle = Math.random()*2*Math.PI;  | |||
        co = 4*Math.cos(angle)+delta*(Math.random()-0.5);  | |||
        si = 4*Math.sin(angle)+delta*(Math.random()-0.5);  | |||
        p.push(brd.create('point',[co+2, si-1], {withLabel:false}));  | |||
    }  | |||
}  | }  | ||
brd.unsuspendUpdate();  | brd.unsuspendUpdate();  | ||
var r = [], rbar = [], x = [], y = [], z = [], A = [[0,0,0],[0,0,0],[0,0,0]], n, d;  | //  | ||
// Ab hier wird der beste Kreis, bzw. die beste Gerade ermittelt.  | |||
var j, r = [], rbar = [], x = [], y = [], z = [], A = [[0,0,0],[0,0,0],[0,0,0]], n, d,  | |||
    eigen, minIndex, minE, ev, c, xm, ym, zm, radius;  | |||
n = p.length;  | n = p.length;  | ||
for (i=0;i<n;i++) {  | for (i=0;i<n;i++) {  | ||
| Line 51: | Line 71: | ||
     A[2][2] += r[i][2]*r[i][2];  |      A[2][2] += r[i][2]*r[i][2];  | ||
}  | }  | ||
/*  | |||
for (i=0;i<3;i++) {  | for (i=0;i<3;i++) {  | ||
     for (j=0;j<3;j++) {  |      for (j=0;j<3;j++) {  | ||
| Line 56: | Line 77: | ||
     }  |      }  | ||
}  | }  | ||
*/  | */  | ||
eigen = JXG.Math.Numerics.Jacobi(A);  | |||
minIndex = 0;  | |||
minE = eigen[0][0][0];  | |||
for (j=1;j<3;j++) {  | |||
    if (eigen[0][j][j]<minE) {  | |||
        minIndex = j;  | |||
        minE = eigen[0][j][j];  | |||
    }  | |||
}  | |||
ev = [eigen[1][0][minIndex],eigen[1][1][minIndex],eigen[1][2][minIndex]];  | |||
c = -(rbar[0]*ev[0]+rbar[1]*ev[1]+rbar[2]*ev[2]);  | |||
xm = -ev[1];  | |||
ym = -ev[2];  | |||
zm = 2.0*(c+ev[0]);  | |||
console.log(c, c+ev[0]);  | |||
if (Math.abs(c)<0.01) {  | |||
    brd.create('line',[zm,xm,ym], {strokeColor:'green'});  | |||
}  else {  | |||
     var radius = Math.sqrt((xm*xm+ym*ym-2*c*zm)/(zm*zm));  | |||
     brd.create('circle',[[zm,xm,ym],radius]);  | |||
}  | }  | ||
</jsxgraph>  | </jsxgraph>  | ||
Revision as of 18:00, 9 November 2010
This little JXSGraph application finds the line - described by homogeneous coordinates [a,b,c] - that minimizes
- [math]\displaystyle{ \sum_{i=1}^n (ax_i+by_i+cz_i)^2. }[/math]
 
Coming soon...