numpy线性代数求解器

huangapple go评论74阅读模式
英文:

numpy linear algebra solver

问题

以下是您提供的内容的翻译部分:

让我直接谈正题,描述一下我试图在Python中解决的简单数学问题:

我有4个n×n的刚度矩阵系数,分别是s11、s12、s21、s22,因此我试图解决的代数方程组如下所示:

[s11]{u}+[s12]{v} = {fx}
[s22]{v}+[s21]{u} = {fy}

其中u和v是未知向量在x和y方向上的nx1分量。即总向量将是g = sqrt(u^2+v^2)。而fx和fy是给定的“力”向量的nx1 x和y分量。

因此,任务相对简单,但我在使用Python中的numpy实现高斯消元时遇到了困难。我最早尝试使用的一种方法是将一切都重写为以下格式:

s = [ [[s11], [s12]],
[[s21], [s22]] ]
f = [ [fx],
[fy] ]
使得s为2nx2n,f为2nx1。它们的组装方式如下:

s1 = np.concatenate((s11, s12), axis=1)
s2 = np.concatenate((s21, s22), axis=1)
s = np.concatenate((s1, s2), axis=0)
f = np.concatenate((fx, fy), axis=0)

但是,当我尝试用以下代码解决这个系统时:

u = np.linalg.solve(s, f)

我期望得到2nx1的未知向量u(其中第一组n个元素是x分量,第二组是y分量),但我得到以下错误:

Traceback (most recent call last):
File "/home/art/PycharmProjects/Cavern/main.py", line 204, in
u = np.linalg.solve(s, f)
File "<array_function internals>", line 5, in solve
File "/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 399, in solve
r = gufunc(a, b, signature=signature, extobj=extobj)
File "/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 97, in _raise_linalgerror_singular
raise LinAlgError("Singular matrix")
numpy.linalg.LinAlgError: Singular matrix

然后,我尝试了另一种有争议的方法,可以总结如下:

s1 = s11 + s21
s2 = s12 + s22
s = np.concatenate((s1, s2), axis=1)
f = fx + fy

使得s现在为nx2n,f为nx1。然后再次尝试使用高斯消元如下:

u = np.linalg.solve(s, f)

再次,我期望得到2nx1的未知向量,但现在出现以下错误:

Traceback (most recent call last):
File "/home/art/PycharmProjects/Cavern/main.py", line 204, in
u = np.linalg.solve(s, f)
File "<array_function internals>", line 5, in solve
File "/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 386, in solve
_assert_stacked_square(a)
File "/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 213, in _assert_stacked_square
raise LinAlgError('Last 2 dimensions of the array must be square')
numpy.linalg.LinAlgError: Last 2 dimensions of the array must be square

因此,我渴望寻求您的帮助。任何协助/提示将不胜感激。是的,也许提到这个不重要,但整个问题是关于将我的Matlab代码转移到Python。在Matlab中,该过程如下:

S1 = [S11, S12]; S2 = [S21, S22];
U1 = S1 \ fx; U2 = S2 \ fy;
U = U1 + U2;
u(:,1) = U(1:nnodes);
v(:,1) = U(nnodes+1:end);

反斜杠在这里代表高斯消元。

英文:

Let me get straight to the deal and describe the simple math problem I'm trying to solve in python:

I have 4 nxn stiffness matrices of coefficients, namely s11, s12, s21, s22, such that the system of algebraic equations I am trying to solve looks like the following:

[s11]*{u}+[s12]*{v} = {fx}
[s22]*{v}+[s21]*{u} = {fy}

where u and v - are nx1 components of unknown vector in the x and y directions. I.e. total vector will be g = sqrt(u^2+v^2). And fx and fy - are the nx1 x and y components of a given say "forces" vector.

So the task is relatively easy, but I'm stuck in implementing the gaussian elimination using the numpy in python. One of the first and most obvious methods I was trying to use, was rewriting everything in the following format:

