lingshu-solver 1.0.4 → 1.0.6
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.
- package/index.html +49 -2
- package/package.json +2 -2
package/index.html
CHANGED
|
@@ -5833,6 +5833,9 @@ function suan22(state) {
|
|
|
5833
5833
|
_walk1(_eq);
|
|
5834
5834
|
})();
|
|
5835
5835
|
if (_lo < _hi) {
|
|
5836
|
+
var _dense = false; // 修3:根稠密/超时提前终止扫描(防宽域周期方程穷举挂起)
|
|
5837
|
+
var _denseByCount = false; // 修3:仅由"根数超阈值"触发的稠密标记(用于无限/截断判定,区别于超时触发)
|
|
5838
|
+
var _denseNonPeriodic = false; // 修3:非周期稠密截断标记(与 periodic→无限 分支互补)
|
|
5836
5839
|
// ---- 周期感知步长(issue A 修复 2026-09-01):高频/多周期方程用 < 周期/2 的网格,
|
|
5837
5840
|
// 确保不漏根;非周期方程回退到 4096 点默认细网格。点数上限 _NMAX 护栏防宽域爆炸。 ----
|
|
5838
5841
|
var _P = _detectPeriod1D(_eq, _vn);
|
|
@@ -5902,8 +5905,11 @@ function suan22(state) {
|
|
|
5902
5905
|
_recScanInterval(_eq, _vn, _gxP, _gx, state, allSolutions, resultVarNames, 0);
|
|
5903
5906
|
}
|
|
5904
5907
|
}
|
|
5908
|
+
if (allSolutions.length > 200) { _dense = true; _denseByCount = true; break; }
|
|
5909
|
+
if ((performance.now() - state.startTime) > 1500) { _dense = true; break; }
|
|
5905
5910
|
_gxP = _gx; _gfP = _gf;
|
|
5906
5911
|
}
|
|
5912
|
+
if (_dense) break;
|
|
5907
5913
|
// 终止端点若有根也记录
|
|
5908
5914
|
if (_gfP !== null && Math.abs(_gfP) < 1e-7) {
|
|
5909
5915
|
var _fbV = reconstructSolution(state, [_B]).map(roundToGrid);
|
|
@@ -5951,6 +5957,31 @@ function suan22(state) {
|
|
|
5951
5957
|
if (_dedupMap[_mi]) mergedSolutions.push(_dedupMap[_mi]);
|
|
5952
5958
|
}
|
|
5953
5959
|
|
|
5960
|
+
// 修3(2026-09-04):稠密根防护——单变量周期方程在宽域内根稠密,
|
|
5961
|
+
// 继续穷举既耗时(曾致 solve 挂起 >110s)又产出无用的海量解集。
|
|
5962
|
+
// 含周期函数且根数超阈值 ⇒ 解集实际为无限(周期平移),如实标 rt=3 无限解集(代表解);
|
|
5963
|
+
// 非周期但稠密(如高次多项式)⇒ 不谎称无限,置 truncated 并后续告警,诚实返回部分代表根。
|
|
5964
|
+
if (_denseByCount) {
|
|
5965
|
+
if (_P !== null) {
|
|
5966
|
+
state.done = true;
|
|
5967
|
+
state.result = {
|
|
5968
|
+
solutions: mergedSolutions,
|
|
5969
|
+
error: null,
|
|
5970
|
+
message: "单变量周期方程在声明域内出现大量(>" + 200 + ")孤立根,呈周期性稠密分布,解集实际为无限(如 x = x₀ + k·" + _P.toFixed(4) + ")。已给出 " + mergedSolutions.length + " 个代表根;如需有限个解请收窄变量定义域。",
|
|
5971
|
+
executionPath: "单变量稠密周期根判定(无限解集)",
|
|
5972
|
+
timeMs: performance.now() - state.startTime,
|
|
5973
|
+
confidence: "high",
|
|
5974
|
+
varNames: resultVarNames,
|
|
5975
|
+
resultType: 3,
|
|
5976
|
+
resultTypeName: "无限解集(代表解)",
|
|
5977
|
+
resultTypeDesc: "周期方程在宽域内根稠密,解集为周期平移的无穷集合,已给出代表根"
|
|
5978
|
+
};
|
|
5979
|
+
return;
|
|
5980
|
+
}
|
|
5981
|
+
state.truncated = true; // 非周期稠密:诚实截断(避免海量/不完整解集),下方 domainFiltered 产出部分代表根
|
|
5982
|
+
_denseNonPeriodic = true;
|
|
5983
|
+
}
|
|
5984
|
+
|
|
5954
5985
|
// 2) 原始方程回代验证:对每组候选解,代入全部原始方程重新计算残差
|
|
5955
5986
|
// 二分查找得到的解(_bisect=true)跳过残差验证(区间收敛保证精度)
|
|
5956
5987
|
var _origEqs = state.originalEquations || state.equations;
|
|
@@ -6082,6 +6113,12 @@ function suan22(state) {
|
|
|
6082
6113
|
}
|
|
6083
6114
|
}
|
|
6084
6115
|
}
|
|
6116
|
+
// 修3:非周期稠密截断告警(与上方 periodic→无限 分支互补)
|
|
6117
|
+
if (_denseNonPeriodic && state.result) {
|
|
6118
|
+
state.result.warnings = (state.result.warnings || []).concat([
|
|
6119
|
+
"方程在声明域内根数量过多(>" + 200 + "),已截断扫描;结果不完整,缩小变量范围或确认方程规模可获完整解集。"
|
|
6120
|
+
]);
|
|
6121
|
+
}
|
|
6085
6122
|
}
|
|
6086
6123
|
}
|
|
6087
6124
|
|
|
@@ -6624,7 +6661,13 @@ function _affineEval(ast, env) {
|
|
|
6624
6661
|
// 超越函数降级:仿射自变量 → 保守区间函数包围(复用 _rangeEval,无递归环)
|
|
6625
6662
|
var tmp = { type: 'func', name: ast.name, arg: { type: 'var', name: '__a' } };
|
|
6626
6663
|
var rv = _rangeEval(tmp, { __a: iv });
|
|
6627
|
-
|
|
6664
|
+
if (!rv || !isFinite(rv.min) || !isFinite(rv.max)) return null; // 含 ±Inf:交还 _rangeEval 直接给出保守区间
|
|
6665
|
+
// 关键修复(P0-2):旧实现 return _Aff((rv.min+rv.max)/2, {}) 把合法区间宽度丢成 0,
|
|
6666
|
+
// 致 intervalEval(sin x)@[-2,2] 塌成 [0,0](unsound:真值须含 [-1,1])。
|
|
6667
|
+
// 正确做法:用半径 (rv.max-rv.min)/2 的噪声符号把 rv 完整编码为仿射,
|
|
6668
|
+
// 使 _affToInterval 还原为 [rv.min, rv.max](sound 且紧致),Krawczyk 雅可比随之可信。
|
|
6669
|
+
var e = {}; e[_affSym++] = (rv.max - rv.min) / 2;
|
|
6670
|
+
return _Aff((rv.min + rv.max) / 2, e);
|
|
6628
6671
|
}
|
|
6629
6672
|
if (ast.type === 'unary') {
|
|
6630
6673
|
var u = _affineEval(ast.operand, env);
|
|
@@ -11378,7 +11421,11 @@ function _newtonRefine(eqs, vns, x0, box) {
|
|
|
11378
11421
|
var F = []; for (var e = 0; e < n; e++) { var fe = evalAST(eqs[e], vmap); if (!isFinite(fe)) return null; F.push(fe); }
|
|
11379
11422
|
var rms = 0; for (var i2 = 0; i2 < n; i2++) rms += F[i2] * F[i2]; rms = Math.sqrt(rms / n);
|
|
11380
11423
|
if (rms < 1e-11) return x;
|
|
11381
|
-
|
|
11424
|
+
// 雅可比区间求导:必须喂退化的点区间 {min:x,max:x}(而非裸点值)。
|
|
11425
|
+
// 旧实现 intervalEval(d, vmap) 把裸数当 iv,iv.min/iv.max 为 undefined → _buildAffEnv 算出 NaN 噪声
|
|
11426
|
+
// → 雅可比整行 NaN → realMatInv 失败 → 本函数对一切良置问题恒返 null(P0-1)。
|
|
11427
|
+
var pmap = {}; for (var i3 = 0; i3 < n; i3++) pmap[vns[i3]] = { min: x[i3], max: x[i3] };
|
|
11428
|
+
var J = []; for (var a = 0; a < n; a++) { J.push([]); for (var b = 0; b < n; b++) { var d = _diffAST(eqs[a], vns[b]); var dv = intervalEval(d, pmap); if (!dv) return null; J[a].push((dv.min + dv.max) / 2); } }
|
|
11382
11429
|
var Y = realMatInv(J); if (!Y) return null;
|
|
11383
11430
|
var dX = rMatVec(Y, F);
|
|
11384
11431
|
for (var j = 0; j < n; j++) x[j] = x[j] - dX[j];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lingshu-solver",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "灵数求解器 · 确定性实数方程组求解 MCP 工具(≤6变量):区间收缩 + Krawczyk 认证,离线零依赖零数据,诚实标记 truncated。",
|
|
5
5
|
"homepage": "https://genesis-plan.github.io/lingshu-solver/",
|
|
6
6
|
"repository": {
|
|
@@ -50,6 +50,6 @@
|
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"start": "node mcp-server.js",
|
|
53
|
-
"test": "node test/
|
|
53
|
+
"test": "node test/p0_fix_regression.js"
|
|
54
54
|
}
|
|
55
55
|
}
|