initialize a MxN matrix with the same number

800 Ansichten (letzte 30 Tage)
Salvatore Mazzarino
Salvatore Mazzarino am 20 Okt. 2012
Kommentiert: Walter Roberson am 11 Dez. 2023
I would initialize a M x N matrix with the same number. Which could be the best way in terms of speed?
Es.
[2 2;
2 2
2 2]

Antworten (10)

Matt Fig
Matt Fig am 20 Okt. 2012
Another:
% Make a 3-by-8 matrix of 9s:
A(1:3,1:8) = 9
  3 Kommentare
John BG
John BG am 28 Sep. 2016
if it has been defined before ..
if it coincides with the name of a function ..
if you start looking backward there is not way to move forward.
Matt gave the right answer, get on with it, or prove it wrong.
Walter Roberson
Walter Roberson am 29 Sep. 2016
? You are arguing with a 4 year old posting ?
Jan did give a counter example:
A = rand(9);
A(1:3, 1:8) = 9;
A
A =
9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 0.9651
9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 0.6406
9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 9.0000 0.7577
0.5009 0.5300 0.3514 0.0230 0.6206 0.5925 0.8718 0.5488 0.7359
0.8410 0.9315 0.2206 0.2301 0.4299 0.1449 0.7987 0.3064 0.6590
0.9057 0.9739 0.3609 0.8522 0.6744 0.5350 0.7201 0.2121 0.9933
0.2481 0.8476 0.1054 0.9497 0.9710 0.2542 0.0973 0.6881 0.8679
0.1017 0.7075 0.1900 0.1831 0.3252 0.8435 0.3257 0.7090 0.4237
0.5273 0.9981 0.1697 0.2163 0.9954 0.9812 0.1355 0.4648 0.6465
Part of the array was set as required but the rest was left alone, which does not meet the specifications.

Melden Sie sich an, um zu kommentieren.


Friedrich
Friedrich am 14 Aug. 2018
Bearbeitet: Friedrich am 15 Aug. 2018
I know this is old but I could not let it go. I found
A=zeros(M,N)+10;
to be the fastest. At least on my computer. Heres my code for testing and the results in Matlab 2017b
% produces 6.4GB of data
M = 80e6;
N = 10;
clear A
tic;
A=ones(M,N)*10;
disp(['A=ones(M,N)*10; = ' num2str(toc) 's']);
clear A
tic;
A=uninit(M,N);
A(:) = 10;
disp(['A=uninit(M,N); A(:)=10; = ' num2str(toc) 's']);
clear A
tic;
A=repmat(10,[M,N]);
disp(['A=repmat(10,[M,N]); = ' num2str(toc) 's']);
clear A
tic;
A = mxFastZeros(0,M,N)+10;
disp(['A=mxFastZeros(0,M,N)+10; = ' num2str(toc) 's']);
clear A
tic;
A=zeros(M,N)+10;
disp(['A=zeros(M,N)+10; = ' num2str(toc) 's']);
clear A
tic;
a = 12;
A = a(ones(M, N));
disp(['a=10;A=a(ones(M, N)); = ' num2str(toc) 's']);
clear A
Results
A=ones(M,N)*10; = 3.312s
A=uninit(M,N); A(:)=10; = 2.508s
A=repmat(10,[M,N]); = 2.1169s
A=mxFastZeros(0,M,N)+10; = 1.8326s
A=zeros(M,N)+10; = 1.8487s
a=10;A=a(ones(M, N)); = 25.0576s
Edit: Thank you James for the hint on mxFastZeros. I included that in the benchmark.
  5 Kommentare
Matt J
Matt J am 18 Jun. 2020
You should probably add repelem to this comparison.
Rik
Rik am 18 Jun. 2020
I also added your suggestion with randi and reposted it as an answer to avoid this being burried.

Melden Sie sich an, um zu kommentieren.


