Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Matlab:创建行与向量相同的矩阵。使用repmat()或乘以一()_Arrays_Matlab_Matrix - Fatal编程技术网

Arrays Matlab:创建行与向量相同的矩阵。使用repmat()或乘以一()

Arrays Matlab:创建行与向量相同的矩阵。使用repmat()或乘以一(),arrays,matlab,matrix,Arrays,Matlab,Matrix,我想从一个向量创建一个矩阵,通过将向量连接到它自身n次。因此,如果我的向量是mx1,那么我的矩阵将是mxn,矩阵的每一列将等于向量 以下哪一项是最好/正确的方法,或者我不知道还有更好的方法 matrix = repmat(vector, 1, n); matrix = vector * ones(1, n); 谢谢如果两种方法都能为您提供所需的输出,那么它们都是正确的 但是,根据您声明向量的方式,使用repmat可能会得到不正确的结果,如果使用ones,则会发现这些结果。举个例子 >&g

我想从一个向量创建一个矩阵,通过将向量连接到它自身n次。因此,如果我的向量是
mx1
,那么我的矩阵将是
mxn
,矩阵的每一列将等于向量

以下哪一项是最好/正确的方法,或者我不知道还有更好的方法

matrix = repmat(vector, 1, n);
matrix = vector * ones(1, n);

谢谢

如果两种方法都能为您提供所需的输出,那么它们都是正确的

但是,根据您声明向量的方式,使用
repmat
可能会得到不正确的结果,如果使用
ones
,则会发现这些结果。举个例子

>> v = 1:10;
>> m = v * ones(1, n)
Error using  * 
Inner matrix dimensions must agree.
>> m = repmat(v, 1, n)
m =

  Columns 1 through 22

     1     2     3     4     5     6     7     8     9    10     1     2     3     4     5     6     7     8     9    10     1     2

  Columns 23 through 44

     3     4     5     6     7     8     9    10     1     2     3     4     5     6     7     8     9    10     1     2     3     4

  Columns 45 through 50

     5     6     7     8     9    10
ones
提供一个错误,让您知道您没有做正确的事情,但是
repmat
没有。虽然此示例可以正确使用
repmat
one

>> v = (1:10).';
>> m = v * ones(1, n)
m =

     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3
     4     4     4     4     4
     5     5     5     5     5
     6     6     6     6     6
     7     7     7     7     7
     8     8     8     8     8
     9     9     9     9     9
    10    10    10    10    10
>> m = repmat(v, 1, n)
m =

     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3
     4     4     4     4     4
     5     5     5     5     5
     6     6     6     6     6
     7     7     7     7     7
     8     8     8     8     8
     9     9     9     9     9
    10    10    10    10    10

两者都是正确的,但对于多维矩阵复制而言,
repmat
是一种更通用的解决方案,因此必然比其他解决方案慢。将两个向量相乘的特定“自制”解决方案可能更快。选择而不是相乘可能更快,即
向量(:,one(n,1))
而不是
向量*one(1,n)

编辑: 在命令窗口中键入
openrepmat
。正如您所看到的,它不是一个内置函数。您可以看到,它还使用
one
(选择)来复制矩阵。但是,由于它是一种更通用的解决方案(针对标量和多维矩阵以及多个方向的副本),因此您将发现不必要的
if
语句和其他不必要的代码,从而有效地降低了速度

编辑: 对于非常大的向量,将向量与
个相乘会变慢。明确的赢家是使用带有选择的
ones
,即
向量(:,ones(n,1))
(由于使用相同的策略,它应该总是比
repmat
更快)。

您也可以这样做-

vector(:,ones(1,n))
但是,如果我必须选择,
repmat
将是我的首选方法,因为它正是为此目的而设计的。此外,根据您将如何使用此复制阵列,您可以避免创建它,因为它会在输入阵列上执行动态复制,并且会对输入应用一些操作。这里有一个关于这一点的比较——这表明在大多数情况下,
bsxfun
优于
repmat

