cpmech / russell

Rust Scientific Libary. ODE and DAE (Runge-Kutta) solvers. Special functions (Bessel, Elliptic, Beta, Gamma, Erf). Linear algebra. Sparse solvers (MUMPS, UMFPACK). Probability distributions. Tensor calculus.
MIT License
114 stars 8 forks source link

Need to have acces to Element in SparseTriplet #46

Closed jgsimard closed 1 year ago

jgsimard commented 1 year ago

Hi, First , thanks for the amazing library!

I am using SparseTriplet to solve a sparse Ax =b;

I am using A.put(i, j, 1000.0)? and it works great, but sometimes, I need to update the value as (i,j) but I dont see a SparseTriplet.get(i,j) function.

How should I do this?

Thanks

cpmech commented 1 year ago

Hi there. Thanks for your interest in Russell!

The reason for not having a get method in SparseTriplet is that it allows duplicates. Thus, to get a value, we would have to peruse the whole data structure to find duplicates and sum their values. This is the goal of SparseTriplet by design. It is a temporary data structure to be converted into a compressed-column-sparse matrix (internally).

Regarding updates of SparseTriplet, the correct way is to call the reset method and then call put for all values (all over again). This is not so expensive, and it is how I use it in finite element simulations, for example.

In summary, we would have to create another SparseTriplet structure that would not allow duplicates to enable real-time updates.

Regards

jgsimard commented 1 year ago

thanks!

cpmech commented 1 year ago

For future reference:

We cannot get a specific value a(i,j) from a SparseTriplet because we don't know the inverse mapping i,j => pos. Let us recall that the order of items in the triplet is random, with the pos pointer growing as the user "puts" values in the triplet.

To allow the recovery of values given (i,j), we would have to either search all items or save a mapping i,j => pos. However, with duplicates, this would require a counter for how many times the user put a value into i,j (for the mapping solution).

Regardless, with duplicates or not, a loss in efficiency (and more memory usage) would occur.

Therefore, it seems (not thoroughly verified) that the use of reset and put for implementing updates of SparseTriplet is a good cost-effective solution.

Alternatively, one way to get values from the SparseTriplet is to use either as_matrix or to_matrix that returns all values (summing eventual duplicates)---the to_matrix method allows the reuse of an existent matrix avoiding repetitive memory allocation.

jgsimard commented 1 year ago

For a bad reference : My "solution" was to build a hashmap where key = (i,j) and value = f64, update incrementally the values in the hashmap, then put everything at once in the SparseTriplet