简体   繁体   English

从 Numpy Meshgrid 生成 Position 向量

[英]Generating Position Vectors from Numpy Meshgrid

I'll try to explain my issue here without going into too much detail on the actual application so that we can stay grounded in the code.我将尝试在这里解释我的问题,而不会对实际应用程序进行太多详细说明,以便我们能够以代码为基础。 Basically, I need to do operations to a vector field.基本上,我需要对向量场进行操作。 My first step is to generate the field as我的第一步是将字段生成为

x,y,z = np.meshgrid(np.linspace(-5,5,10),np.linspace(-5,5,10),np.linspace(-5,5,10))

Keep in mind that this is a generalized case, in the program, the bounds of the vector field are not all the same.请记住,这是一个普遍的情况,在程序中,向量场的边界并不完全相同。 In the general run of things, I would expect to say something along the lines of在一般情况下,我希望能说一些类似的东西

u,v,w = f(x,y,z) . u,v,w = f(x,y,z)

Unfortunately, this case requires so more difficult operations.不幸的是,这种情况需要如此困难的操作。 I need to use a formula similar to我需要使用类似于

Biot Savart 方程的简化版本 where the vector r is defined in the program as np.array([xgrid-x,ygrid-y,zgrid-z]) divided by its own norm.其中向量 r 在程序中定义为np.array([xgrid-x,ygrid-y,zgrid-z])除以其自身的范数。 Basically, this is a vector pointing from every point in space to the position (x,y,z)基本上,这是一个从空间中的每个点指向 position (x,y,z) 的向量

Now Numpy has implemented a cross product function using np.cross() , but I can't seem to create a "meshgrid of vectors" like I need.现在 Numpy 已经使用np.cross()实现了叉积 function ,但我似乎无法像我需要的那样创建“向量网格”。 I have a lambda function that is essentially我有一个 lambda function 本质上是

xgrid,ygrid,zgrid=np.meshgrid(np.linspace(-5,5,10),np.linspace(-5,5,10),np.linspace(-5,5,10)) B(x,y,z) = lambda x,y,z: np.cross(v,np.array([xgrid-x,ygrid-y,zgrid-z]))

Now the array v is imported from another class and seems to work just fine, but the second array, np.array([xgrid-x,ygrid-y,zgrid-z]) is not a proper shape because it is a "vector of meshgrids" instead of a "meshgrid of vectors".现在数组v是从另一个 class 导入的,似乎工作得很好,但是第二个数组np.array([xgrid-x,ygrid-y,zgrid-z])不是正确的形状,因为它是一个“向量网格”而不是“矢量网格”。 My big issue is that I cannot seem to find a method by which to format the meshgrid in such a way that the np.cross() function can use the position vector.我的大问题是我似乎找不到一种方法来格式化网格网格,使得np.cross() function 可以使用 position 向量。 Is there a way to do this?有没有办法做到这一点?

Originally I thought that I could do something along the lines of:最初我认为我可以按照以下方式做一些事情:

x,y,z = np.meshgrid(np.linspace(-2,2,5),np.linspace(-2,2,5),np.linspace(-2,2,5)) A = np.array([x,y,z]) cross_result = np.cross(np.array(v),A)

This, however, returns the following error, which I cannot seem to circumvent:但是,这会返回以下错误,我似乎无法避免:

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python27\lib\site-packages\numpy\core\numeric.py", line 1682, in cross raise ValueError(msg) ValueError: incompatible dimensions for cross product (dimension must be 2 or 3)

There's a work around with reshape and broadcasting:有一个关于reshape和广播的工作:

A = np.array([x_grid, y_grid, z_grid])
# A.shape == (3,5,5,5)

def B(v, p):
    '''
    v.shape = (3,)
    p.shape = (3,) 
    '''
    shape = A.shape

    Ap = A.reshape(3,-1) - p[:,None]

    return np.cross(v[None,:], Ap.reshape(3,-1).T).reshape(shape)

print(B(v,p).shape)
# (3, 5, 5, 5)

I think your original attempt only lacks the specification of the axis along which the cross product should be executed.我认为您最初的尝试仅缺少应执行叉积的轴的规范。

x, y, z = np.meshgrid(np.linspace(-2, 2, 5),np.linspace(-2, 2, 5), np.linspace(-2, 2, 5))
A = np.array([x, y, z])
cross_result = np.cross(np.array(v), A, axis=0)

I tested this with the code below.我用下面的代码对此进行了测试。 As an alternative to np.array([x, y, z]) , you can also use np.stack(x, y, z, axis=0) , which clearly shows along which axis the meshgrids are stacked to form a meshgrid of vectors, the vectors being aligned with axis 0. I also printed the shape each time and used random input for testing.作为np.array([x, y, z])的替代方法,您还可以使用np.stack(x, y, z, axis=0) ,它清楚地显示了网格网格沿着哪个轴堆叠以形成网格网格向量,向量与轴 0 对齐。我还每次都打印形状并使用随机输入进行测试。 In the test, the output of the formula is compared at a random index to the cross product of the input-vector at the same index with vector v.在测试中,将公式的output在随机索引处与输入向量与向量v在相同索引处的叉积进行比较。

import numpy as np 

x, y, z = np.meshgrid(np.linspace(-5, 5, 10), np.linspace(-5, 5, 10), np.linspace(-5, 5, 10))
p = np.random.rand(3) # random reference point
A = np.array([x-p[0], y-p[1], z-p[2]]) # vectors from positions to reference
A_bis = np.stack((x-p[0], y-p[1], z-p[2]), axis=0) 
print(f"A equals A_bis? {np.allclose(A, A_bis)}") # the two methods of stacking yield the same

v = -1 + 2*np.random.rand(3) # random vector v

B = np.cross(v, A, axis=0) # cross-product for all points along correct axis
print(f"Shape of v: {v.shape}")
print(f"Shape of A: {A.shape}")
print(f"Shape of B: {B.shape}")


print("\nComparison for random locations: ")
point = np.random.randint(0, 9, 3) # generate random multi-index
a = A[:, point[0], point[1], point[2]] # look up input-vector corresponding to index
b = B[:, point[0], point[1], point[2]] # look up output-vector corresponding to index
print(f"A[:, {point[0]}, {point[1]}, {point[2]}] = {a}")
print(f"v = {v}")
print(f"Cross-product as v x a:         {np.cross(v, a)}")
print(f"Cross-product from B (= v x A): {b}")

The resulting output looks like:生成的 output 如下所示:

A equals A_bis? True
Shape of v: (3,)
Shape of A: (3, 10, 10, 10)
Shape of B: (3, 10, 10, 10)

Comparison for random locations: 
A[:, 8, 1, 1] = [-4.03607312  3.72661831 -4.87453077]
v = [-0.90817859  0.10110274 -0.17848181]
Cross-product as v x a:         [ 0.17230515 -3.70657882 -2.97637688]
Cross-product from B (= v x A): [ 0.17230515 -3.70657882 -2.97637688]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM