我必须在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;
谢谢。
答案 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在装有tic
和toc
的笔记本电脑上测量的,因此您可能会获得不同的值,甚至是不同的比率。但是我认为时间差足够大,可以尝试一下。