Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

64 wiersze
1.8 KiB

  1. import {abs, epsilon, epsilon2} from "./math.js";
  2. // Approximate Newton-Raphson
  3. // Solve f(x) = y, start from x
  4. export function solve(f, y, x) {
  5. var steps = 100, delta, f0, f1;
  6. x = x === undefined ? 0 : +x;
  7. y = +y;
  8. do {
  9. f0 = f(x);
  10. f1 = f(x + epsilon);
  11. if (f0 === f1) f1 = f0 + epsilon;
  12. x -= delta = (-1 * epsilon * (f0 - y)) / (f0 - f1);
  13. } while (steps-- > 0 && abs(delta) > epsilon);
  14. return steps < 0 ? NaN : x;
  15. }
  16. // Approximate Newton-Raphson in 2D
  17. // Solve f(a,b) = [x,y]
  18. export function solve2d(f, MAX_ITERATIONS, eps) {
  19. if (MAX_ITERATIONS === undefined) MAX_ITERATIONS = 40;
  20. if (eps === undefined) eps = epsilon2;
  21. return function(x, y, a, b) {
  22. var err2, da, db;
  23. a = a === undefined ? 0 : +a;
  24. b = b === undefined ? 0 : +b;
  25. for (var i = 0; i < MAX_ITERATIONS; i++) {
  26. var p = f(a, b),
  27. // diffs
  28. tx = p[0] - x,
  29. ty = p[1] - y;
  30. if (abs(tx) < eps && abs(ty) < eps) break; // we're there!
  31. // backtrack if we overshot
  32. var h = tx * tx + ty * ty;
  33. if (h > err2) {
  34. a -= da /= 2;
  35. b -= db /= 2;
  36. continue;
  37. }
  38. err2 = h;
  39. // partial derivatives
  40. var ea = (a > 0 ? -1 : 1) * eps,
  41. eb = (b > 0 ? -1 : 1) * eps,
  42. pa = f(a + ea, b),
  43. pb = f(a, b + eb),
  44. dxa = (pa[0] - p[0]) / ea,
  45. dya = (pa[1] - p[1]) / ea,
  46. dxb = (pb[0] - p[0]) / eb,
  47. dyb = (pb[1] - p[1]) / eb,
  48. // determinant
  49. D = dyb * dxa - dya * dxb,
  50. // newton step — or half-step for small D
  51. l = (abs(D) < 0.5 ? 0.5 : 1) / D;
  52. da = (ty * dxb - tx * dyb) * l;
  53. db = (tx * dya - ty * dxa) * l;
  54. a += da;
  55. b += db;
  56. if (abs(da) < eps && abs(db) < eps) break; // we're crawling
  57. }
  58. return [a, b];
  59. };
  60. }