Saddle points of a 2D matrix

86 ビュー (過去 30 日間)
Marco Nashaat
Marco Nashaat 2020 年 2 月 11 日
回答済み: Walter Roberson 2023 年 8 月 25 日
the problem I'm working on is to find the saddle points of a matrix and now I'm trying this ...
  • nested loop to check every element
  • check if the element is the smallest in its column and the biggest in its row
  • if it is,print it into the matrix'indices'
  • if there was none,print empty matrix....and the code [row,col]=size(matrix); for I=1:row for j=1:col if matrix (I,j)==max(matrix, I)&&matrix (I,j)==min(matrix, j) indices=[i j;]: else indices=[ ] end end endsome help with the syntax please,thanks!!

採用された回答

Jon
Jon 2020 年 2 月 11 日
編集済み: Jon 2020 年 2 月 11 日
Here is a simple approach. Note I define a saddle point as one that is either the largest in its column and smallest in its row or the smallest in its column and largest in its row. Maybe you only want to look for the second kind in which case you can modify the approach accordingly.
Also this code is quite inefficient. You could further optimize it by finding and saving the column maximums, column minimums, row maximums and row minimums before entering the loop.
You could also probably vectorize this further and not use a loop at all, but I think you wanted to see how the basic syntax would look.
% make a matrix to try algorithm on
% there are saddle points at 2,2 and 4,4
A = [10 12 7 3 12;
3 10 6 2 8;
12 24 17 6 10;
15 21 10 8 12;
1 18 22 4 15];
disp A
% get dimensions of the matrix
[numRows,numCols] = size(A);
% preallocate array to hold indices for saddle points, there can be at most two
indices = zeros(2,2);
% loop through rows and columns of matrix
numSaddle = 0; % counter
for iRow = 1:numRows
for jCol = 1:numCols
% check if it is the biggest element in its row and smallest
% element in its column
brsc = A(iRow,jCol) == max(A(iRow,:)) && A(iRow,jCol) == min(A(:,jCol));
% check if is the smallest element in its row and biggest
% element in its column
srbc = A(iRow,jCol) == min(A(iRow,:)) && A(iRow,jCol)== max(A(:,jCol));
if brsc || srbc
numSaddle = numSaddle + 1;
indices(numSaddle,:) = [iRow,jCol];
end
end
end
% delete off the unused entries in the indices array
indices = indices(1:numSaddle,:);
% display the result
disp(indices)
% display saddle points
for k = 1:numSaddle
disp(A(indices(k,1),indices(k,2)))
end
  7 件のコメント
Faraz Ahmad
Faraz Ahmad 2020 年 11 月 14 日
@Rishi Diwan.Thanks a lot
Kushagra Mehrotra
Kushagra Mehrotra 2021 年 2 月 11 日
Thanks Rishi !

サインインしてコメントする。

その他の回答 (9 件)

Sahil
Sahil 2020 年 4 月 4 日
function indices = saddle(M)
saddle_m = zeros(size(M));
row_maxima = max(M, [], 2);
col_minima = min(M, [], 1);
indices = [];
for i = 1:size(M, 1)
for j = 1:size(M, 2)
if M(i, j) == row_maxima(i) && M(i, j) == col_minima(j)
saddle_m(i, j) = 1;
indices = [i, j; indices];
end
end
end
end
  2 件のコメント
Nihal Dwivedi
Nihal Dwivedi 2020 年 6 月 16 日
thanks this worked perfectly
Jessamyn Johnson
Jessamyn Johnson 2021 年 3 月 20 日
Could you explain to me what the function of the saddle_m is?

サインインしてコメントする。