s = [ [[s11], [s12]],
      [[s21], [s22]] ]
f = [ [fx],
      [fy] ]

Such that s is 2nx2n and f is 2nx1. The way of assembling them is the following:

s1 = np.concatenate((s11, s12), axis=1)
s2 = np.concatenate((s21, s22), axis=1)
s = np.concatenate((s1, s2), axis=0)
f = np.concatenate((fx, fy), axis=0)

But then, when I try to solve the system with

u = np.linalg.solve(s, f)

I expect to get 2nx1 vector of unknowns u (where the first set of n elements are the x components and second set is y), but I get the following error:

Traceback (most recent call last):
File &quot;/home/art/PycharmProjects/Cavern/main.py&quot;, line 204, in &lt;module&gt;
u = np.linalg.solve(s, f)
File &quot;&lt;__array_function__ internals&gt;&quot;, line 5, in solve
File &quot;/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py&quot;, line 399, in solve
r = gufunc(a, b, signature=signature, extobj=extobj)
File &quot;/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py&quot;, line 97, in _raise_linalgerror_singular
raise LinAlgError(&quot;Singular matrix&quot;)
numpy.linalg.LinAlgError: Singular matrix

Then I have tried another controversial way, which can be summarized as follows:

s1 = s11 + s21
s2 = s12 + s22
s = np.concatenate((s1, s2), axis=1)
f = fx + fy

Such that s is now nx2n, f is nx1. Then again, I'm trying to use the gaussian elimination as follows:

u = np.linalg.solve(s, f)

Again I expect to get 2nx1 vector of unknowns, but I get the error which now is the following:

Traceback (most recent call last):
File &quot;/home/art/PycharmProjects/Cavern/main.py&quot;, line 204, in &lt;module&gt;
u = np.linalg.solve(s, f)
File &quot;&lt;__array_function__ internals&gt;&quot;, line 5, in solve
File &quot;/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py&quot;, line 386, in solve
_assert_stacked_square(a)
File &quot;/home/art/.pyenv/versions/test380/lib/python3.8/site-packages/numpy/linalg/linalg.py&quot;, line 213, in _assert_stacked_square
raise LinAlgError(&#39;Last 2 dimensions of the array must be square&#39;)
numpy.linalg.LinAlgError: Last 2 dimensions of the array must be square

Therefore I keen to seek for your help. Any assistance/hints would be much appreciated. And yes, mb it's not important to mention, but the whole thing is about transferring my code from Matlab to python. In the Matlab the procedure is the following:

S1 = [S11, S12]; S2 = [S21, S22];
U1 = S1 \ fx; U2 = S2 \ fy;
U = U1 + U2;
u(:,1) = U(1:nnodes);
v(:,1) = U(nnodes+1:end);

Backslash stands for the gaussian elimination here.

答案1

得分: 1

为什么要使用np.concatenate,如果sf系数是标量?您可以直接将它们转换为numpy数组(或任何有序序列),然后在它们上使用numpy.linalg.solve()

s1 = [s11, s12]
s2 = [s21, s22]
s = np.column_stack((s1, s2))
f = [s11, s12]

u = np.linalg.solve(s, f)

请注意,在这种情况下,1D列表与具有nx1(或1xn)向量的效果相同。向量的方向对于np.linalg.solve()函数无关紧要。

英文:

Why use np.concatenate if the s and f coefficients are scalars? You can directly make them into numpy arrays (or any ordered sequence) and use numpy.linalg.solve() on them.

s1 = [s11, s12]
s2 = [s21, s22]
s = np.column_stack((s1, s2))
f = [s11, s12]

u = np.linalg.solve(s, f)

Note in this case, the 1D list is the same as having a nx1 (or 1xn) vector. The directionality of the vector does not matter for the np.linalg.solve() function.

huangapple
  • 本文由 发表于 2020年1月3日 20:44:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/59578880.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定