Using Eigen rankupdate - sparse-matrix

We solve (via Cholesky decomp) large electrical networks in which only a small percentage of values change between iterations. The network is very sparse and SPD. Solve requires that need to factorize the entire matrix at each step.
My understanding (if correct) is that there are methods available, such as rankUpdate, to directly adjust the factorized matrix which may improve solve times. In our case, each element change results in a change to 2 or 3 rows, and the corresponding 2 or 3 columns.
Can anyone offer a brief discussion and simple example of how rankUpdate is used, or correct my understanding?
This would be very much appreciated.
Thanks
Kevin

In Eigen's Cholesky solvers, rank-updates are available only for dense solvers, e.g.:
LDLT chol(A); // initial factorization
chol.rankUpdate(V,s);
At this stage chol is equvalent to the factorization of A+s*V*V^T.
For sparse problems, this is not supported yet but CHOLMOD from Suite-Sparse does support rank-updates. The best, and likely simplest, way would be add such a rankUpdate method to the Eigen::CholmodLLT class as a thin wrapper to the underlying CHOLMOD routine.

Related

How to obtain the derivative of Rodrigues vector and perform update in nonlinear least square?

I am now interested in the bundle adjustment in SLAM, where the Rodrigues vectors $R$ of dimension 3 are used as part of variables. Assume, without loss of generality, we use Gauss-Newton method to solve it, then in each step we need to solve the following linear least square problem:
$$J(x_k)\Delta x = -F(x_k),$$
where $J$ is the Jacobi of $F$.
Here I am wondering how to calculate the derivative $\frac{\partial F}{\partial R}$. Is it just like the ordinary Jacobi in mathematic analysis? I have this wondering because when I look for papers, I find many other concepts like exponential map, quaternions, Lie group and Lie algebra. So I suspect if there is any misunderstanding.
This is not an answer, but is too long for a comment.
I think you need to give more information about how the Rodrigues vector appears in your F.
First off, is the vector assumed to be of unit length.? If so that presents some difficulties as now it doesn't have 3 independent components. If you know that the vector will lie in some region (eg that it's z component will always be positive), you can work round this.
If instead the vector is normalised before use, then while you could then compute the derivatives, the resulting Jacobian will be singular.
Another approach is to use the length of the vector as the angle through which you rotate. However this means you need a special case to get a rotation through 0, and the resulting function is not differentiable at 0. Of course if this can never occur, you may be ok.

Optimizing sparse matrix solve time

