在不使用repmat的情况下以4维重复向量

时间:2019-04-05 19:01:20

标签: matlab

我必须在4维上重复一个向量,并且我使用repmat函数来执行此操作,但是这要花费大量时间。那么,如何在不使用repmat的情况下实现它呢?

这是我使用的代码示例。

A = rand(1, 240); %The vector I want to replicate

B = repmat(A, 240, 1, 180, 3); %Here I get a matrix of size 240 240 180 3

这是我调用repmat的函数。该函数基本上实现了三个嵌套的总和:

function gr = g_transformation3(f, c, delta)
%f --> image to be transformed
%c --> control points matrix
%delta --> spacing in pixels, between the control points

[X, Y, Z] = size(f);
%[n, m] = size(c);

x0 = 0:(X - 1);
y0 = 0:(Y - 1);
z0 = 0:(Z - 1);

x1 = delta:(X + delta - 1);
y1 = delta:(Y + delta - 1);
z1 = delta:(Z + delta - 1);

x2 = (2*delta):(X + 2*delta - 1);
y2 = (2*delta):(Y + 2*delta - 1);
z2 = (2*delta):(Z + 2*delta - 1);

x3 = (3*delta):(X + 3*delta - 1);
y3 = (3*delta):(Y + 3*delta - 1);
z3 = (3*delta):(Z + 3*delta - 1);

i0 = floor(x0./delta) + 1;
j0 = floor(y0./delta) + 1;
k0 = floor(z0./delta) + 1;

i1 = floor(x1./delta) + 1;
j1 = floor(y1./delta) + 1;
k1 = floor(z1./delta) + 1;

i2 = floor(x2./delta) + 1;
j2 = floor(y2./delta) + 1;
k2 = floor(z2./delta) + 1;

i3 = floor(x3./delta) + 1;
j3 = floor(y3./delta) + 1;
k3 = floor(z3./delta) + 1;

u = x0./delta - floor(x0./delta);
v = y0./delta - floor(y0./delta);
w = z0./delta - floor(z0./delta);

Bu = zeros(4, numel(u));
Bv = zeros(4, numel(v));
Bw = zeros(4, numel(w));

%Computing the vector of B-splines
Bu(1, :) = ((1 - u).^3)/6;
Bu(2, :) = (3*u.^3 - 6*u.^2 + 4)/6;
Bu(3, :) = (-3*u.^3 + 3*u.^2 + 3*u + 1)/6;
Bu(4, :) = (u.^3)/6;

Bv(1, :) = ((1 - v).^3)/6;
Bv(2, :) = (3*v.^3 - 6*v.^2 + 4)/6;
Bv(3, :) = (-3*v.^3 + 3*v.^2 + 3*v + 1)/6;
Bv(4, :) = (v.^3)/6;

Bw(1, :) = ((1 - w).^3)/6;
Bw(2, :) = (3*w.^3 - 6*w.^2 + 4)/6;
Bw(3, :) = (-3*w.^3 + 3*w.^2 + 3*w + 1)/6;
Bw(4, :) = (w.^3)/6;

T00 = repmat(Bu(1, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i0, j0, k0, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i0, j1, k0, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i0, j2, k0, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i0, j3, k0, :));

T01 = repmat(Bu(2, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i1, j0, k0, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i1, j1, k0, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i1, j2, k0, :) + ... 
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i1, j3, k0, :));

T02 = repmat(Bu(3, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i2, j0, k0, :) + ... 
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i2, j1, k0, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i2, j2, k0, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i2, j3, k0, :));

T03 = repmat(Bu(4, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i3, j0, k0, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i3, j1, k0, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i3, j2, k0, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i3, j3, k0, :));

matr = reshape(Bw(1, :), [1 1 Z]);
T0 = repmat(matr, X, X, 1, 3).*(T00 + T01 + T02 + T03);

clear T00 T01 T02 T03;

T10 = repmat(Bu(1, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i0, j0, k1, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i0, j1, k1, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i0, j2, k1, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i0, j3, k1, :));

T11 = repmat(Bu(2, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i1, j0, k1, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i1, j1, k1, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i1, j2, k1, :) + ... 
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i1, j3, k1, :));

T12 = repmat(Bu(3, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i2, j0, k1, :) + ... 
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i2, j1, k1, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i2, j2, k1, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i2, j3, k1, :));

