javascript中非线性方程组的数学求解

h7appiyu  于 2021-09-23  发布在  Java
关注(0)|答案(3)|浏览(443)

我有一个电阻系统,类似这样:电阻原理图
我做了一个网站,它可以呈现像这样的图表(不是这个)。用户可以改变每个电阻器的电阻。我想计算系统中的每个电流。
我用基尔霍夫定律找到了一个解,它给了我一个线性方程组。我用math.js用逆矩阵解决了这个问题。这种方法在较小的电路上运行良好。
在这个电路中,我有更多的方程,而不是变量,这意味着我无法计算逆矩阵来求解它们。手动简化它们,以匹配未知数量是一种选择,但这需要人工操作。该网站应该能够计算自己的一切。
现在我正在寻找一种方法来解决一个线性方程组,它不能表示为一个平方矩阵。有什么建议吗?
塔克斯!
编辑:
我目前的做法是这样的。

let R1 = 3;
let R2 = 10;
let R3 = 3;
let R4 = 2;
let R5 = 4;
let R6 = 4;
let V1 = 5;

let I1 = 0;
let I2 = 0;
let I3 = 0;
let I4 = 0;
let I5 = 0;
let I6 = 0;

const matrix = [
  [-1, 1, 1, 0, 0, 0],
  [1, -1, 0, 0, 0, -1],
  [0, 0, -1, 1, 1, 0],
  [0, -R2, 0, 0, 0, 0],
  [0, 0, 0, -R6, -R5, 0],
  [0, 0, -R1, -R6, 0, -(R3 + R4)]
];
const result = [0, 0, 0, -V1, 0, -V1];

const inverse = math.inv(matrix);
const currents = math.multiply(inverse, result);

console.log(currents);
[I1, I2, I3, I4, I5, I6] = currents;
<script src="https://cdn.jsdelivr.net/npm/mathjs@9.4.4/lib/browser/math.min.js"></script>

问题是,在这个例子中,我得到了错误的解决方案。我把范围缩小到缺少的条件(方程式)。
我有6个电流,这意味着我只能有6个方程来计算逆矩阵。。。但在这种情况下,以及我所拥有的许多其他情况下,6个方程是不够的。
问题是,我需要一台计算机来理解这一点。不是人。所以,我需要找到一种方法来解决这类问题,6个变量,但有6个以上的方程。

8fq7wneg

8fq7wneg1#

经过反复试验,我发现 solve ml矩阵中的函数允许使用n个变量的多个方程。
我还尝试了伪逆的方法,但这也要求矩阵是平方的。

gg58donl

gg58donl2#

这种方法对矩阵进行行缩减,结果得到一个具有未知值的字符串。如果系统有无限分辨率,这将返回简化的方程,以便以后可以进行参数化。
编辑:独立术语位于数组的最后一列。

let eq = [[1, 4, -2, 5, 0],
          [2, 2, 1, -2, 0],
          [0, -1, 3, 1, 0],
          [0, 3, -1, 1, 0],
          [1, -1, 3, 1, 0]];

console.log(rowReduction());

function rowReduction() {
  let state = "compatible";
  for (let column_index = 0; column_index < eq[0].length; column_index++) {
    state = searchIncompability();
    if (state == "compatible") {
      for (let row_index = 0; row_index < eq.length; row_index++) {
        if (row_index != column_index) {
          if (typeof eq[column_index] !== 'undefined' && eq[column_index][column_index] != null) {
            let row = eq[row_index];
            let valueToZero = (-1 * row[column_index]);
            eq[row_index] = row.map(function(n, i) { return n + (valueToZero * eq[column_index][i]); });
          }
        }
      }
    }else return state;
  }
  return evaluateEq();
}

function searchIncompability() {
  let state = "compatible";
  for (let index = 0; index < eq.length; index++) {
    let row = eq[index], indepTerm = row[row.length - 1];
    if (typeof row[index] !== 'undefined') {
      //if matrix has incompability [0, 0, 0, 3]
      if (row.reduce((l, n) => l + Math.abs(n), 0) - Math.abs(indepTerm) == 0 && indepTerm != 0) {
        state = "incompatible";
      } 
      let sumToZero = 0;
      while (row[index] == 0 && sumToZero < eq.length && state == "compatible") {
        if (sumToZero != index) {
          row =  eq[sumToZero].map(function(n, i) { return n + row[i]; });
        }
        sumToZero++;
      }
      if (row[index] != 0)  eq[index] = row.map(function(n) { return n / row[index]; });
    }
   }
   return state;
}

function evaluateEq() {
  let str = "";
  eq.forEach(function a(row, i) {
    //avoid null rows
    if (row.reduce((l, n) => l + Math.abs(n), 0) != 0) {
      row.forEach(function b(e, j) {
        e = e.toFixed(3);                 //decimals after comma
        if (j + 1 == row.length) {        //independent term
          str += " = " + e;
        }else if (e != 0) {
          str += " + ";
          if (e != 1)  str += "(" + e + ")*";
          str += "x[" + j + "]";
        }
      });
      str += "\n";
    }
  });
  return str;
}
gr8qqesn

gr8qqesn3#

如果方程和未知数的数量相等,则可以使用lu分解求解矩阵。
如果方程式的数量大于未知数的数量,则使用最小二乘法。
如果方程的数目小于未知数的数目,则使用奇异值分解。
下面是一个使用r的示例。我确信python、jama和其他库都有svd解算器。我不懂javascript。

相关问题