[R] Changing a matrix based on eigen value

David Winsemius dwinsemius at comcast.net
Thu Jul 21 15:54:51 CEST 2011


On Jul 21, 2011, at 12:22 AM, B. Jonathan B. Jonathan wrote:

> Thanks David for your pointer. Here my original matrix is VCV matrix  
> which is the utmost important matrix in finance. However in reality  
> what happens is that due to incomplete data. lot of missing values  
> (or some other problems) that matrix may be unstable like min eigen  
> value is negative or very close to zero etc.
>
> My goal is to make that unstable matrix stable for further  
> calculation. Here I want to make the min eigen "quite far from zero  
> in positive quadrant", however still do not want to loose much  
> information that is hidden in my original matrix (what I call it  
> "Real information").
>
> I want to have a control on: How far min eigen value I want from zero.
>
> Please let me should I need to give more information.
>
> Thanks,
> On Thu, Jul 21, 2011 at 9:27 AM, David Winsemius <dwinsemius at comcast.net 
> > wrote:
>
> On Jul 20, 2011, at 11:17 PM, B. Jonathan B. Jonathan wrote:
>
> It is not any homework problem. I just need some pointer. Given that  
> I think
> I would be able to carry forward.
>
> Then what kind of problem _is_ it? You say:
>
> "nearest matrix"   ... using what measure for distance or similarity?
>
> "... keep all other properties (whatever are those) of my original  
> matrix "mat" as unaltered as possible."
>
>     ... this really does leave your question looking ... what would  
> be kind? ... perhaps the word "nebulous" would be apt? How are we  
> supposed to make choices for you in the absence of any goals?
>
> -- 
> David
>


On Jul 20, 2011, at 1:06 PM, B. Jonathan B. Jonathan wrote:

> Dear all, my question is not directly related to R, however I  
> believe that
> experts here would not mind anything to have a look on my problem.
>
> Please consider a symmetric matrix and it's eigen values:
>
>> set.seed(1)
>> mat <- matrix(rnorm(36), 6)
>> mat <- mat %*% t(mat) # symmetric matrix
>> mat
>          [,1]       [,2]        [,3]       [,4]       [,5]        [,6]
> [1,]  3.920570  1.9339770  1.29012167 -1.4627174 -1.5655953  
> -1.82083435
> [2,]  1.933977  5.8501784 -1.70504980  0.7195951  1.4252209  
> -3.11543738
> [3,]  1.290122 -1.7050498  3.31434984 -0.6324029  0.1860666  
> -0.08234236
> [4,] -1.462717  0.7195951 -0.63240294  5.4179467  0.9003576  
> -3.61864495
> [5,] -1.565595  1.4252209  0.18606662  0.9003576  4.5248002   
> 0.52702347
> [6,] -1.820834 -3.1154374 -0.08234236 -3.6186449  0.5270235   
> 6.02038872
>> eigen(mat)$values
> [1] 11.4213448  7.3302845  5.7033748  3.9863332  0.4827576  0.1241385
>
> Here my goal is to find the "nearest matrix" of "mat" for which the  
> minimum
> eigen value is 0.20

  Still waiting for a specific definition of "near".

If all you want to get is an output that matches your minimum  
eigenvalue specification it is very nearly trivial but probably not  
optimal "solution"::

mat*0.2/0.1241385    # but is this meaningful?
 > det(mat*0.2/0.1241385)
[1] 1994.896   # big change in determinant, by factor of  
(0.2/0.1241385)^6

> (I would rather want to fix some arbitrary value). While
> finding that nearest matrix, I would like to keep all other properties
> (whatever are those)

Yes, _what_ are those "all other properties"? Ratios of elements?  
Determinant? Condition number? You've hinted at why are you asking  
this question, but still have not presented any specifics on how a  
strategy would be assessed. I freely admit that I was very surprised  
upon Google-searching to see how much applicability has developed in  
physics from the notion of random symmetric matrices. I had not been  
aware of Wigner's fascinating results in nuclear physics nor the other  
findings that have emerged in the last 50 years.

(I also found that multiplying the diagonal elements of 'mat' by a  
very small fraction and leaving all other elements the same could  
achieve the same sort of result.

mat2 <- mat
 > det(mat)
[1] 114.072
 > eigen(mat)$values[1]/eigen(mat)$values[6]  # original condition  
number
[1] 92.00486

diag(mat2) <- diag(mat)*1.01679
eigen(mat2)$values
 > det(mat2)
[1] 228.4126
 > eigen(mat2)$values[1]/eigen(mat2)$values[6] # new condition number
[1] 57.58801

But that factor to be applied to the diagonal seems arbitrary at least  
to the extent that it is not any power of 0.2/0.1241385 that I can  
determine.

Played with changing the "lower-right corner element with very little  
effect. Then looking at eigenvector for the lowest eigenvalue,

 > eigen(mat)$vectors[6,]
[1] -0.66846249  0.10870793  0.32972715  0.07842753  0.60828836   
0.23760238

    .... and noting that its highest components in absolute magnitude   
were the first and fifth..... found that small alterations in the 5th  
diagonal also raised the eigenvalue.

 > mat2[5,5] <- mat[5,5]*1.110125 ... is this close to  1.01679^6
 > eigen(mat2)$values[6]
[1] 0.1999991
 > det(mat2)
[1] 199.4463  # so the impact on the det() is a bit less that  
"adjusting the diagonal"

 > mat2[5,5] <- mat[5,5]*1.110125
 > eigen(mat2)$values[1]/eigen(mat2)$values[6]
[1] 57.12198   very similar to diag-manipulated result


> of my original matrix "mat" as unaltered as possible.
>
> Is there any algorithm to achieve that?

I used successive approximation for the second method and third  
methods. You could, therefore, probably get optim() to do it. There is  
a literature on the effect of perturbations of matrices on  
eigenvalues, but I am not at all versed in it. Heck, I'm not  
particularly well-versed in matrix algebra for that matter. So these  
experiments should be seen as an effort at sel-learning on my part  
rather than any specific advice.

-- 
David Winsemius, MD
West Hartford, CT



More information about the R-help mailing list