Rik
Rik am 18 Jun. 2020
Bearbeitet: Rik am 19 Jun. 2020
Inspired by the comparative speed test in the answer by Friedrich, I extended his code to have more robust testing that could be performed on multiple different releases. Timings below are normalized to 10*ones(M,N), and Octave and ML6.5 have fewer elements to prevent max array size errors. See the attached file for all details.
(failed options are removed from this post, but are displayed by the function) (you could make the function more fancy, but I didn't feel like spending time on that. I might update this function at some point)
Matlab 6.5:
A=ones(M,N)*10; = 0.0410s (normalized time = 0.99)
A=zeros(M,N)+10; = 0.0400s (normalized time = 1.01)
A=repmat(10,[M,N]) = 0.0460s (normalized time = 1.14)
a=10;A=a(ones(M, N)); = 0.2770s (normalized time = 6.84)
R2011a:
A=repmat(10,[M,N]) = 1.8918s (normalized time = 0.98)
A=ones(M,N)*10; = 1.8975s (normalized time = 0.99)
A=uninit(M,N); A(:)=10; = 1.9129s (normalized time = 1.00)
A=zeros(M,N)+10; = 2.0259s (normalized time = 1.05)
A=mxFastZeros(0,M,N)+10; = 3.7976s (normalized time = 1.94)
a=10;A=a(ones(M, N)); = 8.4049s (normalized time = 4.36)
A=randi([10,10], M,N); = 12.0829s (normalized time = 6.20)
R2015a:
A=repmat(10,[M,N]) = 0.6856s (normalized time = 0.39)
A=repelem(10, M, N); = 0.7803s (normalized time = 0.44)
A=mxFastZeros(0,M,N)+10; = 1.7123s (normalized time = 0.97)
A=uninit(M,N); A(:)=10; = 1.7477s (normalized time = 0.99)
A=ones(M,N)*10; = 1.7598s (normalized time = 0.99)
A=zeros(M,N)+10; = 1.8429s (normalized time = 1.04)
a=10;A=a(ones(M, N)); = 7.6893s (normalized time = 4.35)
A=randi([10,10], M,N); = 7.7680s (normalized time = 4.40)
R2020a:
A=mxFastZeros(0,M,N)+10; = 0.6672s (normalized time = 0.31)
A=zeros(M,N)+10; = 0.6879s (normalized time = 0.31)
A=repmat(10,[M,N]) = 0.7013s (normalized time = 0.32)
A=repelem(10, M, N); = 0.7761s (normalized time = 0.36)
A=uninit(M,N); A(:)=10; = 1.7886s (normalized time = 0.83)
A=ones(M,N)*10; = 2.1304s (normalized time = 0.98)
A=randi([10,10], M,N); = 6.9900s (normalized time = 3.21)
a=10;A=a(ones(M, N)); = 7.2315s (normalized time = 3.32)
Octave 5.2.0
A=repmat(10,[M,N]) = 0.0264s (normalized time = 0.43)
A=repelem(10, M, N); = 0.0366s (normalized time = 0.59)
A=zeros(M,N)+10; = 0.0583s (normalized time = 0.94)
A=uninit(M,N); A(:)=10; = 0.0628s (normalized time = 1.00)
A=ones(M,N)*10; = 0.0637s (normalized time = 1.03)
a=10;A=a(ones(M, N)); = 0.0945s (normalized time = 1.53)
A=randi([10,10], M,N); = 0.4947s (normalized time = 8.00)
  3 Kommentare
Rik
Rik am 18 Jun. 2020
This is the output. I replaced the current directory and the install path with placeholders. In case it is relevant: the pwd doesn't have spaces, but the install path does.
Building with 'MinGW64 Compiler (C)'.
Error using mex
{{pwd}}\mxFastZeros.c:14:10: error: conflicting types for 'mxFastZeros'
mxArray *mxFastZeros(mxComplexity ComplexFlag, mwSize m, mwSize n);
^~~~~~~~~~~
In file included from {{mlroot}}/extern/include/mex.h:43:0,
from {{pwd}}\mxFastZeros.c:10:
{{mlroot}}/extern/include/matrix.h:1171:46: note: previous declaration of 'mxFastZeros' was here
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxArray *mxFastZeros(int cmplx_flag, int m, int n);
^~~~~~~~~~~
{{pwd}}\mxFastZeros.c:15:10: error: conflicting types for 'mxCreateSharedDataCopy'
mxArray *mxCreateSharedDataCopy(mxArray *mx);
^~~~~~~~~~~~~~~~~~~~~~
In file included from {{mlroot}}/extern/include/mex.h:43:0,
from {{pwd}}\mxFastZeros.c:10:
{{mlroot}}/extern/include/matrix.h:1169:46: note: previous declaration of 'mxCreateSharedDataCopy' was here
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxArray *mxCreateSharedDataCopy(const mxArray *pa);
^~~~~~~~~~~~~~~~~~~~~~
James Tursa
James Tursa am 18 Jun. 2020
Looks like they have exposed the true interfaces to these unofficial functions. Just use them. E.g.,
mxArray *mxFastZeros(int cmplx_flag, int m, int n);
mxArray *mxCreateSharedDataCopy(const mxArray *mx);

Melden Sie sich an, um zu kommentieren.


Azzi Abdelmalek
Azzi Abdelmalek am 20 Okt. 2012
Bearbeitet: Azzi Abdelmalek am 20 Okt. 2012
  4 Kommentare
Azzi Abdelmalek
Azzi Abdelmalek am 20 Okt. 2012
or
A=repmat(12,M,N);
Azzi Abdelmalek
Azzi Abdelmalek am 20 Okt. 2012
Matt's init is the fastest

Melden Sie sich an, um zu kommentieren.


Jan
Jan am 20 Okt. 2012
To avoid troubles with earlier definitions, I prefer:
A = repmat(12, M, N);
The overhead for calling the M-file repmat can be omitted:
a = 12;
A = a(ones(M, N));

Matt J
Matt J am 20 Okt. 2012
A=zeros(M,N);
A(:)=some_number;

James Tursa
James Tursa am 20 Okt. 2012
Bearbeitet: James Tursa am 20 Okt. 2012
Another method if matrix A is not already allocated:
A = uninit(M,N);
A(:) = some_number;
UNINIT can be found here:
If the matrix A is pre-existing, then of course skip the allocation step and just fill the values ala the 2nd line above.
SIDE NOTE: On later version of MATLAB it seems the parser is smart enough to recognize the value*ones(m,n) formulation and not actually do the multiply. At least that is my conclusion based on speed tests.

Rozh Al-Mashhdi
Rozh Al-Mashhdi am 10 Dez. 2023
Bearbeitet: Stephen23 am 10 Dez. 2023
At least on my system (macbook pro 2021, Matlab 2023), the following is faster than V * ones (M,N) for very large M and N. For small M and N there is no measurable difference
A=zeros(M,1)+V;
B=zeros(1,N)+1;
C=A*B;
The above is inspired by:
  5 Kommentare
Walter Roberson
Walter Roberson am 11 Dez. 2023
For those sizes, here on MATLAB Answers, nothing is reliable about the timing, and the third version I came up with might be a hair faster.
Relative performance on your own system might be substantially different.
format long g
testtimes();
ans = 3×3
0.393793 0.451649 0.390828 0.335784 0.370165 0.399899 0.330778 0.365417 0.367776
function testtimes()
M = 12000; N = 18000;
V = 123;
start = tic;
A1 = zeros(M,1)+V;
B1 = zeros(1,N)+1;
C1 = A1*B1;
t1a = toc(start);
start = tic;
A2 = zeros(M,1)+V;
B2 = ones(1,N);
C2 = A2*B2;
t2a = toc(start);
start = tic;
A3 = ones(M,1)*V;
B3 = ones(1,N);
C3 = A3*B3;
t3a = toc(start);
start = tic;
A1 = zeros(M,1)+V;
B1 = zeros(1,N)+1;
C1 = A1*B1;
t1b = toc(start);
start = tic;
A2 = zeros(M,1)+V;
B2 = ones(1,N);
C2 = A2*B2;
t2b = toc(start);
start = tic;
A3 = ones(M,1)*V;
B3 = ones(1,N);
C3 = A3*B3;
t3b = toc(start);
start = tic;
A1 = zeros(M,1)+V;
B1 = zeros(1,N)+1;
C1 = A1*B1;
t1c = toc(start);
start = tic;
A2 = zeros(M,1)+V;
B2 = ones(1,N);
C2 = A2*B2;
t2c = toc(start);
start = tic;
A3 = ones(M,1)*V;
B3 = ones(1,N);
C3 = A3*B3;
t3c = toc(start);
[t1a, t1b, t1c; t2a, t2b, t2c; t3a, t3b, t3c]
end
Walter Roberson
Walter Roberson am 11 Dez. 2023
On my system, with those array sizes:
>> another_way
ans =
0.110873719 0.192779666 0.17914935
0.105916544 0.167061579 0.178607924
0.108013696 0.177013045 0.169540193
>> another_way
ans =
0.101248998 0.176637954 0.200039796
0.10419013 0.155409292 0.162791305
0.098662435 0.154152901 0.173319562
Nothing there is reliable either.

Melden Sie sich an, um zu kommentieren.


MathWorks Support Team
MathWorks Support Team am 9 Nov. 2018
In general, the easiest ways to initialize a matrix with the same number are the following, which produce a 3-by-2 matrix whose elements are all 2:
A = 2*ones(3,2)
A = zeros(3,2) + 2
A = repmat(2,3,2)
The speed of these methods relative to each other can depend on your computing environment.

Matt J
Matt J am 11 Nov. 2018
Here's a safe one-liner, but I don't know how fast it is.
A=randi([n,n], M,N);

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by