如何从依赖于参数的二维数组中定义一个三维数组?

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

How can I define a 3d array from a 2d array that depends on a parameter?

问题

我有一个具有2个维度的矩阵

```python
M = np.array([[0.5+t, 1, 1],
              [0.5, 0.5, t],
              [0.5, 1-t, 0.5]])

我想计算这个矩阵的一些属性,对于多个不同的$t$值。我可以使用for循环来完成,但我想知道是否有一种方法可以不使用循环来实现。例如,创建一个3D数组,其中数组的每个切片都是包含给定$t$的矩阵M的2D数组。

使用循环的实现方式如下:

import numpy as np

def M(t: float):
    return np.array([[0.5+t, 1, 1], [0.5, 0.5, t], [0.5, 1-t, 0.5]])

t_vec = np.linspace(0, 1, num=100)

norm = np.zeros_like(t_vec)
for i, t in enumerate(t_vec):
    matrix = M(t)
    norm[i] = np.linalg.norm(matrix)

在这种情况下,我想计算矩阵的2范数,并将所有值存储在一个数组中。


<details>
<summary>英文:</summary>

I have a matrix with 2 dimensions

M = np.array([[0.5+t, 1, 1],
[0.5, 0.5, t],
[0.5, 1-t, 0.5]])


I want to compute some properties of this matrix for several values of $t$. I could do it witn a for loop but I was wondering if there&#39;s a way of doing it without a loop. For example creating a 3d array where every slide of that array is a 2d array containg the matrix M for a given t.

The loop implementation will we something like this.

import numpy as np

def M(t: float):
return np.array([[0.5+t, 1, 1], [0.5, 0.5, t], [0.5, 1-t, 0.5]])

t_vec = np.linspace(0, 1, num=100)

norm = np.zeros_like(t_vec)
for i, t in enumerate(t_vec):
matrix = M(t)
norm[i] = np.linalg.norm(matrix)

In this case I wanted to compute the 2 norm of the matrix an store all the values in an array.



</details>


# 答案1
**得分**: 5

M = np.array([[0.5, 1.0, 1.0],
              [0.5, 0.5, 0.0],
              [0.5, 1.0, 0.5]])
t = np.array([[1, 0, 0],
              [0, 0, 1],
              [0, -1, 0]])

然后:

M+t

M+t*2

等等。


或者,以向量方式:

t_vec = np.linspace(0, 1, num=100)

out = M+t*t_vec[:,None,None]

norm = np.linalg.norm(M, axis=(1, 2))


<details>
<summary>英文:</summary>

I would recommend to use 2 arrays, one for M, one for `t`:

M = np.array([[0.5, 1.0, 1.0],
[0.5, 0.5, 0.0],
[0.5, 1.0, 0.5]])
t = np.array([[1, 0, 0],
[0, 0, 1],
[0, -1, 0]])

Then:

M+t

M+t*2

etc.

Or, in a vectorial way:

t_vec = np.linspace(0, 1, num=100)

out = M+t*t_vec[:,None,None]

norm = np.linalg.norm(M, axis=(1, 2))


</details>



# 答案2
**得分**: 3

你可以创建没有`t`值的基本矩阵,然后通过要使用的值与`t`值的 'mask' 相乘来添加`t`值。例如:

```python
M_base = np.array(
    [[0.5, 1,   1  ],
     [0.5, 0.5, 0  ],
     [0.5, 1,   0.5]])
t = np.array(
    [[ 1,  0,  0],
     [ 0,  0,  1],
     [ 0, -1,  0]])

t_values = np.linspace(0, 1, num=100)

M = M_base + t*t_values[:, np.newaxis, np.newaxis]

norm = np.linalg.norm(M, axis=(1, 2))
英文:

You can create base matrix without t values and then add t values 'mask' multiplied by the values you want to use. For example:

M_base = np.array(
    [[0.5, 1,   1  ],
     [0.5, 0.5, 0  ],
     [0.5, 1,   0.5]])
t = np.array(
    [[ 1,  0,  0],
     [ 0,  0,  1],
     [ 0, -1,  0]])

t_values = np.linspace(0, 1, num=100)

M = M_base + t*t_values[:, np.newaxis, np.newaxis]

norm = np.linalg.norm(M, axis=(1, 2))

答案3

得分: 1

The others answers do what you want to do. I put this answer only to have a faster way.

Let's say you have two matrix:

N = np.array([[0.5, 1.0, 1.0],
              [0.5, 0.5, 0.0],
              [0.5, 1.0, 0.5]])
T = np.array([[1,  0, 0],
              [0,  0, 1],
              [0, -1, 0]])

Then, for given t, M = N + t * T.

The numpy.linalg.norm(M) can be described as numpy.sqrt(numpy.sum(M**2)). Therefore, to compute the norm for many t I would do:

t_vec = np.linspace(0, 1, 100)
# Once M**2 = (N+t*T)**2 = N**2 + 2*t * N*T + t**2 * T**2
# norm(M) = np.sqrt(M**2) = np.sqrt(N**2 + 2*t * N*T + t**2 * T**2)
sumN2 = np.linalg.norm(N)**2
sumT2 = np.linalg.norm(T)**2
sumNT = np.sum(N*T)
norm = np.sqrt(sumN2 + 2*t_vec * sumNT + t_vec**2 * sumT2)
英文:

The others answers do what you want to do. I put this answer only to have a faster way.

Let's say you have two matrix:

N = np.array([[0.5, 1.0, 1.0],
              [0.5, 0.5, 0.0],
              [0.5, 1.0, 0.5]])
T = np.array([[1,  0, 0],
              [0,  0, 1],
              [0, -1, 0]])

Then, for given t, M = N + t * T.

The numpy.linalg.norm(M) can be described as numpy.sqrt(numpy.sum(M**2)). Therefore, to compute the norm for many t I would do:

t_vec = np.linspace(0, 1, 100)
# Once M**2 = (N+t*T)**2 = N**2 + 2*t * N*T + t**2 * T**2
# norm(M) = np.sqrt(M**2) = np.sqrt(N**2 + 2*t * N*T + t**2 * T**2)
sumN2 = np.linalg.norm(N)**2
sumT2 = np.linalg.norm(T)**2
sumNT = np.sum(N*T)
norm = np.sqrt(sumN2 + 2*t_vec * sumNT + t_vec**2 * sumT2)

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

发表评论

匿名网友

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

确定