簡體   English   中英

為具有不同尺寸的 arrays 在 C++ 中實現 numpy.tensordot 代碼

[英]Implementing numpy.tensordot code in C++ for arrays having different dimensions

我正在嘗試實現 numpy.tensordot,例如 C++ 中兩個不同矩陣的乘積總和。 盡管我了解相同維度的 arrays 的實現,但我無法弄清楚將大小為3 * 3的二維數組與大小為3 * 600 * 600的數組相乘的方法。 結果數組的大小應為3 * 600 * 600

為了理解直覺,我嘗試在筆和紙上完成3 * 3 * 33 * 3 arrays ,但這會導致結果不一致。

我的代碼的示例 numpy 版本如下:

import numpy as np
R = np.arange(9).reshape(3,3)
XYZ = np.arange(3*600*600).reshape*3, 600, 600)

result = np.tensordot(R, XYZ, axes = 1)   

為方便起見,我附上了numpy.tensordot文檔的鏈接。

In [129]: R = np.arange(9).reshape(3,3)
     ...: XYZ = np.arange(3*600*600).reshape(3, 600, 600)

tensordot有 2 個 styles 的axes ,標量和元組:

In [130]: result = np.tensordot(R, XYZ, axes=1)
In [131]: result.shape
Out[131]: (3, 600, 600)

einsum等價物是:

In [132]: res1 = np.einsum('ij,jkl->ikl',R, XYZ)
In [133]: res1.shape
Out[133]: (3, 600, 600)
In [134]: np.allclose(result, res1)
Out[134]: True

和元組軸等效:

In [135]: res2 = np.tensordot(R, XYZ, axes=(1,0))
In [136]: res2.shape
Out[136]: (3, 600, 600)
In [137]: np.allclose(result, res2)
Out[137]: True

我認為元組軸樣式是原始的,並且在此基礎上添加了 integer 軸。 前段時間我研究了整數大小寫如何轉換為元組輸入,但我忘記了細節。

無論如何,產品總和維度是R的最后一個和XYZ的第一個。

另一種方法是將元素與廣播相乘,然后求和:

In [139]: res4=(R[:,:,None,None]*XYZ[None,:,:,:]).sum(axis=1)
In [140]: np.allclose(result, res4)
Out[140]: True

通過將XYZ的最后一個維度壓縮為 1,我們得到傳統的dot積,其中積和是第一個的最后一個,第二個到第二個的最后一個:

In [141]: res5 = (R@XYZ.reshape(3,-1)).reshape(3,600,600)
In [142]: np.allclose(result, res5)
Out[142]: True
In [143]: res6 = (R.dot(XYZ.reshape(3,-1))).reshape(3,600,600)
In [144]: np.allclose(result, res6)
Out[144]: True

我相信tensordot正在有效地做 [143]。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM