JavaScript使用nerdamer库求解两函数相交所有解的方法
解决方案
1 修正基础调用错误
你当前的代码首先存在调用逻辑错误:nerdamer.solve('f1', 'f2')传入的是字符串常量'f1'、'f2',而非你传入的函数表达式变量,首先要修正构造方程的逻辑:求解两个函数交点等价于求解方程f1(x) = f2(x),也就是f1(x) - f2(x) = 0。
2 有限解场景获取所有根
对于多项式这类只有有限个解的场景,修正调用逻辑后,新版nerdamer的solve方法会返回所有解析解的数组,示例代码如下:
intersect("x^3", "x") function intersect(f1, f2){ // 构造待求解方程 const equation = `${f1} - (${f2})` // 传入方程和求解变量x const xSolutions = nerdamer.solve(equation, 'x'); // 转换为普通JS数组输出 const result = xSolutions.map(item => item.evaluate().text()) console.log(result); }
上述代码执行后会输出["-1", "0", "1"],符合你预期的三个解。
3 周期函数无穷解场景处理
对于sin(x)=0这类存在无穷多周期解的场景,nerdamer会返回带整数参数n的通解,你拿到通解后可以根据自己需要的x取值范围,代入不同的整数n生成对应区间内的所有交点,示例代码如下:
// 获取指定x范围内的周期函数交点 function getPeriodicIntersections(f1, f2, xMin, xMax) { const equation = `${f1} - (${f2})` const generalSolution = nerdamer.solve(equation, 'x')[0].text() const intersections = [] // 以sin(x)=0的通解 pi*n 为例,遍历n的取值 for (let n = Math.ceil(xMin / Math.PI); n <= Math.floor(xMax / Math.PI); n++) { const x = Number(nerdamer(generalSolution, {n: n}).evaluate().text()) const y = Number(nerdamer(f1, {x: x}).evaluate().text()) intersections.push([x, y]) } return intersections } // 测试获取sin(x)与y=0在[-2π, 3π]范围内的交点 console.log(getPeriodicIntersections("sin(x)", "0", -2 * Math.PI, 3 * Math.PI))
上述代码会输出你需要的[[-6.283..., 0], [-3.1415..., 0], [0, 0], [3.1415..., 0], [6.283..., 0], [9.424..., 0]]格式的交点数组。
4 注意事项
- 请确保你使用的是最新版本的nerdamer库,旧版本的
solve方法确实存在仅返回单个解的问题 - 如果求解的是无解析通解的超越方程,可使用nerdamer的
solveNum方法,指定遍历区间和步长做数值求解获取对应范围内的所有零点
内容的提问来源于stack exchange,提问作者user17150885
相关产品推荐
相关产品推荐