fred  ssemwogerere
fred ssemwogerere 2020 年 2 月 11 日
Hello, i think something like this should do nicely:
% To check which element is the smallest in its column, and biggest in its row, for a given matrix say,
% "b", you can first pre-allocate a matrix of zeros where the valid saddle points will be input.
indices=zeros(size(b)); % pre-alocating "indices" based on size of assumed matrix "b"
% Next determine the minimum values of each column of the matrix, "b"
b_colmin=min(b);
% Determine the maximum values for each row of "b" by first taking the transpose of "b"
b_rowmax=max(b');
% Check for membership of "b_colmin" in "b_rowmax"."lm" is a vector of lowest indices in "b_rowmax" for each value of "b_colmin" in "b_rowmax"
[~,lm]=ismember(b_colmin,b_rowmax);
% find the column indices of non-zero indices ("nzCol") in "lm", and the corresponding vector on non-zero values ("nzVec"). The vector "nzVec" in actual sense will be a vector of row indices for the saddle points.
[~,nzCol,nzVec]=find(lm);
% Input saddle points into marix "indices" based on indices
indices(nzVec,nzCol)=b(nzVec,nzCol);
  2 件のコメント
Marco Nashaat
Marco Nashaat 2020 年 2 月 11 日
Thanks but I guess there might be a bug....when asking for membership let's say the maximum value of a row was actually equal to minimum of Irrelative column then "indices" will return the index of a wrong element!! correct me if I was wrong,thanks
fred  ssemwogerere
fred ssemwogerere 2020 年 2 月 11 日
"indices" returns the values that are maximum in a row, but minimum in their column, at their indexed positions in an assumed matrix "b". However, if the aim is to only get the indices of the saddle points, then all you need will be: "nzVec" and "nzCol". You can write this into an array as [nzVec,nzCol].

サインインしてコメントする。


darova
darova 2020 年 2 月 11 日
One way to use surfnorm
clc,clear
% generate some data
[X,Y] = meshgrid( linspace(-1,1,20) );
Z = X.^2-Y.^2;
[nx,ny,nz] = surfnorm(X,Y,Z); % normal vectors
[az,el,rho] = cart2sph(nx,ny,nz); % find azimuth and elevation
[~,ix] = max(el(:)); % find maximum elevation
mesh(X,Y,Z)
hold on
scatter3(X(ix),Y(ix),Z(ix),50,'r','filled') % saddle point
quiver3(X,Y,Z,nx,ny,nz,'b') % show normal vectors
hold off
axis equal

Ajijul Mridol
Ajijul Mridol 2020 年 6 月 27 日
編集済み: Ajijul Mridol 2020 年 6 月 27 日
function indices=saddle(M)
[row,col]=size(M);
k=1;
for i=1:row
for j=1:col
%check if it is the biggest element in row and smallest in that column
if (M(i,j)==max(M(i,:)) | M(i,j)==M(i,:)) & (M(i,j)==min(M(:,j)) | M(i,j)==M(:,j))
indices(k,1)=i;
indices(k,2)=j;
k=k+1;
end
end
end
if k==1
indices=[]; %return an empty matrix if there is not saddle point
return
end
end

Sharnam Singhwal
Sharnam Singhwal 2020 年 8 月 27 日
function indices=saddle(M)
[row,col]=size(M);
count=0;
indices=[];
for i= 1:row
for j= 1:col
if M(i,j)==max(M(i,:)) && M(i,j)==min(M(:,j))
indices=[indices;i j];
end
end
end
end

shubham nayak
shubham nayak 2020 年 9 月 3 日
編集済み: DGM 2023 年 8 月 25 日
function indices=saddle(z)
[a,b]=size(z);c=1;
indices=[];
for i = 1:a
for j = 1:b
maxrow(i,j)=max(z(i,1:b));
if(maxrow(i,j)<=min(z(1:a,j)))
indices(c,1)=i;
indices(c,2)=j;
c=c+1;
end
end
end
end

Soumyadip Sikdar
Soumyadip Sikdar 2022 年 7 月 18 日
function [number,indices]=saddle_point(M)
s=size(M);
n=0;
indices=[];
number={};
for i=1:s(1)
for j=1:s(2)
l=M(i,j)>=M(i,:);
x=M(i,j)<=M(:,j);
if l==ones(1,s(2))& x==ones(s(1),1)
n=n+1;
number{n,1}=[i,j];
else
continue
end
end
end
indices=cell2mat(number);
This might help you out

muhammad akl
muhammad akl 2023 年 8 月 24 日
編集済み: DGM 2023 年 8 月 25 日
% this is my answer
function indices=saddle(M)
[r,c]=size(M);
indices=[];
for i=1:r
for j=1:c
if M(i,j) >= max(M(i,:)) && M(i,j) <= min(M(:,j))
indices=[indices; i,j];
end
end
end
  1 件のコメント
DGM
DGM 2023 年 8 月 25 日
編集済み: DGM 2023 年 8 月 25 日
Care to explain how your answer is different from this answer?
... because it's not consequentially different. The only changes are a trivial change of variable name, some extra spaces scattered about, and an inconsequential change of comparison operators.
When you're adding an answer to a thread full of other answers, it's important to make sure you're adding something new to the conversation. It's entirely appropriate to challenge existing answers or improve upon them, but if you're repeating what's already been presented, or if it's unclear how your answer is worth considering, there's no value added to what the reader sees.

サインインしてコメントする。


Walter Roberson
Walter Roberson 2023 年 8 月 25 日
M = imread('cameraman.tif');
SM = [0 0 0; 1 1 1; 0 0 0];
maxmask1 = imregionalmax(M, SM);
minmask1 = imregionalmin(M, SM);
maxmask2 = imregionalmax(M, SM.');
minmask2 = imregionalmin(M, SM.');
loc_is_saddle = (maxmask1 & minmask2) | (minmask1 & maxmask2);
imshow(M); title('original');
imshow(loc_is_saddle); title('saddle points')

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by