Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Removing zeros from diagonal of a square matrix?

15 views
Skip to first unread message

roach

unread,
Feb 5, 2007, 10:38:20 PM2/5/07
to
Say I have a square matrix with zeros along the diagonal. I want to
take the average of each row but I know the diagonal 'zero' is not to
be factored into the calculation.

eg: bb =

0 1.2106 1.0797
-1.2106 0 0.3460
-1.0797 -0.3458 0

>> mean(bb,2)

ans =

0.7634
-0.2882
-0.4752

But I want mean to be:

1.1452
-0.4323
-0.7127

I have a cludgy do-loop that goes through each row, removes the
diagonal '0'. Very slow on big matrices. Is there an easier way?
TIA.

m

John D'Errico

unread,
Feb 5, 2007, 10:56:10 PM2/5/07
to

Do you know the diagonals are zero?
If so, then why remove them?

sum(bb,2)/(size(bb,2)-1)

HTH,
John

ImageAnalyst

unread,
Feb 5, 2007, 10:56:07 PM2/5/07
to
m:
If you know that there will always be a zero on the diagonal, and that
if there are any zeros off diagonal you want them included in the
average, then this code gives you exactly what you requested:

bb = [ 0 1.2106 1.0797 ; -1.2106 0 0.3460 ; -1.0797 -0.3458 0 ]
sizebb = size(bb)
sumbb = sum(bb')'
meansWithNoZerosInbb = sumbb ./ (sizebb(1) - 1)

Basically, you just divide the sum of each row by the number of
(dimensions - 1) since you know that one of the elements will be zero
and should be excluded from calculating the average. I think it
should be very fast and efficient. If you want ALL zeros excluded no
matter where they are located and how many of them there are, you'll
have to use the find() function and it gets more complicated (but
still just a few lines).
Regards,
ImageAnalyst

=============================================

roach

unread,
Feb 5, 2007, 11:06:40 PM2/5/07
to
On Feb 5, 10:56 pm, "ImageAnalyst" <imageanal...@mailinator.com>
wrote:

> m:
> If you know that there will always be a zero on the diagonal, and that
> if there are any zeros off diagonal you want them included in the
> average, then this code gives you exactly what you requested:
>
> bb = [ 0 1.2106 1.0797 ; -1.2106 0 0.3460 ; -1.0797 -0.3458 0 ]
> sizebb = size(bb)
> sumbb = sum(bb')'
> meansWithNoZerosInbb = sumbb ./ (sizebb(1) - 1)
>
> Basically, you just divide the sum of each row by the number of
> (dimensions - 1) since you know that one of the elements will be zero
> and should be excluded from calculating the average. I think it
> should be very fast and efficient. If you want ALL zeros excluded no
> matter where they are located and how many of them there are, you'll
> have to use the find() function and it gets more complicated (but
> still just a few lines).
> Regards,
> ImageAnalyst
>

Thanks. As I replied to John, lost sight of what I was trying to do.
Should go to bed now :)

roach

unread,
Feb 5, 2007, 11:13:24 PM2/5/07
to

> If so, then why remove them?
>
> sum(bb,2)/(size(bb,2)-1)
>
> HTH,
> John

And the answer is ... 'cause I got so caught up in trying to find a
fancy concatenation that I lost sight of what I was trying to do! V.
embarrassing! Thanks.

cal

unread,
Feb 6, 2007, 3:49:42 AM2/6/07
to
> Say I have a square matrix with zeros along the diagonal. I want to
> take the average of each row but I know the diagonal 'zero' is not to
> be factored into the calculation.

this is an answer:
replace the zero by nans and use nanmean (in the stats toolbox):

bb = rand(5);
n = size(bb,1);
bb(sub2ind([n,n],1:n,1:n))=nan;
nanmean(bb)

John D'Errico

unread,
Feb 6, 2007, 4:16:16 AM2/6/07
to

Well, thank god I've never done that.

Said by the fellow who once spent
2-3 hours of time obsessively
optimizing a code that would almost
never be used. Worse, the code took
approximately .01 seconds to run,
and I was able to cut that in half
for my efforts.

8-))

John

us

unread,
Feb 6, 2007, 4:33:22 AM2/6/07
to
roach:
<SNIP operation on matrices w/o using diag vals...

one of the very many other solutions (in particular, if you want to
do several operations on the de-diagonalized mat)

m=magic(5);
r=reshape(m(~eye(size(m,2))),size(m)-[1,0]);
m
r
% now, do you op(s), eg
[sum(r);median(r);mean(r);std(r)]

us

0 new messages