-
Notifications
You must be signed in to change notification settings - Fork 1
/
lagrange.js
77 lines (74 loc) · 1.77 KB
/
lagrange.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Lagrange = {};
/**
* At least two points are needed to interpolate something.
* @class Lagrange polynomial interpolation.
* The computed interpolation polynomial will be reffered to as L(x).
* @example
* var l = new Lagrange(0, 0, 1, 1);
* var index = l.addPoint(0.5, 0.8);
* console.log(l.valueOf(0.1));
*
* l.changePoint(index, 0.5, 0.1);
* console.log(l.valueOf(0.1));
*
* @see https://gist.github.com/dburner/8550030
* @see http://jsfiddle.net/maccesch/jgU3Y/
*/
var Lagrange = function(x1, y1, x2, y2) {
this.xs = [x1, x2];
this.ys = [y1, y2];
this.ws = [];
this._updateWeights();
}
/**
* Adds a new point to the polynomial. L(x) = y
* @return {Number} The index of the added point. Used for changing the point. See changePoint.
*/
Lagrange.prototype.addPoint = function(x, y) {
this.xs.push(x);
this.ys.push(y);
this._updateWeights();
return this.xs.length-1;
}
/**
* Recalculate barycentric weights.
*/
Lagrange.prototype._updateWeights = function() {
var len = this.xs.length; // the number of points
var weight;
for (var j = 0; j < len; ++j) {
weight = 1;
for (var i = 0; i < len; ++i) {
if (i != j) {
weight *= this.xs[j] - this.xs[i];
}
}
this.ws[j] = 1/weight;
}
}
/**
* Calculate L(x)
*/
Lagrange.prototype.valueOf = function(x) {
var a = 0;
var b = 0;
var c = 0;
for (var j = 0; j < this.xs.length; ++j) {
if (x != this.xs[j]) {
a = this.ws[j] / (x - this.xs[j]);
b += a * this.ys[j];
c += a;
} else {
return this.ys[j];
}
}
return b / c;
}
Lagrange.prototype.addMultiPoints = function(arr){
for(var i = 0, n = arr.length; i < n; i++){
if(arr[i][0] !== 0 && arr[i][0] !== 1){
this.addPoint(arr[i][1], arr[i][2]);
}
}
};
module.exports = Lagrange;