标杆管理 为了提高性能,让我们测试一下这些。下面是一个基准测试代码-

%// Inputs
vector = rand(1000,1);
n = 1000;

%// Warm up tic/toc.
for iter = 1:50000
    tic(); elapsed = toc();
end

disp(' ------- With REPMAT -------')
tic,
for iter = 1:200
    A = repmat(vector, 1, n);
end
toc, clear A

disp(' ------- With vector(:,ones(1,n)) -------')
tic,
for iter = 1:200
    A = vector(:,ones(1,n));
end
toc, clear A

disp(' ------- With vector * ones(1, n) -------')
tic,
for iter = 1:200
    A = vector * ones(1, n);
end
toc
运行时结果-

 ------- With REPMAT -------
Elapsed time is 1.241546 seconds.
 ------- With vector(:,ones(1,n)) -------
Elapsed time is 1.212566 seconds.
 ------- With vector * ones(1, n) -------
Elapsed time is 3.023552 seconds.

下面是一些基准测试使用不同的向量大小重复因子。将要显示的结果适用于Windows上的Matlab R2015b

首先为每种考虑的方法定义一个函数:

%// repmat approach
function matrix = f_repmat(vector, n)
matrix = repmat(vector, 1, n);

%// multiply approach
function matrix = f_multiply(vector, n)
matrix = vector * ones(1, n);

%// indexing approach
function matrix = f_indexing(vector,n)
matrix = vector(:,ones(1,n));
然后生成不同大小的向量,并使用不同的重复因子:

M = round(logspace(2,4,15)); %// vector sizes
N = round(logspace(2,3,15)); %// repetition factors
time_repmat   = NaN(numel(M), numel(N)); %// preallocate results
time_multiply = NaN(numel(M), numel(N));
time_indexing = NaN(numel(M), numel(N));
for ind_m = 1:numel(M);
    for ind_n = 1:numel(N);
        vector = (1:M(ind_m)).';
        n = N(ind_n);
        time_repmat(ind_m, ind_n)   = timeit(@() f_repmat(vector, n)); %// measure time
        time_multiply(ind_m, ind_n) = timeit(@() f_multiply(vector, n));
        time_indexing(ind_m, ind_n) = timeit(@() f_indexing(vector, n));
    end
end
结果
repmat
为参考绘制在以下两幅图中:

figure
imagesc(time_multiply./time_repmat)
set(gca, 'xtick',1:2:numel(N), 'xticklabels',N(1:2:end))
set(gca, 'ytick',1:2:numel(M), 'yticklabels',M(1:2:end))
title('Time of multiply / time of repmat')
axis image
colorbar

figure
imagesc(time_indexing./time_repmat)
set(gca, 'xtick',1:2:numel(N), 'xticklabels',N(1:2:end))
set(gca, 'ytick',1:2:numel(M), 'yticklabels',M(1:2:end))
title('Time of indexing / time of repmat')
axis image
colorbar

也许更好的比较是指出,对于每个测试向量大小和重复因子,三种方法中哪一种最快

figure
times = cat(3, time_repmat, time_multiply, time_indexing);
[~, fastest] = min(times, [], 3);
imagesc(fastest)
set(gca, 'xtick',1:2:numel(N), 'xticklabels',N(1:2:end))
set(gca, 'ytick',1:2:numel(M), 'yticklabels',M(1:2:end))
title('1: repmat is fastest; 2: multiply is; 3: indexing is')    
axis image
colorbar

从图中可以得出一些结论:

  • 基于乘法的方法总是比
    repmat
  • 基于索引的方法类似于
    repmat
    。向量大小或重复因子的值越大,速度越快,而值越小,速度越慢

  • matrix=bsxfun(@times,vector,one(1,n))怎么样。。。可能更快。我还做了一些时间测试。我想我拿到了前两个情节,但第三个。。我无法解释那个。我想我已经习惯了那些直线图上下移动:)@Divakar第三个告诉我哪种方法最快。它只包含1、2或3个(大小、重复因子)-容器