explanation of logical condition?

3 次查看(过去 30 天)
luisa bertoli
luisa bertoli 2018-5-20
评论: Jan 2018-5-20
Hi, i found this code:
A=mov;
max=0;
conx=0;
cony=0;
v=0;
DD=zeros(1205,3);
for k=1:1205
for i=1:336
for j=1:432
if (i < 4-[size((A(k).cdata),1)]) && (j < 4-[size((A(k).cdata),2)])
v=A(k).cdata(i ,j ) + A(k).cdata(i+1,j ) + A(k).cdata(i ,j+1) + A(k).cdata(i+1,j+1) + ...
A(k).cdata(i+2,j ) + A(k).cdata(i+2,j+1) + A(k).cdata(i ,j+2) + A(k).cdata(i+1,j+2) + A(k).cdata(i+2,j+2) + ...
A(k).cdata(i ,j+3) + A(k).cdata(i+1,j+3) + A(k).cdata(i+2,j+3) + A(k).cdata(i+3,j+3) + ...
A(k).cdata(1+3,j ) + A(k).cdata(1+3,j+1) + A(k).cdata(1+3,j+2);
else
v=A(k).cdata(i,j);
end
if v>max
max=v;
conx=i;
cony=j;
end
end
end
DD(k,1)=max;
DD(k,2)=conx;
DD(k,3)=cony;
max=0;
end
and i can't understand the meaning of the logical condition:
if (i < 4-[size((A(k).cdata),1)]) && (j < 4-[size((A(k).cdata),2)])
else
v=A(k).cdata(i,j);
can anybody explain it to me? /as for me A(k).cdata is equal to 332.

回答(2 个)

Jan
Jan 2018-5-20
编辑:Jan 2018-5-20
By the way: In
(i < 4-[size((A(k).cdata),1)])
the square brackets are confusing only. [] is the operator for concatenation, but here it contains a scalar element only. Easier:
(i < 4 - size(A(k).cdata, 1))
It would be even nicer, to move the determination of the size outside the inner loops:
A = mov;
DD = zeros(1205,3);
for k = 1:1205
c = A(k).cdata; % Makes the code MUCH shorter and nicer
s = size(c);
% Initialize INSIDE the loop!
maxV = 0; % Do not use "max", because it is a Matlab function
conx = 0;
cony = 0;
v = 0;
for i = 1:336
for j = 1:432
if i < 4 - s(1) && j < 4 - s(2) % ??? Sure?
v = c(i, j) + c(i+1,j) + c(i, j+1) + ...
c(i+1,j+1) + c(i+2,j) + c(i+2,j+1) + ...
c(i, j+2) + c(i+1,j+2) + c(i+2,j+2) + ...
c(i, j+3) + c(i+1,j+3) + c(i+2,j+3) + ...
c(i+3,j+3) + c(1+3,j) + c(1+3,j+1) + ... % ??? 1+3 ???
c(1+3,j+2);
else
v = c(i,j);
end
if v > maxV
maxV = v;
conx = i;
cony = j;
end
end
end
DD(k,1) = maxV;
DD(k,2) = conx;
DD(k,3) = cony;
end
I assume there is a typo in your code
...
c(i+3,j+3) + c(1+3,j) + c(1+3,j+1) + ...
c(1+3,j+2);
should be
...
c(i+3,j+3) + c(i+3,j) + c(i+3,j+1) + ...
c(i+3,j+2);
with "i+3", instead of "1+3".
The condition looks suspicious:
if i < 4 - s(1) && j < 4 - s(2)
When the size of cdata if greater than 3x3, the condition is never true. Maybe you meant:
if i < s(1) - 4 && j < s(2) - 4
This would avoid using elements outside the matrix. [EDITED] To be exact, if avoid processing the 5 right columns and 5 bottom rows. The actual computations would work for this also:
if i <= s(1) - 3 && j <= s(2) - 3
to exclude the 3 right and bottom indices only.
I'd prefer to reorder the terms, because this makes it easier to detect typos in the indices:
v = c(i, j) + c(i+1, j) + c(i+2, j) + c(i+3, j) + ...
c(i, j+1) + c(i+1, j+1) + c(i+2, j+1) + c(i+3, j+1) + ...
c(i, j+2) + c(i+1, j+2) + c(i+2, j+2) + c(i+3, j+2) + ...
c(i, j+3) + c(i+1, j+3) + c(i+2, j+3) + c(i+3, j+3);
Instead of using a loop to determine v, it is much cheaper to call conv2:
M = 5; % Size of the margin, I'd suggest using 3 for a 4x4 convolution
DD = zeros(numel(mov), 3);
for k = 1:numel(mov)
v = mov(k).cdata;
s = size(c);
Q = conv2(c, ones(4, 4), 'valid');
v(1:s(1) - M, 1:s(2) - M) = Q(1:s(1) - M, 1:s(2) - M);
[maxV, Ind] = max(v(:));
DD(k, 1) = maxV;
[DD(k, 2), DD(k, 2)] = ind2sub(s, Ind);
end
This code is shorter, faster and less prone to typos.

dpb
dpb 2018-5-20
编辑:dpb 2018-5-20
size((A(k).cdata),1) --> number rows in kth element of struct array A field cdata
size((A(k).cdata),2) --> number cols in kth element of struct array A field cdata
so the IF keeps from the terms i+n for n = 1,2,3,4 in the indexing expressions A(k).cdata(i+1,j), etc., from having out-of-bounds addressing errors.
IOW, if i were =333, what are the indices of the array for all the terms and what would happen?
ADDENDUM Somewhat unusual code in that only looking for the one value; some other comments--
  1. Using max as variable not a good idea to alias the builtin MAX() function; use a different variable name like maxv or somesuch,
  2. In general not great coding idea to use "magic numbers"; find the constants from the input data instead; then the routine is general instead of specific and don't have to recode if the array sizes change,
  3. Can eliminate the i,j loops at the expense of some memory--
[nR,nC]=size(A(k).cdata); % get array size
N=4; % filter size
v=A(k).cdata; % preload array, will overwrite central portion
v(1+N:end-N,1+N:end-N)=filt2(ones(N),v,'valid'); % compute inner summation
[vmx,ivmx]=max(v(:)); % max, location in array
[r,c]=ind2sub(size(v),ivmx); % convert to row, column subscripts
DD=[k,:]=[vmx;r;c]; % put into previous variable
  1 个评论
Jan
Jan 2018-5-20
@dpb: It is funny, how similar our suggestions are :-). I assume you meant "filter2" instead of "filt2". This function uses conv2 internally also, and then the approaches are identical (except for the number of marginal columns and rows).
There is another typo in the last line. This works:
DD(kk, :) = [vmx, r, c];

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Function Creation 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by