Find the row/column with the lowest maxima - matlab

Consider the matrix below:
A = randi([0 100], 5, 7)
62 59 20 42 49 41 83
37 34 13 65 82 47 24
93 33 19 93 30 37 20
42 49 74 96 26 41 21
14 85 14 90 77 4 96
first I want to find the maxima of each row and the column index:
83 7
82 5
93 1
96 4
96 7
then I need to find the row with the lowest maxima:
82 5 2
so far, I have implemented this:
close all;
clear all;
clc;
A = randi([0 100], 5, 7);
[M1, I1] = max(A, [], 2);
[M1, I1]
[M2, I2] = min(M1);
[M2, I1(I2), I2]
Though it feels like a workaround, I wondered if there is a more canonical way to do this? Maybe a built-in function or min/max syntax for this specific purpose?
P.S. Shared this question also on the MATLAB Discord channel.

What about this with find?
M = min(max(A,[],2));
[i,j] = find(A == M);
[M,j,i]

Related

Plot 2D topographic map of EEG node network on MATLAB

I would like to plot a topographic map from EEG network. The electrodes (nodes) have a associated networks metric and from these values I want to interpolate between them and plot in a head shape. Here is the code that i have reseached and the result that I am getting...
=========================================
%The position X and Y as integers (electrodes position) and the value of Z (network metric)
X = [36 51 66 11 22 51 79 91 3 16 51 86 99 1 14 51 88 101 3 16 51 86 99 11 22 51 79 91 36 51 66];
Y = [99 101 99 80 85 87 85 80 66 69 70 69 66 51 51 51 51 51 36 33 32 33 36 22 17 15 17 22 3 1 3];
Z = [-404 -566 -379 -71 -102 -119 -87 9 -62 -160 -104 -81 -26 12 -120 -176 -85 -13 0 -118 -288 -159 -36 -115 -145 -292 -215 -266 -235 -364 -192];
%Making the meshgrid
for dd = 1:31
I(Xd(dd),Yd(dd))=Zd(dd);
end
Zd = [Zd; zeros(70,1)];
Xd = [Xd; zeros(70,1)];
Yd = [Yd; zeros(70,1)];
[XX,YY] = meshgrid(1:101,1:101);
z = griddata(Xd,Yd,Zd,XX,YY,'cubic');
contourf(z)
=========================================
The resulting plot of this code is
http://s16.postimg.org/s7a627s5h/Graph.jpg
I would like some help to remove this "tail" from my graph and a sugggestion of how to draw a head + nose on the same picture (only if it is possible to plot this kind of graph).
I don't have enough reputation to comment above but you can set your own custom locations in EEGlab as far as I remember. Have you looked at the function writelocs? Maybe that helps. EEGlab's topoplots include nose and ears.
http://sccn.ucsd.edu/eeglab/allfunctions/writelocs.html

How to regress Y on X using matlab?

