Message Boards Message Boards

0
|
248 Views
|
7 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Define a sparse matrix from triplets

Posted 6 days ago

Have four binary files. Two of int32 being the indices or positions i and j. Two of double being the matching values in the sparse matrix A and b the RHS.

My question is I know how to read the binary files to get lists "i", "j" and "val". How do I define the sparse matrix from the lists?

POSTED BY: Terry Hendicott
7 Replies

Thanks Michael Working now. The LinearSolve cell crashes my system though. enter image description here

POSTED BY: Terry Hendicott

A couple of additional variants:

(* SET UP *)
SeedRandom[0]; (* optional, for reproducibility *)
dim = 2^16;
rowIdcs = RandomSample[Range[dim], 1000];(*i*)
colIdcs = RandomSample[Range[dim], 1000];(*j*)
entries = RandomReal[1, 1000];(*vals*)

sa1 = SparseArray[ (* first variant *)
   MapThread[{#1, #2} -> #3 &, {rowIdcs, colIdcs, entries}],
   {dim, dim}];

sa2 = SparseArray[ (* second variant *)
   Thread[Transpose[{rowIdcs, colIdcs}] -> entries],
   {dim, dim}];

sa2 == sa1
(*  True  *)

Some are uncomfortable with # and anonymous (or pure) functions. One can make a utility function on the fly. Here a couple variant, plus an anonymous one with named arguments.

ClearAll[entryRule];
entryRule[{i_, j_, val_}] := {i, j} -> val; (* Note {} in argument *)
sa3 = SparseArray[
   entryRule /@
    Thread[{rowIdcs, colIdcs, entries}],(* = triples *)
   {dim, dim}];

ClearAll[entryRuleL]; (* uses Listability instead of Map/Thread *)
SetAttributes[entryRuleL, Listable];
entryRuleL[i_, j_, val_] := {i, j} -> val; (* No {} in arguments *)
sa4 = SparseArray[entryRuleL[rowIdcs, colIdcs, entries], {dim, dim}];

sa5 = SparseArray[ (* anonymous variant of entryRuleL *)
   Function[{i, j, val}, {i, j} -> val, Listable][
    rowIdcs, colIdcs, entries],
   {dim, dim}];

sa5 == sa4 == sa3 == sa2 == sa1
(*  True  *)

Oh well, now it feels embarrassingly like overkill. :)

POSTED BY: Michael Rogers

Spoke to fast, the second statement produces a 16 736 562 x 1 matrix instead of 46 328 x 46 328 sparse matrix? enter image description here

POSTED BY: Terry Hendicott
Posted 6 days ago

Your second little grey information box including

Sparsearray[
 ...
{1,1}->{1,1}->20.8
....

shows something is very wrong for you to get {1,1}->{1,1}->20.8

Maybe I broke something in the way I coded that. I apologize.

Let me try coding that slightly differently

i={1,2,7};j={2,5,3};val={1.3,2.9,3.1};
rules=Map[Most[#]->Last[#]&,Thread[{i,j,val}]];
mat=SparseArray[rules]
MatrixForm[mat]

which I thought should be equivalent and which displays for me

Sparsearray[ Specified Elements 3, Dimensions (7,5)

( 0 1.3 0 0 0 )
( 0 0 0 0 2.9 )
( 0 0 0 0 0 )
( 0 0 0 0 0 )
( 0 0 0 0 0 )
( 0 0 0 0 0 )
( 0 0 3.1 0 0 )

Please try my tiny example and see if you get exactly the same result.

And, again this example is only doing the left hand side of your problem. Hopefully you can see how to use these ideas to do the right hand side of your problem.

If so then start with a tiny tiny subset of your 16.7 million elements and see if that works and if so then gradually work up by small amounts and see if it keeps working for larger and larger lists.

POSTED BY: Bill Nelson

Thank you Bill the array is formed nicely and LinearSolve is working

rules=Map[Most[#]->Last[#]&,Thread[{i,j,val}]];
mat=SparseArray[rules]
POSTED BY: Terry Hendicott

Thank you for your help. All is good statements work thank you.

POSTED BY: Terry Hendicott
Posted 6 days ago

Please test this very carefully

(*Given that you have read your three lists into i,j,val*)
triple=Thread[{i,j,val}];
mat=SparseArray[Map[{{#[[1]],#[[2]]}->#[[3]]}&,triple]]

If that is working exactly correctly then you might be able to see how to construct your RHS.

POSTED BY: Bill Nelson
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract