LoginSignup
phyblas
@phyblas (雛星 φυβλας)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

MATLABでPythonのnp.dotみたいな計算はできないですか?

解決したいこと

[m, n, l]と[l, k]サイズの配列があって、これの内積を計算したいです。

しかし簡単な方法は見つかりません。

dot関数を使ってもエラーです。

発生している問題・エラー

ar1 = rand(5,4,3);
ar2 = rand(3,2);
dot(ar1,ar2)
結果
次を使用中のエラー: dot (行 37)
A と B は同じサイズでなければなりません。

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

tensorprodという関数もあってこれも試してみましたが、違うみたいです。

Pythonだったらnp.dot簡単にできるので、いつもこれを使って慣れています。

import numpy as np

ar1 = np.ones([5,4,3])
ar2 = np.ones([3,2])
ar = np.dot(ar1,ar2)
print(ar.shape) # (5, 4, 2)

同じdotという名前の関数ですが、MATLABのdot関数はPythonほど使い勝手がよくないらしいです。

一応forループを使ったらできなくもないが、これはちょっと面倒です。いい方法とは言い難いですね。

function ar = dot3d(ar1,ar2)
    s1 = size(ar1);
    s2 = size(ar2);
    ar = NaN([s1(1:2) s2(2)]);
    for i = 1:s1(1)
        ar(i,:,:) = reshape(ar1(i,:,:),s1(2:3))*ar2;
    end
end

ar1 = rand(5,4,3);
ar2 = rand(3,2);
ar = dot3d(ar1,ar2);
size(ar) % 5     4     2

ググって答えを探そうとしましたが、答えは全然見つかりません。

この計算は回転行列やアフィン変換などを計算する時にとても重要なはずなのに、MATLABで簡単にできる方法がないなんてあまり信じがたいです。

普段こんな計算をする時にMATLABでどうすれば一番いいですか?

0

2Answer

補足です。
forループを使わないもっと簡単な方法を思いついたのです。

function ar = npdot(ar1,ar2)
    s1 = size(ar1);
    s2 = size(ar2);
    ar = reshape(reshape(ar1,[],s1(end))*ar2,[s1(1:end-1) s2(end)]);
end

ar1 = rand(5,4,3);
ar2 = rand(3,2);
ar = npdot(ar1,ar2);
size(ar) % 5     4     2

それでもやはりまだあまり簡潔ではないので、もっといい方法があったら嬉しいです。

0Like

Comments

  1. 十分簡潔な気がしますが、どこら辺がまだあまりなのでしょうか?

@nak435 さん
返事ありがとうございます。

2度reshape関数を使う必要がありますし、1行で書くことができないので、簡潔とは言いにくいでしょう。

まあ、自分で関数を作っておいたら後でPythonと同じようにすぐ使えるからこれでいいと思います。

ただ、これはよく使われる計算でもあるので、できればMATLAB公式の関数として搭載して欲しいですね。これがないのは正直がっかりしてしまいました。

0Like

Comments

  1. まあ、自分で関数を作っておいたら後でPythonと同じようにすぐ使えるからこれでいいと思います。

    標準に無い限りは、今のが最善と思います。

    ただ、これはよく使われる計算でもあるので、できればMATLAB公式の関数として搭載して欲しいですね。

    何か裏があるのですかね?
    公式のコミュニティで発言してみたらどうですか。

    一旦、解決とするならば、当Q&Aはクローズしていただいて結構です。

  2. @phyblas

    Questioner

    もっといい方法を見つけたので、記事に纏めました。

Your answer might help someone💌