numopt-js 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CODING_RULES.md +161 -0
  2. package/LICENSE +22 -0
  3. package/README.md +807 -0
  4. package/dist/core/adjointGradientDescent.d.ts +61 -0
  5. package/dist/core/adjointGradientDescent.d.ts.map +1 -0
  6. package/dist/core/adjointGradientDescent.js +764 -0
  7. package/dist/core/adjointGradientDescent.js.map +1 -0
  8. package/dist/core/constrainedGaussNewton.d.ts +44 -0
  9. package/dist/core/constrainedGaussNewton.d.ts.map +1 -0
  10. package/dist/core/constrainedGaussNewton.js +314 -0
  11. package/dist/core/constrainedGaussNewton.js.map +1 -0
  12. package/dist/core/constrainedLevenbergMarquardt.d.ts +46 -0
  13. package/dist/core/constrainedLevenbergMarquardt.d.ts.map +1 -0
  14. package/dist/core/constrainedLevenbergMarquardt.js +469 -0
  15. package/dist/core/constrainedLevenbergMarquardt.js.map +1 -0
  16. package/dist/core/constrainedUtils.d.ts +92 -0
  17. package/dist/core/constrainedUtils.d.ts.map +1 -0
  18. package/dist/core/constrainedUtils.js +364 -0
  19. package/dist/core/constrainedUtils.js.map +1 -0
  20. package/dist/core/convergence.d.ts +35 -0
  21. package/dist/core/convergence.d.ts.map +1 -0
  22. package/dist/core/convergence.js +51 -0
  23. package/dist/core/convergence.js.map +1 -0
  24. package/dist/core/createGradientFunction.d.ts +85 -0
  25. package/dist/core/createGradientFunction.d.ts.map +1 -0
  26. package/dist/core/createGradientFunction.js +93 -0
  27. package/dist/core/createGradientFunction.js.map +1 -0
  28. package/dist/core/effectiveJacobian.d.ts +90 -0
  29. package/dist/core/effectiveJacobian.d.ts.map +1 -0
  30. package/dist/core/effectiveJacobian.js +128 -0
  31. package/dist/core/effectiveJacobian.js.map +1 -0
  32. package/dist/core/finiteDiff.d.ts +171 -0
  33. package/dist/core/finiteDiff.d.ts.map +1 -0
  34. package/dist/core/finiteDiff.js +363 -0
  35. package/dist/core/finiteDiff.js.map +1 -0
  36. package/dist/core/gaussNewton.d.ts +29 -0
  37. package/dist/core/gaussNewton.d.ts.map +1 -0
  38. package/dist/core/gaussNewton.js +151 -0
  39. package/dist/core/gaussNewton.js.map +1 -0
  40. package/dist/core/gradientDescent.d.ts +35 -0
  41. package/dist/core/gradientDescent.d.ts.map +1 -0
  42. package/dist/core/gradientDescent.js +204 -0
  43. package/dist/core/gradientDescent.js.map +1 -0
  44. package/dist/core/jacobianComputation.d.ts +24 -0
  45. package/dist/core/jacobianComputation.d.ts.map +1 -0
  46. package/dist/core/jacobianComputation.js +38 -0
  47. package/dist/core/jacobianComputation.js.map +1 -0
  48. package/dist/core/levenbergMarquardt.d.ts +36 -0
  49. package/dist/core/levenbergMarquardt.d.ts.map +1 -0
  50. package/dist/core/levenbergMarquardt.js +286 -0
  51. package/dist/core/levenbergMarquardt.js.map +1 -0
  52. package/dist/core/lineSearch.d.ts +42 -0
  53. package/dist/core/lineSearch.d.ts.map +1 -0
  54. package/dist/core/lineSearch.js +106 -0
  55. package/dist/core/lineSearch.js.map +1 -0
  56. package/dist/core/logger.d.ts +77 -0
  57. package/dist/core/logger.d.ts.map +1 -0
  58. package/dist/core/logger.js +162 -0
  59. package/dist/core/logger.js.map +1 -0
  60. package/dist/core/types.d.ts +427 -0
  61. package/dist/core/types.d.ts.map +1 -0
  62. package/dist/core/types.js +15 -0
  63. package/dist/core/types.js.map +1 -0
  64. package/dist/index.d.ts +26 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +29 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/utils/formatting.d.ts +27 -0
  69. package/dist/utils/formatting.d.ts.map +1 -0
  70. package/dist/utils/formatting.js +54 -0
  71. package/dist/utils/formatting.js.map +1 -0
  72. package/dist/utils/matrix.d.ts +63 -0
  73. package/dist/utils/matrix.d.ts.map +1 -0
  74. package/dist/utils/matrix.js +129 -0
  75. package/dist/utils/matrix.js.map +1 -0
  76. package/dist/utils/resultFormatter.d.ts +122 -0
  77. package/dist/utils/resultFormatter.d.ts.map +1 -0
  78. package/dist/utils/resultFormatter.js +342 -0
  79. package/dist/utils/resultFormatter.js.map +1 -0
  80. package/package.json +74 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createGradientFunction.js","sourceRoot":"","sources":["../../src/core/createGradientFunction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AASzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,wBAAwB,CACpC,YAAoB,EACpB,OAAyC;IAEzC,OAAO,CAAC,MAAoB,EAAgB,EAAE;QAC1C,OAAO,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,wBAAwB,CACpC,gBAA4B,EAC5B,OAAyC;IAEzC,OAAO,CAAC,MAAoB,EAAE,EAAE;QAC5B,OAAO,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * This file implements the effective Jacobian computation for constrained optimization.