Our simulations have large very sparse sets of SPD equations (a resistive network with current sources). We solve Ax = b, where A is conductance matrix and b is the current vector. We have effective solution methods (Eigen/sparse and/or Tim Davis's LDL). During the simulation, only a few of the elements in A change between time steps, but we need to factorize the entire matrix for the new solution (though we can avoid the ordering step in many cases).
We are wondering if there are methods that could segregate the fixed portion in A from the dynamic portions, factorize the fixed portions separately from the dynamic, then combine the two for the solution (forward/back substitution). From a top level understanding of standard solution methods, my sense is that this is not possible. But .... ??
Thanks in advance
Kevin

Raise matrix to complex power

I'm implementing a library which makes use of the GSL for matrix operations. I am now at a point where I need to raise things to any power, including imaginary ones. I already have the code in place to handle negative powers of a matrix, but now I need to handle imaginary powers, since all numbers in my library are complex.
Does the GSL have facilities for doing this already, or am I about to enter loop hell trying to create an algorithm for this? I need to be able to raise not only to imaginary but also complex numbers, such as 3+2i. Having limited experience with matrices as a whole, I'm not even certain on the process for doing this by hand, much less with a computer.
Hmm I never thought the electrical engineering classes I went through would help me on here, but what do you know. So the process for raising something to a complex power is not that complex and I believe you could write something fairly easily (I am not too familiar with the library your using, but this should still work with any library that has some basic complex number functions).
First your going to need to change the number to polar coordinates (i.e 3 + 3i would become (3^2 + 3^2) ^(1/2) angle 45 degrees. Pardon the awful notation. If you are confused on the process of changing the numbers over just do some quick googling on converting from cartesian to polar.
So now that you have changed it to polar coordinates you will have some radius r at an angle a. Lets raise it to the nth power now. You will then get r^n * e^(jan).
If you need more examples on this, research the "general power rule for complex numbers." Best of luck. I hope this helps!
Just reread the question and I see you need to raise to complex as well as imaginary. Well complex and imaginary are going to be the same just with one extra step using the exponent rule. This link will quickly explain how to raise something to a complex http://boards.straightdope.com/sdmb/showthread.php?t=261399
One approach would be to compute (if possible) the logarithm of your matrix, multiply that by your (complex) exponent, and then exponentiate.
That is you could have
mat_pow( M, z) = mat_exp( z * mat_log( M));
However mat_log and even mat_exp are tricky.
In case it is still relevant to you, I have extended the capabilities of my package so that now you can raise any diagonalizable matrix to any power (including, in particular, complex powers). The name of the function is 'Matpow', and can be found in package 'powerplus'. Also, this package is for the R language, not C, but perhaps you could do your calculations in R if needed.
Edit: Version 3.0 extends capabilities to (some) non-diagonalizable matrices too.
I hope it helps!

How to remove apparent redundency in numpy vector operations?

New to python and not sure about efficiency issues here. For vectors x, y, and z that represent the coordinates of n particles I can do the following computation
import numpy as np
X=np.subtract.outer(x,x)
Y=np.subtract.outer(y,y)
Z=np.subtract.outer(z,z)
R=np.sqrt(X**2+Y**2+Z**2)
A=X/R
np.fill_diagonal(A,0)
a=np.sum(A,axis=0)
With this calculation there is about a factor of 2 in redundancy in so far as multiplications and divisions go as the diagonals are not needed and the lower diagonal is just the negative of the upper diagonal. I plan to use this kind of computation inside a function call that is used by odeint - i.e. it would be called a lot and the vectors will be large - as large as my computer will handle. To remove it, naively I would end up doing a for loop which presumably is a stupid thing to do. Can I get rid of this redundancy in a vectorized way or is it even worth the effort?
Update: Based on the suggestions below, the only way I could see to improve was
ut=np.triu_indices(n,1)
X=x[ut[0]]-x[ut[1]]
With similar expressions for Y and Z and using pdist to find R. This construction only calculates the upper triangular part. Looking at the source code for pdist I am not convinced it does anything particularly smart so I think my expression above would be equally good. The use of squareform only produces the symmetric form. For the antisymmetric may as well use
B=np.zeros((n,n),dtype=np.float64)
B(ut[0],ut[1])=A
B=B-B.T
This cannot be slower than square form because this is pretty much exactly what squareform does. Since the function is called often it would seem to me that ut should be made static along with storage for others (X,Y,Z,A,B). However being new to python I'm not sure how that is done.

Preconditioning of a linear system

I have a large sparse linear system generated as a part of PDE solution for flows in the form Ax=b. The condition number of matrix A is very bad - of the order 3000!. But I get expected solutions with direct solvers. So, now I want to precondition the matrix so that I can use iterative solvers and use the sparseness. I have tried Jacobi preconditioner, but it does not work well as the matrix is not diagonally dominant. I need some help in proceeding further:
1) Imagine I get an approximate solution for x (generated by one run of biconjugate gradient solver). Now can I get "inverse of A" (for preconditioning) from this, seems like it must be possible but I am unable to figure out how! i.e knowing x and b can I calculate the A inverse (which may be used as preconditioner!).
2) Any other way of preconditioning which you feel would be worth a try?
3) Any way to circumvent pre-conditioning for iterative schemes for bad condition number systems?
Thanks a lot in advance for any help. Any comments are welcome.

Resources