T13 = repmat(Bu(4, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i3, j0, k1, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i3, j1, k1, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i3, j2, k1, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i3, j3, k1, :));

matr = reshape(Bw(2, :), [1 1 Z]);
T1 = repmat(matr, X, X, 1, 3).*(T10 + T11 + T12 + T13);

clear T10 T11 T12 T13;

T20 = repmat(Bu(1, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i0, j0, k2, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i0, j1, k2, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i0, j2, k2, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i0, j3, k2, :));

T21 = repmat(Bu(2, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i1, j0, k2, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i1, j1, k2, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i1, j2, k2, :) + ... 
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i1, j3, k2, :));

T22 = repmat(Bu(3, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i2, j0, k2, :) + ... 
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i2, j1, k2, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i2, j2, k2, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i2, j3, k2, :));

T23 = repmat(Bu(4, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i3, j0, k2, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i3, j1, k2, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i3, j2, k2, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i3, j3, k2, :));                              

matr = reshape(Bw(3, :), [1 1 Z]);
T2 = repmat(matr, X, X, 1, 3).*(T20 + T21 + T22 + T23);

clear T20 T21 T22 T23;

T30 = repmat(Bu(1, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i0, j0, k3, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i0, j1, k3, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i0, j2, k3, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i0, j3, k3, :));

T31 = repmat(Bu(2, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i1, j0, k3, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i1, j1, k3, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i1, j2, k3, :) + ... 
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i1, j3, k3, :));

T32 = repmat(Bu(3, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i2, j0, k3, :) + ... 
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i2, j1, k3, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i2, j2, k3, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i2, j3, k3, :));

T33 = repmat(Bu(4, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i3, j0, k3, :) + ...
                                  repmat(Bv(2, :), X, 1, Z, 3).*c(i3, j1, k3, :) + ... 
                                  repmat(Bv(3, :), X, 1, Z, 3).*c(i3, j2, k3, :) + ...
                                  repmat(Bv(4, :), X, 1, Z, 3).*c(i3, j3, k3, :));

matr = reshape(Bw(4, :), [1 1 Z]);
T3 = repmat(matr, X, X, 1, 3).*(T30 + T31 + T32 + T33);

clear T30 T31 T32 T33;

gr = T0 + T1 + T2 + T3;

谢谢。

2 个答案:

答案 0 :(得分:2)

如果您具有MATLAB R2016b或更高版本,则可以直接实现所有这些操作,而无需进行任何repmat调用:

T00 = repmat(Bu(1, :)', 1, Y, Z, 3).*(repmat(Bv(1, :), X, 1, Z, 3).*c(i0, j0, k0, :) + ...
                                      repmat(Bv(2, :), X, 1, Z, 3).*c(i0, j1, k0, :) + ... 
                                      repmat(Bv(3, :), X, 1, Z, 3).*c(i0, j2, k0, :) + ...
                                      repmat(Bv(4, :), X, 1, Z, 3).*c(i0, j3, k0, :));

相同
T00 = Bu(1, :).' .* (Bv(1, :) .* c(i0, j0, k0, :) + ...
                     Bv(2, :) .* c(i0, j1, k0, :) + ... 
                     Bv(3, :) .* c(i0, j2, k0, :) + ...
                     Bv(4, :) .* c(i0, j3, k0, :));

如果您使用的是旧版本的MATLAB,则可以使用bsxfun来实现每个这些运算符。不过,这看起来会更加难看。


请注意,我将'替换为.'。前者是复杂的共轭转置,可能不是您打算使用的。要更改矢量的方向,应始终首选.'。对于实值矩阵,它们是相同的,但是如果将来将来使用复杂数据,那么习惯于正确的运算符将防止出现许多难以发现的错误。

答案 1 :(得分:1)

直接按元素操作怎么样?使用最新的Matlab版本,它可以为您完成所有调整:

B = repmat(A, 240, 1, 180, 3);  % Elapsed time is 0.264423 seconds.
C = A.*ones(240,1,180,3);       % Elapsed time is 0.027216 seconds.

免责声明:时间是使用R2019a在装有tictoc的笔记本电脑上测量的,因此您可能会获得不同的值,甚至是不同的比率。但是我认为时间差足够大,可以尝试一下。