3
+ *
4
+ * The effective Jacobian J_eff = dr/dp = r_p - r_x C_x^+ C_p captures all constraint
5
+ * effects, allowing constrained least squares problems to be solved using the same
6
+ * structure as unconstrained problems.
7
+ *
8
+ * Mathematical background:
9
+ * - For constrained residual r(p, x) where c(p, x) = 0, the implicit function
10
+ * theorem gives: dr/dp = r_p - r_x C_x^+ C_p
11
+ * - We compute this efficiently by solving C_x dx = (C_p)_j for each parameter j,
12
+ * then (J_eff)_j = (r_p)_j - r_x dx
13
+ * - This reuses the C_x decomposition across all columns for efficiency.
14
+ *
15
+ * Role in system:
16
+ * - Core component for constrained Gauss-Newton and Levenberg-Marquardt methods
17
+ * - Enables efficient constrained least squares optimization
18
+ * - Uses direct linear solve to avoid explicit matrix inversion
19
+ *
20
+ * For first-time readers:
21
+ * - Start with computeEffectiveJacobian function
22
+ * - Understand how each column is computed efficiently
23
+ * - Note the reuse of C_x decomposition for performance
24
+ */
25
+ import { Matrix } from 'ml-matrix';
26
+ import type { ConstrainedResidualFn, ConstraintFn } from './types.js';
27
+ import { Logger } from './logger.js';
28
+ /**
29
+ * Options for effective Jacobian computation.
30
+ */
31
+ export interface EffectiveJacobianOptions {
32
+ /**
33
+ * Analytical partial derivative of residual function with respect to parameters.
34
+ * If provided, this will be used instead of numerical differentiation.
35
+ * Returns a Matrix of size (residualCount × parameterCount).
36
+ */
37
+ drdp?: (parameters: Float64Array, states: Float64Array) => Matrix;
38
+ /**
39
+ * Analytical partial derivative of residual function with respect to states.
40
+ * If provided, this will be used instead of numerical differentiation.
41
+ * Returns a Matrix of size (residualCount × stateCount).
42
+ */
43
+ drdx?: (parameters: Float64Array, states: Float64Array) => Matrix;
44
+ /**
45
+ * Analytical partial derivative of constraint function with respect to parameters.
46
+ * If provided, this will be used instead of numerical differentiation.
47
+ * Returns a Matrix of size (constraintCount × parameterCount).
48
+ */
49
+ dcdp?: (parameters: Float64Array, states: Float64Array) => Matrix;
50
+ /**
51
+ * Analytical partial derivative of constraint function with respect to states.
52
+ * If provided, this will be used instead of numerical differentiation.
53
+ * Returns a Matrix of size (constraintCount × stateCount).
54
+ */
55
+ dcdx?: (parameters: Float64Array, states: Float64Array) => Matrix;
56
+ /**
57
+ * Step size for numerical differentiation with respect to parameters.
58
+ * Default: 1e-6
59
+ */
60
+ stepSizeP?: number;
61
+ /**
62
+ * Step size for numerical differentiation with respect to states.
63
+ * Default: 1e-6
64
+ */
65
+ stepSizeX?: number;
66
+ }
67
+ /**
68
+ * Computes the effective Jacobian J_eff = r_p - r_x C_x^+ C_p.
69
+ *
70
+ * Algorithm:
71
+ * 1. Compute partial derivatives: r_p, r_x, C_p, C_x
72
+ * 2. For each column j (parameter j):
73
+ * a. Extract j-th column of C_p: (C_p)_j
74
+ * b. Solve: C_x dx = (C_p)_j to get dx = C_x^-1 (C_p)_j
75
+ * c. Compute column: (J_eff)_j = (r_p)_j - r_x dx
76
+ * 3. Return effective Jacobian matrix
77
+ *
78
+ * The C_x decomposition is reused across all columns for efficiency.
79
+ *
80
+ * @param parameters - Parameter vector p
81
+ * @param states - State vector x (satisfies c(p, x) = 0)
82
+ * @param residualFunction - Residual function r(p, x)
83
+ * @param constraintFunction - Constraint function c(p, x) = 0
84
+ * @param options - Options for Jacobian computation
85
+ * @param logger - Logger instance for error reporting
86
+ * @param algorithmName - Name of calling algorithm (for error messages)
87
+ * @returns Effective Jacobian matrix J_eff (residualCount × parameterCount)
88
+ */
89
+ export declare function computeEffectiveJacobian(parameters: Float64Array, states: Float64Array, residualFunction: ConstrainedResidualFn, constraintFunction: ConstraintFn, options: EffectiveJacobianOptions | undefined, logger: Logger, algorithmName?: string): Matrix;
90
+ //# sourceMappingURL=effectiveJacobian.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effectiveJacobian.d.ts","sourceRoot":"","sources":["../../src/core/effectiveJacobian.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,EACV,qBAAqB,EACrB,YAAY,EACb,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IAElE;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IAElE;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IAElE;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC;IAElE;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,gBAAgB,EAAE,qBAAqB,EACvC,kBAAkB,EAAE,YAAY,EAChC,OAAO,EAAE,wBAAwB,YAAK,EACtC,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAkC,GAChD,MAAM,CAqER"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * This file implements the effective Jacobian computation for constrained optimization.
3
+ *
4
+ * The effective Jacobian J_eff = dr/dp = r_p - r_x C_x^+ C_p captures all constraint
5
+ * effects, allowing constrained least squares problems to be solved using the same
6
+ * structure as unconstrained problems.
7
+ *
8
+ * Mathematical background:
9
+ * - For constrained residual r(p, x) where c(p, x) = 0, the implicit function
10
+ * theorem gives: dr/dp = r_p - r_x C_x^+ C_p
11
+ * - We compute this efficiently by solving C_x dx = (C_p)_j for each parameter j,
12
+ * then (J_eff)_j = (r_p)_j - r_x dx
13
+ * - This reuses the C_x decomposition across all columns for efficiency.
14
+ *
15
+ * Role in system:
16
+ * - Core component for constrained Gauss-Newton and Levenberg-Marquardt methods
17
+ * - Enables efficient constrained least squares optimization
18
+ * - Uses direct linear solve to avoid explicit matrix inversion
19
+ *
20
+ * For first-time readers:
21
+ * - Start with computeEffectiveJacobian function
22
+ * - Understand how each column is computed efficiently
23
+ * - Note the reuse of C_x decomposition for performance
24
+ */
25
+ import { Matrix } from 'ml-matrix';
26
+ import { finiteDiffResidualPartialP, finiteDiffResidualPartialX, finiteDiffConstraintPartialP, finiteDiffConstraintPartialX } from './finiteDiff.js';
27
+ import { float64ArrayToMatrix } from '../utils/matrix.js';
28
+ import { solveLeastSquares } from './constrainedUtils.js';
29
+ const DEFAULT_STEP_SIZE_P = 1e-6;
30
+ const DEFAULT_STEP_SIZE_X = 1e-6;
31
+ /**
32
+ * Computes the effective Jacobian J_eff = r_p - r_x C_x^+ C_p.
33
+ *
34
+ * Algorithm:
35
+ * 1. Compute partial derivatives: r_p, r_x, C_p, C_x
36
+ * 2. For each column j (parameter j):
37
+ * a. Extract j-th column of C_p: (C_p)_j
38
+ * b. Solve: C_x dx = (C_p)_j to get dx = C_x^-1 (C_p)_j
39
+ * c. Compute column: (J_eff)_j = (r_p)_j - r_x dx
40
+ * 3. Return effective Jacobian matrix
41
+ *
42
+ * The C_x decomposition is reused across all columns for efficiency.
43
+ *
44
+ * @param parameters - Parameter vector p
45
+ * @param states - State vector x (satisfies c(p, x) = 0)
46
+ * @param residualFunction - Residual function r(p, x)
47
+ * @param constraintFunction - Constraint function c(p, x) = 0
48
+ * @param options - Options for Jacobian computation
49
+ * @param logger - Logger instance for error reporting
50
+ * @param algorithmName - Name of calling algorithm (for error messages)
51
+ * @returns Effective Jacobian matrix J_eff (residualCount × parameterCount)
52
+ */
53
+ export function computeEffectiveJacobian(parameters, states, residualFunction, constraintFunction, options = {}, logger, algorithmName = 'constrainedOptimization') {
54
+ const stepSizeP = options.stepSizeP ?? DEFAULT_STEP_SIZE_P;
55
+ const stepSizeX = options.stepSizeX ?? DEFAULT_STEP_SIZE_X;
56
+ // Compute partial derivatives
57
+ const r_p = options.drdp
58
+ ? options.drdp(parameters, states)
59
+ : finiteDiffResidualPartialP(parameters, states, residualFunction, { stepSize: stepSizeP });
60
+ const r_x = options.drdx
61
+ ? options.drdx(parameters, states)
62
+ : finiteDiffResidualPartialX(parameters, states, residualFunction, { stepSize: stepSizeX });
63
+ const c_p = options.dcdp
64
+ ? options.dcdp(parameters, states)
65
+ : finiteDiffConstraintPartialP(parameters, states, constraintFunction, { stepSize: stepSizeP });
66
+ const c_x = options.dcdx
67
+ ? options.dcdx(parameters, states)
68
+ : finiteDiffConstraintPartialX(parameters, states, constraintFunction, { stepSize: stepSizeX });
69
+ // Get dimensions
70
+ const residualCount = r_p.rows;
71
+ const parameterCount = r_p.columns;
72
+ const stateCount = c_x.columns;
73
+ // Note: Constraint Jacobian ∂c/∂x can be non-square.
74
+ // The adjoint method now supports both square and non-square constraint Jacobians.
75
+ // Dimension validation removed to allow non-square matrices.
76
+ if (r_x.columns !== stateCount) {
77
+ const errorMsg = `Residual Jacobian ∂r/∂x must have stateCount columns. ` +
78
+ `Got ${r_x.rows} × ${r_x.columns}, expected ${r_x.rows} × ${stateCount}. Algorithm: ${algorithmName}`;
79
+ logger.warn(algorithmName, undefined, errorMsg);
80
+ throw new Error(errorMsg);
81
+ }
82
+ if (c_p.columns !== parameterCount) {
83
+ const errorMsg = `Constraint Jacobian ∂c/∂p must have parameterCount columns. ` +
84
+ `Got ${c_p.rows} × ${c_p.columns}, expected ${c_p.rows} × ${parameterCount}. Algorithm: ${algorithmName}`;
85
+ logger.warn(algorithmName, undefined, errorMsg);
86
+ throw new Error(errorMsg);
87
+ }
88
+ // Initialize effective Jacobian matrix (residualCount × parameterCount)
89
+ const effectiveJacobianData = [];
90
+ for (let i = 0; i < residualCount; i++) {
91
+ effectiveJacobianData.push(new Array(parameterCount).fill(0));
92
+ }
93
+ // Compute each column of effective Jacobian
94
+ for (let paramIndex = 0; paramIndex < parameterCount; paramIndex++) {
95
+ const column = computeEffectiveJacobianColumn(paramIndex, c_p, c_x, r_p, r_x, stateCount, residualCount, logger, algorithmName);
96
+ for (let i = 0; i < residualCount; i++) {
97
+ effectiveJacobianData[i][paramIndex] = column[i];
98
+ }
99
+ }
100
+ return new Matrix(effectiveJacobianData);
101
+ }
102
+ /**
103
+ * Computes a single column of the effective Jacobian.
104
+ * For parameter j: (J_eff)_j = (r_p)_j - r_x dx, where dx solves C_x dx = (C_p)_j
105
+ */
106
+ function computeEffectiveJacobianColumn(paramIndex, constraintJacobianP, constraintJacobianX, residualJacobianP, residualJacobianX, stateCount, residualCount, logger, algorithmName) {
107
+ // Extract j-th column of C_p: (C_p)_j
108
+ const constraintCount = constraintJacobianP.rows;
109
+ const constraintJacobianPColumn = new Float64Array(constraintCount);
110
+ for (let k = 0; k < constraintCount; k++) {
111
+ constraintJacobianPColumn[k] = constraintJacobianP.get(k, paramIndex);
112
+ }
113
+ // Solve: C_x dx = (C_p)_j to get dx = C_x^+ (C_p)_j
114
+ // Uses hierarchical solver that handles both square and non-square matrices
115
+ const constraintJacobianPColumnMatrix = float64ArrayToMatrix(constraintJacobianPColumn);
116
+ const stateSensitivity = solveLeastSquares(constraintJacobianX, constraintJacobianPColumnMatrix, logger, algorithmName);
117
+ // Compute: (J_eff)_j = (r_p)_j - r_x dx
118
+ const effectiveJacobianColumn = new Float64Array(residualCount);
119
+ for (let i = 0; i < residualCount; i++) {
120
+ let residualJacobianXTimesStateSensitivity = 0;
121
+ for (let k = 0; k < stateCount; k++) {
122
+ residualJacobianXTimesStateSensitivity += residualJacobianX.get(i, k) * stateSensitivity[k];
123
+ }
124
+ effectiveJacobianColumn[i] = residualJacobianP.get(i, paramIndex) - residualJacobianXTimesStateSensitivity;
125
+ }
126
+ return effectiveJacobianColumn;
127
+ }
128
+ //# sourceMappingURL=effectiveJacobian.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effectiveJacobian.js","sourceRoot":"","sources":["../../src/core/effectiveJacobian.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * This file implements numerical differentiation methods for computing
3
+ * gradients and Jacobian matrices when analytical derivatives are not available.
4
+ *
5
+ * Role in system:
6
+ * - Provides automatic gradient/Jacobian computation via finite differences
7
+ * - Used when users don't provide analytical derivatives
8
+ * - Critical for algorithms that require gradient information
9
+ *
10
+ * For first-time readers:
11
+ * - Start with finiteDiffGradient for general optimization
12
+ * - finiteDiffJacobian is for nonlinear least squares problems
13
+ * - Central difference is used for better accuracy than forward difference
14
+ */
15
+ import { Matrix } from 'ml-matrix';
16
+ import type { CostFn, ResidualFn, NumericalDifferentiationOptions, ConstrainedCostFn, ConstraintFn, ConstrainedResidualFn } from './types.js';
17
+ /**
18
+ * Computes the gradient vector using central difference method.
19
+ *
20
+ * Central difference formula: f'(x) ≈ (f(x+h) - f(x-h)) / (2h)
21
+ *
22
+ * This is more accurate than forward difference but requires two function
23
+ * evaluations per parameter. The trade-off is worth it for better convergence.
24
+ *
25
+ * @param parameters - The point at which to evaluate the gradient
26
+ * @param costFunction - The cost function to differentiate
27
+ * @param options - Optional numerical differentiation settings
28
+ * @returns The gradient vector at the given parameters
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Standalone usage - compute gradient at a specific point
33
+ * const costFn = (params) => params[0] ** 2 + params[1] ** 2;
34
+ * const params = new Float64Array([1.0, 2.0]);
35
+ * const gradient = finiteDiffGradient(params, costFn);
36
+ * // gradient ≈ [2.0, 4.0]
37
+ * ```
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * // Usage with gradientDescent - note the parameter order!
42
+ * import { gradientDescent, finiteDiffGradient } from 'numopt-js';
43
+ *
44
+ * const costFn = (params) => Math.pow(params[0] - 3, 2) + Math.pow(params[1] - 2, 2);
45
+ *
46
+ * const result = gradientDescent(
47
+ * new Float64Array([0, 0]),
48
+ * costFn,
49
+ * (params) => finiteDiffGradient(params, costFn), // ✅ Correct: params first!
50
+ * { maxIterations: 100, tolerance: 1e-6 }
51
+ * );
52
+ * ```
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * // For easier usage with optimizers, consider using createFiniteDiffGradient:
57
+ * import { gradientDescent, createFiniteDiffGradient } from 'numopt-js';
58
+ *
59
+ * const costFn = (params) => Math.pow(params[0] - 3, 2) + Math.pow(params[1] - 2, 2);
60
+ * const gradientFn = createFiniteDiffGradient(costFn); // No parameter order confusion!
61
+ *
62
+ * const result = gradientDescent(
63
+ * new Float64Array([0, 0]),
64
+ * costFn,
65
+ * gradientFn,
66
+ * { maxIterations: 100, tolerance: 1e-6 }
67
+ * );
68
+ * ```
69
+ *
70
+ * @remarks
71
+ * **Important:** When using with optimization algorithms, note the parameter order:
72
+ * - ✅ Correct: `(params) => finiteDiffGradient(params, costFn)`
73
+ * - ❌ Wrong: `(params) => finiteDiffGradient(costFn, params)`
74
+ *
75
+ * Consider using {@link createFiniteDiffGradient} for a more intuitive API.
76
+ */
77
+ export declare function finiteDiffGradient(parameters: Float64Array, costFunction: CostFn, options?: NumericalDifferentiationOptions): Float64Array;
78
+ /**
79
+ * Computes the Jacobian matrix using central difference method.
80
+ *
81
+ * The Jacobian J has dimensions (residualCount × parameterCount) where:
82
+ * - Each row corresponds to a residual component
83
+ * - Each column corresponds to a parameter
84
+ * - J[i][j] = ∂r_i / ∂p_j
85
+ *
86
+ * Central difference is used for each partial derivative.
87
+ */
88
+ export declare function finiteDiffJacobian(residualFunction: ResidualFn, parameters: Float64Array, options?: NumericalDifferentiationOptions): Matrix;
89
+ /**
90
+ * Computes the partial derivative of a constrained cost function with respect to parameters.
91
+ * Uses central difference method while keeping states fixed.
92
+ *
93
+ * Formula: ∂f/∂p_i ≈ (f(p+h·e_i, x) - f(p-h·e_i, x)) / (2h)
94
+ *
95
+ * @param parameters - Parameter vector p
96
+ * @param states - State vector x (kept fixed)
97
+ * @param costFunction - Constrained cost function f(p, x)
98
+ * @param options - Optional numerical differentiation settings
99
+ * @returns Gradient vector ∂f/∂p
100
+ */
101
+ export declare function finiteDiffPartialP(parameters: Float64Array, states: Float64Array, costFunction: ConstrainedCostFn, options?: NumericalDifferentiationOptions): Float64Array;
102
+ /**
103
+ * Computes the partial derivative of a constrained cost function with respect to states.
104
+ * Uses central difference method while keeping parameters fixed.
105
+ *
106
+ * Formula: ∂f/∂x_i ≈ (f(p, x+h·e_i) - f(p, x-h·e_i)) / (2h)
107
+ *
108
+ * @param parameters - Parameter vector p (kept fixed)
109
+ * @param states - State vector x
110
+ * @param costFunction - Constrained cost function f(p, x)
111
+ * @param options - Optional numerical differentiation settings
112
+ * @returns Gradient vector ∂f/∂x
113
+ */
114
+ export declare function finiteDiffPartialX(parameters: Float64Array, states: Float64Array, costFunction: ConstrainedCostFn, options?: NumericalDifferentiationOptions): Float64Array;
115
+ /**
116
+ * Computes the partial derivative of a constraint function with respect to parameters.
117
+ * Uses central difference method while keeping states fixed.
118
+ * Returns a Jacobian matrix of size (constraintCount × parameterCount).
119
+ *
120
+ * Formula: ∂c/∂p_ij ≈ (c_i(p+h·e_j, x) - c_i(p-h·e_j, x)) / (2h)
121
+ *
122
+ * @param parameters - Parameter vector p
123
+ * @param states - State vector x (kept fixed)
124
+ * @param constraintFunction - Constraint function c(p, x)
125
+ * @param options - Optional numerical differentiation settings
126
+ * @returns Jacobian matrix ∂c/∂p
127
+ */
128
+ export declare function finiteDiffConstraintPartialP(parameters: Float64Array, states: Float64Array, constraintFunction: ConstraintFn, options?: NumericalDifferentiationOptions): Matrix;
129
+ /**
130
+ * Computes the partial derivative of a constraint function with respect to states.
131
+ * Uses central difference method while keeping parameters fixed.
132
+ * Returns a Jacobian matrix of size (constraintCount × stateCount).
133
+ *
134
+ * Formula: ∂c/∂x_ij ≈ (c_i(p, x+h·e_j) - c_i(p, x-h·e_j)) / (2h)
135
+ *
136
+ * @param parameters - Parameter vector p (kept fixed)
137
+ * @param states - State vector x
138
+ * @param constraintFunction - Constraint function c(p, x)
139
+ * @param options - Optional numerical differentiation settings
140
+ * @returns Jacobian matrix ∂c/∂x
141
+ */
142
+ export declare function finiteDiffConstraintPartialX(parameters: Float64Array, states: Float64Array, constraintFunction: ConstraintFn, options?: NumericalDifferentiationOptions): Matrix;
143
+ /**
144
+ * Computes the partial derivative of a constrained residual function with respect to parameters.
145
+ * Uses central difference method while keeping states fixed.
146
+ * Returns a Jacobian matrix of size (residualCount × parameterCount).
147
+ *
148
+ * Formula: ∂r/∂p_ij ≈ (r_i(p+h·e_j, x) - r_i(p-h·e_j, x)) / (2h)
149
+ *
150
+ * @param parameters - Parameter vector p
151
+ * @param states - State vector x (kept fixed)
152
+ * @param residualFunction - Constrained residual function r(p, x)
153
+ * @param options - Optional numerical differentiation settings
154
+ * @returns Jacobian matrix ∂r/∂p
155
+ */
156
+ export declare function finiteDiffResidualPartialP(parameters: Float64Array, states: Float64Array, residualFunction: ConstrainedResidualFn, options?: NumericalDifferentiationOptions): Matrix;
157
+ /**
158
+ * Computes the partial derivative of a constrained residual function with respect to states.
159
+ * Uses central difference method while keeping parameters fixed.
160
+ * Returns a Jacobian matrix of size (residualCount × stateCount).
161
+ *
162
+ * Formula: ∂r/∂x_ij ≈ (r_i(p, x+h·e_j) - r_i(p, x-h·e_j)) / (2h)
163
+ *
164
+ * @param parameters - Parameter vector p (kept fixed)
165
+ * @param states - State vector x
166
+ * @param residualFunction - Constrained residual function r(p, x)
167
+ * @param options - Optional numerical differentiation settings
168
+ * @returns Jacobian matrix ∂r/∂x
169
+ */
170
+ export declare function finiteDiffResidualPartialX(parameters: Float64Array, states: Float64Array, residualFunction: ConstrainedResidualFn, options?: NumericalDifferentiationOptions): Matrix;
171
+ //# sourceMappingURL=finiteDiff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finiteDiff.d.ts","sourceRoot":"","sources":["../../src/core/finiteDiff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,+BAA+B,EAC/B,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,YAAY,EACxB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,+BAAoC,GAC5C,YAAY,CAqBd;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,gBAAgB,EAAE,UAAU,EAC5B,UAAU,EAAE,YAAY,EACxB,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAkCR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,iBAAiB,EAC/B,OAAO,GAAE,+BAAoC,GAC5C,YAAY,CAqBd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,iBAAiB,EAC/B,OAAO,GAAE,+BAAoC,GAC5C,YAAY,CAqBd;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,kBAAkB,EAAE,YAAY,EAChC,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAkCR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,kBAAkB,EAAE,YAAY,EAChC,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAkCR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,gBAAgB,EAAE,qBAAqB,EACvC,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAkCR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,YAAY,EACxB,MAAM,EAAE,YAAY,EACpB,gBAAgB,EAAE,qBAAqB,EACvC,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAkCR"}