| SOY/i Contents |
|---|
March 2009: SOI release v1.3 (IDL)
Download: soi.tgz
Long time no update.. This is the latest version of SOI/PTSOI for IDL. I have not kept track of the changes, but they are mainly minor bug fixes, and a few new functions for specialized matrix creation. The new library PTSOI implements a couple of functions (rcovx, rcoata) with POSIX threads, for multi-threading on multi-core computers. Have also added a README text file and a "check.pro" script for testing the installation.
2005-Dec-01: SOI release v1.2 (IDL)
2005-Oct-07: SOY release v1.2.01
SOY/i (Sparse Operations with Yorick/IDL) originates from a collection of IDL/C routines that I originally put together for a specific purpose: efficient wavefront reconstruction in adaptive optics simulations. Seeing as its application is more general than that, however, I offer it here as a self-contained sparse matrix plugin for Yorick and IDL, with the time-critical functions coded in ANSI C.
If you encounter problems or discover bugs, you can send me an email (given in the README file, or on my home page).
Revision history: 2005/12/01: SOI v1.2 - New IDL version released 2005/10/07: SOY v1.2.01 - Several minor revisions and bugfixes 2005/04/11: SOY v1.2 - Updated for Yorick v1.6.02 - Ported for 64-bit OS compatibility 2004/11/18: SOY v1.1 - Adapted as a plugin for Yorick v1.6.01 - Memory management from Yorick scripting level 2004/11/14: SOY v1.0 - Wrappers translated from IDL to Yorick (v1.5.15) |
(A few important things when using SOY: read the fine print)
| Download SOY/i v1.2 for Yorick/IDL (soyi.tar.gz) |
Tarball contents:
Yorick installation (Yorick v1.6.02):
| Gain of the sparse method versus fill of the matrix, for all tests above: |
A two-dimensional real matrix A may be represented in RR(C)O by specifying the three vectors IX, JX and XN:
0. 9. 7. 0. 0.
A = 0. 8. 0. 7. 7.
8. 0. 7. 0. 9.
|
IX = [ 0 2 5 8 ] JX = [ 1 2 1 3 4 0 2 4 ] XN = [ 9. 7. 8. 7. 7. 8. 7. 9.] |
For a symmetric matrix S the rules are the same, except that the RR(U)O format stores the diagonal separately in the vector XD, and only the upper triangle of S are stored in IX, JX and XN. For instance:
1. 0. 4. 2.
S = 0. 2. 0. 1.
4. 0. 3. 0.
2. 1. 0. 5.
|
IX = [ 0 2 3 ] JX = [ 1 2 2 ] XN = [ 4. 2. 1.] XD = [ 1. 2. 3. 5.] |
References
| matrix type : | RR(C)O | RR(U)O |
| Structure definition (float) |
struct rco
{
int r;
int c;
int n;
pointer ix;
pointer jx;
pointer xn;
float t;
}
|
struct ruo
{
int r;
int n;
pointer ix;
pointer jx;
pointer xn;
pointer xd;
float t;
}
|
|---|---|---|
| Structure definition (double) |
struct rco_d
{
int r;
int c;
int n;
pointer ix;
pointer jx;
pointer xn;
double t;
}
|
struct ruo_d
{
int r;
int n;
pointer ix;
pointer jx;
pointer xn;
pointer xd;
double t;
}
|
| Instantiation (float) |
a = rco(); |
s = ruo(); |
| Instantiation (double) |
a = rco_d(); |
s = ruo_d(); |
| Conversion full→sparse | a = sprco(A); |
s = spruo(S); |
| Conversion sparse→full | A = rcoinf(a); |
S = ruoinf(s); |
| Conversion RUO→RCO | a = ruo2rco(s); |
| Matrix-scalar mult. | rcox,a,scalar; |
ruox,s,scalar; |
|---|---|---|
| Matrix-vector mult. | u = rcoxv(a,v); |
u = ruoxv(s,v); |
| Matrix-matrix mult. | c = rcoatb(a,b); |
s = rcoata(a); |
| Matrix-matrix addition | c = rcoadd(a,b); |
s = ruoadd(s2,s3); |
| Matrix transpose | at = rcotr(a); |
|
|---|---|---|
| Append rows | rcobuild,a,v,t; |
|
| Delete rows | rcodr,a,r; |
|
| Concatennate matrices | spcon,a,b,diag=,ruo=; |
spcon,a,b,diag=,ruo=; |
| Split RUO matrix into upper+lower+diagonal |
ptr = ruo_UDL(s); |
| Conjugate gradient solver | v = ruopcg(a,b,x0,&nit,tol=,itmax=,sgs=); |
|---|
| Save to file | save_rco,a,file; |
save_ruo,s,file; |
|---|---|---|
| Read from file | a = restore_rco(file); |
s = restore_ruo(file); |
| Laplacian operator | a = Laplace_FDA(nx,aind); |
|
| Interpolation operator | ptr = intop(dimlist); |
| Structure info | spinfo,a; |
|---|
Matrix multiplications
Currently, only multiplication between RCO matrices is implemented, in the functions rcoatb(a,b) ("a transpose b") and rcoata(a) ("a transpose a"). RUO multiplication is considerably more complicated to code, and I didn't do it yet. Solution: use ruo2rco(a) to convert your RUO matrices to RCO. This conversion function is reasonably efficient even though it has to call both rcotr and rcoadd. It is probably not a good solution, however, if you need to do it repeatedly and fast, e.g. in a loop.
Memory management
extern MR,MN; within your script. The second is invoked by activating the keywords (ur=,un=) when calling the function. Their meaning are the same: MR and ur indicate the maximum number of rows to accomodate (i.e. the length of the IX vector, and also XD in RUO), MN and un the maximum number of non-zero elements to store (i.e. the lengths of JX and XN).
MR and MN values that you think will cover most of your applications without hogging too much memory, and in the special cases when something falls outside of this range, use the (ur=,un=) keywords to override. Note: in the case when ur and un are not given explicitly, MR and MN must be defined globally.
Building sparse matrices
sprco or spruo). It is only at this level that the sparse method becomes really valuable - if the complexities of your matrices are such that you can still define them and operate with them explicitly, well, then you don't really need this package.
rcobuild(&a,v,t) builds an RCO matrix row by row. Each call to rcobuild appends a vector v to the RCO structure a, discarding elements below the threshold t. If you can come up with an algorithm that decribes your matrix row by row, you will thus never need to define it explicitly.
Portability issues
typedef statemets in soy.c are gone, and long are redefined as int. However, the code has not been adapted to make use of the extended address space of a true 64-bit architecture. Pointers are still being dereferenced to integers, which means that truncation would occur if memory beyond the 32-bit address space was used, with strage behavior and/or segmentation errors ensuing. The v1.2 release has been verified on an 2GB AMD64 architecture with Yorick 1.6.02 compiled both to 64-bit and 32-bit (using the "-m32 -malign-double" compilation flags) versions under Red Hat Enterprise Linux 3, and also on a G4 Mac OS under 10.3.8 (32-bit). If you encouter problems with this version of SOY on a specific platform, please send a bug report to
.
Explicit handling of sparse structures
a = rco().
a.r, a.c and a.n must be set to the number of rows, columns (only RCO), and elements.
a.t (threshold) is optional, and should defaults to 0 if not set.
a.ix, a.jx, a.xn and a.xd (only RUO) must be dereferenced to integer (IX and JX) arrays and floating point (XN and XD) arrays of the proper size. That is, with ur and un as defined in the paragraph above ("Memory management"):
a.ix = &array(int,ur)
a.jx = &array(int,un)
a.xn = &array(float,un)
a.xd = &array(float,ur) (only RUO)
IX and JX vectors observe a 0-indexing convention! to conform with the C description. Careful not to confuse this with Yorick's 1-indexing when writing scripts....that way lies madness.
(*a.xn)(i), for element i.
a = array(rco,3). Then (*a(j).xn)(i) is the i'th element of the IX vector of the j'th RCO matrix.
License
Credits