Given :
Y=[81 55 80 24 78 52 88 45 50 69 66 45 24 43 38 72 41 48 52 52 66 89];
X=[124 49 181 4 22 152 75 54 43 41 17 22 16 10 63 170 125 15 222 171 97 254];
I want to regress Y on X (simple linear regression). I tried with this code :
b= regress(Y,X)
But it gives me this error :
??? Error using ==> regress at 65
The number of rows in Y must equal the number of rows in X.
Thanks for any help.
regress expect its inputs as column vectors.
Transposing (.') your inputs should do the trick:
>> b = regress( Y.', X.' )
b =
0.4291

MATLAB CODE Rectification

The below code is not running in matlab. I am trying an anonymous function in matlab.Can you pls tell me whats wrong in this line :
Inv_Y_Quant = blockproc(BB,[8 8], InvQuant);
and the related code is below:
clear all
clc
I = imread('cameraman.tif');
% convert it to double
I = im2double(I);
% "Trim by 128"
I = I-128;
% Generate the DCT matrix
T = dctmtx(8);
% Generate Function handler for DCT
MyFun1 = #(block_struct) T * block_struct.data * T';
% BlockProcess the DCT the function for 8 by 8 blocks
B = blockproc(I,[8 8],MyFun1);
% Form the Quantization matrix
Q = [ 16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99];
% now generate function handler for the quantization
MyFun2 = #(block_struct)block_struct.data ./Q;
% perform the quantization
BB = blockproc(B,[8 8],MyFun2);
InvQuant = #(block_struct)round(block_struct.data.*Q);
Inv_Y_Quant = blockproc(BB,[8 8], InvQuant);
InvDct = #(block_struct)dct_matrix'*block_struct.data*dct_matrix;
Z = blockproc(Inv_Y_Quant, [8 8], InvDct);
Z = Z+128;
figure, imshow(Z)
Z = uint8(Z);
figure, imshow(Z)
%imwrite(Z, 'Mar7.tif');
%b = imread('Mar7.tif');
%imshow(b)
As you wrote in your comment, the problem is that you try to use array dct_matrix in anonymous function InvDct. This array was never defined in your code.
Did you meant to use matrix T (init as dctmtx(8))?
edit:
When using parameters in anonymous functions (as dct_matrix in this example), these parameters should be defined before the anonymous function is defined.

MATLAB: extracting groups of columns into a submatrix?

I have a data-set, in which I want to extract columns 1-3, 7-9, 13-15, all the way to the end of the matrix
As an example, I've used the standard magic function to create a matrix
A=magic(10)
A =
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 81 88 20 22 54 56 63 70 47
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
23 5 82 89 91 48 30 32 39 66
79 6 13 95 97 29 31 38 45 72
10 12 94 96 78 35 37 44 46 53
11 18 100 77 84 36 43 50 27 59
I know that I can extract single columns starting at 1, in intervals of 3 with the command:
Aex=a(:,1 : 3 : end)
Aex =
92 8 74 40
98 14 55 41
4 20 56 47
85 21 62 28
86 2 68 34
17 83 49 65
23 89 30 66
79 95 31 72
10 96 37 53
11 77 43 59
Say I want to extract groups of columns instead (e.g. column 1-3, 7-9 etc.).
Is there a way to do this without having to manually point out all the column numbers?
Thanks for your help!
Rasmus
Is this what you are looking for:
Aex = A(:,[1:3 7:9])
?
I am assuming that you would like the result all concatenated into another large matrix?
If that is the case, try this one on for size:
result = A(diag(0:2)*ones(3,floor((size(A,2) - 3)/6) + 1) + ...
ones(3,floor((size(A,2) - 3)/6) + 1)*diag(1:6:(size(A,2)-3)))
That could probably be shortened with some matrix math rules. You could also parameterize the values so that it can be modified to do more than what this problem expects, (and also might make more sense),
a = 3;
b = 6;
result = A(diag(0:a-1)*ones(a,floor((size(A,2) - a)/b) + 1) + ...
ones(a,floor((size(A,2) - a)/b) + 1)*diag(1:b:(size(A,2)-a)))
where a is the size of "group" (length([1 2 3]) = length([7 8 9]) = ... = 3), etc. and b is the column spacing ([1...7...13...] in your example)
If you would like them separated, I put them in cells here, but they can go to wherever you need:
a = 3;
b = 6;
results = {};
for Cols = 1:b:(size(A,2)-a)
results{end+1} = A(:, Cols:(Cols+2));
end
I didn't check the speed of either of these, but I think the first one may be faster. You may want to split it up into terms so it's more readable, I just did it to fit on a single line (which isn't always the best way of writing code).
The simple way to do this:
M = magic(10);
n = size(M,2)
idx = sort([1:3:n 2:3:n 3:3:n])
M(:,idx)
If however, the pattern of removal is simpler than the pattern of colums that you want to keep you could use this instead:
A = magic(10);
B = A;
B(:,4:3:end)=[];
B(:,4:3:end)=[]; %Yes 3x the same line of code.
B(:,4:3:end)=[];

Sliding window algorithm for activity recognition

I want to write a sliding window algorithm for use in activity recognition.
The training data is <1xN> so I'm thinking I just need to take (say window_size=3) the window_size of data and train that. I also later want to use this algorithm on a matrix
.
I'm new to matlab so i need any advice/directions on how to implement this correctly.
The short answer:
%# nx = length(x)
%# nwind = window_size
idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix(nx/nwind)-1))*nwind)-1;
idx will be a matrix of size nwind-by-K where K is the number of sliding windows (ie each column contains the indices of one sliding window).
Note that in the code above, if the last window's length is less than the desired one, it is dropped. Also the sliding windows are non-overlapping.
An example to illustrate:
%# lets create a sin signal
t = linspace(0,1,200);
x = sin(2*pi*5*t);
%# compute indices
nx = length(x);
nwind = 8;
idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix(nx/nwind)-1))*nwind)-1;
%'# loop over sliding windows
for k=1:size(idx,2)
slidingWindow = x( idx(:,k) );
%# do something with it ..
end
%# or more concisely as
slidingWindows = x(idx);
EDIT:
For overlapping windows, let:
noverlap = number of overlapping elements
then the above is simply changed to:
idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix((nx-noverlap)/(nwind-noverlap))-1))*(nwind-noverlap))-1;
An example to show the result:
>> nx = 100; nwind = 10; noverlap = 2;
>> idx = bsxfun(#plus, (1:nwind)', 1+(0:(fix((nx-noverlap)/(nwind-noverlap))-1))*(nwind-noverlap))-1
idx =
1 9 17 25 33 41 49 57 65 73 81 89
2 10 18 26 34 42 50 58 66 74 82 90
3 11 19 27 35 43 51 59 67 75 83 91
4 12 20 28 36 44 52 60 68 76 84 92
5 13 21 29 37 45 53 61 69 77 85 93
6 14 22 30 38 46 54 62 70 78 86 94
7 15 23 31 39 47 55 63 71 79 87 95
8 16 24 32 40 48 56 64 72 80 88 96
9 17 25 33 41 49 57 65 73 81 89 97
10 18 26 34 42 50 58 66 74 82 90 98