Matlab 高维矩阵与向量的点乘 (Permute)
今天遇到一个问题,如何用一个n维的向量点乘一个 m × k × n m\times k\times n m×k×n 的矩阵, 并避免用循环。Matlab矩阵实验室名不虚传,通过permute这个命令可以有效解决这个问题。因此记录下来,以备不时之需 (几年前遇到过同样的问题,但是没做笔记,所以这次一定要记下来)。
a = [1,2,3]; % 这里需要注意Matlab是按列存储的;
test = repmat(a,3,1,3); % 把向量a复制成一个3*3*3的矩阵;
查看test矩阵
t e s t ( : , : , 1 ) = [ 1 2 3 1 2 3 1 2 3 ] , t e s t ( : , : , 2 ) = [ 1 2 3 1 2 3 1 2 3 ] , t e s t ( : , : , 3 ) = [ 1 2 3 1 2 3 1 2 3 ] test\left( :,: ,1\right) =\left[ \begin{matrix} 1& 2& 3\\ 1& 2& 3\\ 1& 2& 3\end{matrix} \right],test\left( :,: ,2\right) =\left[ \begin{matrix} 1& 2& 3\\ 1& 2& 3\\ 1& 2& 3\end{matrix} \right], test\left( :,: ,3\right) =\left[ \begin{matrix} 1& 2& 3\\ 1& 2& 3\\ 1& 2& 3\end{matrix} \right] test(:,:,1)=⎣⎡111222333⎦⎤,test(:,:,2)=⎣⎡111222333⎦⎤,test(:,:,3)=⎣⎡111222333⎦⎤
我想要的结果
t e s t z ( : , : , 1 ) = [ 1 2 3 1 2 3 1 2 3 ] , t e s t z ( : , : , 2 ) = [ 10 20 30 10 20 30 10 20 30 ] , t e s t z ( : , : , 3 ) = [ 100 200 300 100 200 300 100 200 300 ] testz\left( :,: ,1\right) =\left[ \begin{matrix} 1& 2& 3\\ 1& 2& 3\\ 1& 2& 3\end{matrix} \right],testz\left( :,: ,2\right) =\left[ \begin{matrix} 10& 20& 30\\ 10& 20& 30\\ 10& 20& 30\end{matrix} \right], testz\left( :,: ,3\right) =\left[ \begin{matrix} 100& 200& 300\\ 100& 200& 300\\ 100& 200& 300\end{matrix} \right] testz(:,:,1)=⎣⎡111222333⎦⎤,testz(:,:,2)=⎣⎡101010202020303030⎦⎤,testz(:,:,3)=⎣⎡100100100200200200300300300⎦⎤
实现的方法
z = [1,10,100]; % 定义一个向量z
test_z = permute(z,[1,3,2]); %permute 用于求三维矩阵的转置
% Alternatively
% test_z = reshape([1,10,100],[1,1,3])
对于二维矩阵的转置,我们通常用 ’ ;但是对于高维向量,需要使用permute, 上面的命令表示第二个维度的数据(列)放到第三个维度,所以我们猜测test_z会是一个 1 × 1 × 3 1\times 1\times 3 1×1×3的这么一个矩阵,查看test_z的结果
t e s t z ( : , : , 1 ) = 1 ; t e s t z ( : , : , 2 ) = 10 ; t e s t z ( : , : , 3 ) = 100 ; test_z\left( :,: ,1\right) = 1;test_z\left( :,: ,2\right) = 10; test_z\left( :,: ,3\right)=100; testz(:,:,1)=1;testz(:,:,2)=10;testz(:,:,3)=100;
如你所愿,最后我们有
testz = test_z.*test; % 得到我想要的效果
注意,如果是对行(第一维度)点乘,只需要:
z.* test
t e s t z ( : , : , 1 ) = [ 1 2 3 10 20 30 100 200 300 ] , t e s t z ( : , : , 2 ) = [ 1 2 3 10 20 30 100 200 300 ] , t e s t z ( : , : , 3 ) = [ 1 2 3 10 20 30 100 200 300 ] testz\left( :,: ,1\right) =\left[ \begin{matrix} 1& 2& 3\\ 10& 20& 30\\ 100& 200& 300\end{matrix} \right],testz\left( :,: ,2\right) =\left[ \begin{matrix} 1& 2& 3\\ 10& 20& 30\\ 100& 200& 300\end{matrix} \right], testz\left( :,: ,3\right) =\left[ \begin{matrix} 1& 2& 3\\ 10& 20& 30\\ 100& 200& 300\end{matrix} \right] testz(:,:,1)=⎣⎡110100220200330300⎦⎤,testz(:,:,2)=⎣⎡110100220200330300⎦⎤,testz(:,:,3)=⎣⎡110100220200330300⎦⎤
如果对列进行点乘,需要进行行列转置
z'.*test
t e s t z ( : , : , 1 ) = [ 1 20 300 1 20 300 1 20 300 ] , t e s t z ( : , : , 2 ) = [ 1 20 300 1 20 300 1 20 300 ] , t e s t z ( : , : , 3 ) = [ 1 20 300 1 20 300 1 20 300 ] testz\left( :,: ,1\right) =\left[ \begin{matrix} 1& 20& 300\\ 1& 20& 300\\ 1& 20& 300\end{matrix} \right],testz\left( :,: ,2\right) =\left[ \begin{matrix} 1& 20& 300\\ 1& 20& 300\\ 1& 20& 300\end{matrix} \right], testz\left( :,: ,3\right) =\left[ \begin{matrix} 1& 20& 300\\ 1& 20& 300\\ 1& 20& 300\end{matrix} \right] testz(:,:,1)=⎣⎡111202020300300300⎦⎤,testz(:,:,2)=⎣⎡111202020300300300⎦⎤,testz(:,:,3)=⎣⎡111202020300300300⎦⎤
虽然很简单,但是这么简单的问题我也是花了大概二十分钟去思考,再花二十分钟做笔记,希望以后可以帮助自己和有缘人。能遇到同样的变态问题,还看到我的博客,说明都是猿粪啊,既然这么有缘,你舍得不给我点赞吗?哈哈
更多精彩内容见作者的个人博客主页:(https://canbulajiji.github.io)