Matrix 'if' statement
198 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I just learned how to do matrices today, and am quite confused on this problem. So I have to create a 100 x 100 matrix. Every spot in the matrix takes on the value , where i represents the row and j represents the column location. I have a formula in which the value K is defined as the greater value of i and j. I need to create an if loop that compares the row and column position values and chooses the larger of the two, then defines that as the variable K.
I don't know what kind of syntax to use in terms of matrices. I know how to build an if staement, but am jsut simply confused on the kind of matlab syntax that needs to be followed.
2 Kommentare
KALYAN ACHARJYA
am 2 Dez. 2019
Bearbeitet: KALYAN ACHARJYA
am 2 Dez. 2019
%create matrics
[r c]=size(matrix); % find row and col number, If not known already
for i=1:r
for j=1:c
if condition
matrix(i,j)=...
end
end
end
You can do same without loop also. Being as beginer atleast you should learn how to use loop to do iteration on 1D or 2D array
Welcome to Matlab World! Please try and try, you can. We are here to help you!
Happy Learning & Good Luck!
:)
Manuel Dullnig
am 24 Aug. 2021
KALYAN you said one can do it without a loop. I need to do this without the loop, can you show me how?
Antworten (2)
John D'Errico
am 24 Aug. 2021
Bearbeitet: John D'Errico
am 24 Aug. 2021
One thing that new users of MATLAB mistake, is they want an if statement to apply to every element of a matrix or vector. For example:
M = magic(7)
So M is a matrix. Now users want to have an if statement that will do something different for every element of the matrix, depending on some test, and MATLAB does not have such an ability, at least not as they want. But there are some things you can do. For example, suppose I wanted to divide all of the even numbers by 2, but for the odd numbers, I want to multiply by 3, and then add 1? (You may recognize what I am doing here, if not, then you could do some reading about the Collatz conjecture, sometimes just called the 3n+1 problem.)
Solution 1: Just use a loop.
for i = 1:numel(M)
if rem(M(i),2) == 0
M(i) = M(i)/2; % even condition
else
M(i) = 3*M(i) + 1; % odd condition
end
end
M
So it did exactly as we need it to do, operating on each element of M separately. Note that the loop uses a linear index, treating the matrix as if it were a vector of elements. This works in MATLAB, so I did not need to create a double loop on the rows AND the columns of M.
But the MATLAB way is to use matrices. That is how MATLAB is really written to be efficient. So we might have used this next idea. (I'll just apply it directly to the last result of M.)
Solution 2:
% create a boolean variable that is either 0 or 1, depending on whether the
% corresponding element in M was even or odd.
evenloc = rem(M,2) == 0;
oddloc = ~evenloc;
M(evenloc) = M(evenloc)/2;
M(oddloc) = 3*M(oddloc) + 1;
M
As you can see, this also worked. No explicit loops were used, although internally inside the guts of MATLAB, it will be performing a loop in a lower level language, so an implicit loop. It employed what is called a boolean index. I could also have used find in a very similar way.
Solution 3:
% create a list of the elements in M that were even,
% and another list of the odd elements.
evenloc = find(rem(M,2) == 0);
oddloc = find(rem(M,2) == 1);
% Use those lists to index into M.
M(evenloc) = M(evenloc)/2;
M(oddloc) = 3*M(oddloc) + 1;
M
These are the common solutions you may see. Certainly there are others ways to do it too. I might have tried to be tricky, perhaps like this:
Solution 4:
mfac = [1/2 3];
afac = [0 1];
M = mfac(rem(M,2) + 1) .* M + afac(rem(M,2) + 1)
You may wish to look carefully at this last one. Why did it work? (Because it does work.) We could even use the last idea to usein a simple iteration scheme to play with the classic Collatz problem.
mfac = [1/2 3];
afac = [0 1];
% creating a simple function handle to perform one step of the Collatz
% iteration.
Miter = @(M) mfac(rem(M,2) + 1) .* M + afac(rem(M,2) + 1);
niter = 0;
while any(~ismember(M(:),[1 2 4]))
niter = niter + 1;
M = Miter(M);
end
niter
% and so, after 105 more iterations, we see that every element has now
% stabilized into the 3 oscillating terminal elements in the famous
% Collatz conjecture.
M
And there are cetainly other creative ways to solve the problem. In any such scheme I should have probably worried if the number was too large to be exactly representable as an integer in floating point arithematic in MATLAB, thus as a double. The limit for that is calling flintmax in MATLAB, but now I am digressing too far.
3 Kommentare
Jan
am 30 Aug. 2021
Bearbeitet: Jan
am 30 Aug. 2021
@Manuel Schiestl: A simpler version:
x = (1:10).'; % No need to create the full matrices
y = 1:10;
z = cos(0.1 * x .* y .^ 2); % Implicit expanding, Matlab >= R2016b
z((x>5) & (y>5)) = 5
There is no need to compare a logical with 1:
oddloc = (lrx==1 & lry==1);
% Simpler:
oddloc = (lrx & lry)
Wan Ji
am 24 Aug. 2021
If you do not want the loop, then
M = 100; N = 100;
[j, i] = meshgrid(1:N,1:M);
q = i>j;
A(q) = i(q);
A(~q)=j(~q);
2 Kommentare
Jan
am 24 Aug. 2021
|meshgrid| creates matrices, but for the comparison it is cheaper to work with vectors:
col = (1:N).';
row = (1:M);
q = row > col; % Auto-expand working for >= R2016b
Wan Ji
am 24 Aug. 2021
Hi, Jan
Thank you very much for your comment.
You open a door of new world in matlab for me. How surprising to see its simple and beautiful.
Wan Ji
Siehe auch
Kategorien
Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!