[R] proportional matrix rows
Peter Dalgaard
p.dalgaard at biostat.ku.dk
Mon Feb 7 17:42:50 CET 2005
Gabor Grothendieck <ggrothendieck at myway.com> writes:
> Robin Hankin <r.hankin <at> soc.soton.ac.uk> writes:
>
> :
> : Hi
> :
> : I have a two-column integer matrix like this:
> :
> : R> jj
> :
> : [,1] [,2]
> : [1,] -1 1
> : [2,] -2 2
> : [3,] -7 6
> : [4,] -8 7
> : [5,] -6 5
> : [6,] -9 8
> : [7,] -5 4
> : [8,] 3 -3
> : [9,] -10 9
> : [10,] -4 3
> :
> : I want a diagnostic that detects whether a row is a multiple of
> : the first row or not. In this case, this would be rows 1,2, and 8.
> :
> : How to do this nicely? Sometimes the first row has a zero, so the
> : method would have to work on
> :
> : [,1] [,2]
> : [1,] 0 1
> : [2,] 1 1
> : [3,] 0 8
> : [4,] 0 -4
> : [5,] 0 0
> : [6,] 4 0
> : >
> :
> : in which case rows 1,3,4,5 are multiples. It'd be nice to have
> : a solution that works for any number of columns.
>
>
> If rowi is a multiple of row1 then
> crossprod(cbind(row1, rowi)) is singular so:
>
> apply(mat, 1, function(x) det(crossprod(cbind(x, mat[1,])))) == 0
>
> If your matrix only has two columns then crossprod(x) is singular
> iff x is so you can eliminate the crossprod.
..and in that case it might be easier just to calculate the dot
product with the orthogonal of mat[1,]:
> z <- jj[1,]
> jj %*% c(z[1], -z[2])
[,1]
[1,] 0
[2,] 0
[3,] 1
[4,] 1
[5,] 1
[6,] 1
[7,] 1
[8,] 0
[9,] 1
[10,] 1
(Notice that the value "1" just comes from Robin being singularly bad
at selecting "arbitrary" rows that are not proportional to the first
one!)
This generalizes to more than two columns as
jj %*% (diag(ncol(jj)) - z%*%solve(crossprod(z))%*%t(z))
having rows that are identically zero (the multiplier matrix is
obviously rank-deficient so you can leave out one column, but you need
to guard against leaving in a column of zeroes, so it is hardly worth
it).
In all cases you probably need some sort of guard against round-off.
I.e. something like
> rowSums(zapsmall(jj %*% (diag(2) - z%*%solve(crossprod(z),t(z))))^2) == 0
[1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
or
> rowSums((jj %*% (diag(2) - z%*%solve(crossprod(z),t(z))))^2) < 1e-7
[1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
--
O__ ---- Peter Dalgaard Blegdamsvej 3
c/ /'_ --- Dept. of Biostatistics 2200 Cph. N
(*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
More information about the R-help
mailing list