/* ========================================================================== */1/* === umf4_f77wrapper ====================================================== */2/* ========================================================================== */34/* -------------------------------------------------------------------------- */5/* UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis. CISE Dept, */6/* Univ. of Florida. All Rights Reserved. See ../Doc/License for License. */7/* web: http://www.cise.ufl.edu/research/sparse/umfpack */8/* -------------------------------------------------------------------------- */910/* FORTRAN interface for the C-callable UMFPACK library (double / int version11* only and double / long versions only). This is HIGHLY non-portable. You12* will need to modify this depending on how your FORTRAN and C compilers13* behave. This has been tested in Linux, Sun Solaris, SGI IRIX, and IBM AIX,14* with various compilers. It has not been exhaustively tested on all possible15* combinations of C and FORTRAN compilers. The long version works on16* Solaris, SGI IRIX, and IBM AIX when the UMFPACK library is compiled in17* 64-bit mode.18*19* Only a subset of UMFPACK's capabilities are provided. Refer to the UMFPACK20* User Guide for details.21*22* For some C and FORTRAN compilers, the FORTRAN compiler appends a single23* underscore ("_") after each routine name. C doesn't do this, so the24* translation is made here. Other FORTRAN compilers treat underscores25* differently. For example, a FORTRAN call to a_b gets translated to a call26* to a_b__ by g77, and to a_b_ by most other FORTRAN compilers. Thus, the27* FORTRAN names here do not use underscores. The xlf compiler in IBM AIX28* doesn't add an underscore.29*30* The matrix A is passed to UMFPACK in compressed column form, with 0-based31* indices. In FORTRAN, for an m-by-n matrix A with nz entries, the row32* indices of the first column (column 1) are in Ai (Ap (1) + 1 ... Ap (2)),33* with values in Ax (Ap (1) + 1 ... Ap (2)). The last column (column n) is34* in Ai (Ap (n) + 1 ... Ap (n+1)) and Ax (Ap (n) + 1 ... Ap (n+1)). The row35* indices in Ai are in the range 0 to m-1. They must be sorted, with no36* duplicate entries allowed. Refer to umfpack_di_triplet_to_col for a more37* flexible format for the input matrix. The following defintions apply38* for each of the routines in this file:39*40* integer m, n, Ap (n+1), Ai (nz), symbolic, numeric, filenum, status41* double precision Ax (nz), control (20), info (90), x (n), b (n)42*43* UMFPACK's status is returned in either a status argument, or in info (1).44* It is zero if everything is OK, 1 if the matrix is singular (this is a45* warning, not an error), and negative if an error occurred. See umfpack.h46* for more details on the contents of the control and info arrays, and the47* value of the sys argument.48*49* For the Numeric and Symbolic handles, it's probably safe to assume that a50* FORTRAN integer is sufficient to store a C pointer. If that doesn't work,51* try defining numeric and symbolic as integer arrays of size 2, or as52* integer*8, in the FORTRAN routine that calls these wrapper routines.53* The latter is required on Solaris, SGI IRIX, and IBM AIX when UMFPACK is54* compiled in 64-bit mode.55*56* If you want to use 64-bit integers, try compiling this file with the -DDLONG57* compiler option (via "make fortran64"). First modify your Make/Make.include58* and Make/Make.<arch> files to compile UMFPACK in LP64 mode (see the User59* Guide for details). Your FORTRAN code should use integer*8. See umf4hb64.f60* for an example.61*62* Tested with the following compilers:63* * Solaris with cc and f77 from Sun WorkShop 6 update 164* (32-bit and 64-bit modes)65* * SGI Irix with MIPSpro cc and f77 compilers version 7.466* (32-bit and 64-bit modes)67* * Linux with GNU gcc and Intel's icc, and GNU g77 and Intel's68* ifc FORTRAN compiler. See the comments above about g77 and69* underscores. Only supports 32-bit mode.70* * IBM AIX xlc and xlf compilers.71* (32-bit and 64-bit modes)72*/7374#include "umfpack.h"75#include <ctype.h>76#include <stdio.h>77#ifdef NULL78#undef NULL79#endif80#define NULL 081#define LEN 2008283/* -------------------------------------------------------------------------- */84/* integer type: int or long */85/* -------------------------------------------------------------------------- */8687#if defined (DLONG)8889#define Int long90#define UMFPACK_defaults umfpack_dl_defaults91#define UMFPACK_free_numeric umfpack_dl_free_numeric92#define UMFPACK_free_symbolic umfpack_dl_free_symbolic93#define UMFPACK_numeric umfpack_dl_numeric94#define UMFPACK_report_control umfpack_dl_report_control95#define UMFPACK_report_info umfpack_dl_report_info96#define UMFPACK_save_numeric umfpack_dl_save_numeric97#define UMFPACK_save_symbolic umfpack_dl_save_symbolic98#define UMFPACK_load_numeric umfpack_dl_load_numeric99#define UMFPACK_load_symbolic umfpack_dl_load_symbolic100#define UMFPACK_scale umfpack_dl_scale101#define UMFPACK_solve umfpack_dl_solve102#define UMFPACK_symbolic umfpack_dl_symbolic103104#else105106#define Int int107#define UMFPACK_defaults umfpack_di_defaults108#define UMFPACK_free_numeric umfpack_di_free_numeric109#define UMFPACK_free_symbolic umfpack_di_free_symbolic110#define UMFPACK_numeric umfpack_di_numeric111#define UMFPACK_report_control umfpack_di_report_control112#define UMFPACK_report_info umfpack_di_report_info113#define UMFPACK_save_numeric umfpack_di_save_numeric114#define UMFPACK_save_symbolic umfpack_di_save_symbolic115#define UMFPACK_load_numeric umfpack_di_load_numeric116#define UMFPACK_load_symbolic umfpack_di_load_symbolic117#define UMFPACK_scale umfpack_di_scale118#define UMFPACK_solve umfpack_di_solve119#define UMFPACK_symbolic umfpack_di_symbolic120121#endif122123/* -------------------------------------------------------------------------- */124/* construct a file name from a file number (not user-callable) */125/* -------------------------------------------------------------------------- */126127static void make_filename (Int filenum, char *prefix, char *filename)128{129char *psrc, *pdst ;130#ifdef DLONG131sprintf (filename, "%s%ld.umf", prefix, filenum) ;132#else133sprintf (filename, "%s%d.umf", prefix, filenum) ;134#endif135/* remove any spaces in the filename */136pdst = filename ;137for (psrc = filename ; *psrc ; psrc++)138{139if (!isspace (*psrc)) *pdst++ = *psrc ;140}141*pdst = '\0' ;142}143144/* ========================================================================== */145/* === with underscore ====================================================== */146/* ========================================================================== */147148/* Solaris, Linux, and SGI IRIX. Probably Compaq Alpha as well. */149150/* -------------------------------------------------------------------------- */151/* umf4def: set default control parameters */152/* -------------------------------------------------------------------------- */153154/* call umf4def (control) */155156void umf4def_ (double Control [UMFPACK_CONTROL])157{158UMFPACK_defaults (Control) ;159}160161/* -------------------------------------------------------------------------- */162/* umf4pcon: print control parameters */163/* -------------------------------------------------------------------------- */164165/* call umf4pcon (control) */166167void umf4pcon_ (double Control [UMFPACK_CONTROL])168{169fflush (stdout) ;170UMFPACK_report_control (Control) ;171fflush (stdout) ;172}173174/* -------------------------------------------------------------------------- */175/* umf4sym: pre-ordering and symbolic factorization */176/* -------------------------------------------------------------------------- */177178/* call umf4sym (m, n, Ap, Ai, Ax, symbolic, control, info) */179180void umf4sym_ (Int *m, Int *n, Int Ap [ ], Int Ai [ ],181double Ax [ ], void **Symbolic,182double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])183{184(void) UMFPACK_symbolic (*m, *n, Ap, Ai, Ax, Symbolic, Control, Info) ;185}186187/* -------------------------------------------------------------------------- */188/* umf4num: numeric factorization */189/* -------------------------------------------------------------------------- */190191/* call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info) */192193void umf4num_ (Int Ap [ ], Int Ai [ ], double Ax [ ],194void **Symbolic, void **Numeric,195double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])196{197(void) UMFPACK_numeric (Ap, Ai, Ax, *Symbolic, Numeric, Control, Info);198}199200/* -------------------------------------------------------------------------- */201/* umf4solr: solve a linear system with iterative refinement */202/* -------------------------------------------------------------------------- */203204/* call umf4solr (sys, Ap, Ai, Ax, x, b, numeric, control, info) */205206void umf4solr_ (Int *sys, Int Ap [ ], Int Ai [ ], double Ax [ ],207double x [ ], double b [ ], void **Numeric,208double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])209{210(void) UMFPACK_solve (*sys, Ap, Ai, Ax, x, b, *Numeric, Control, Info) ;211}212213/* -------------------------------------------------------------------------- */214/* umf4sol: solve a linear system without iterative refinement */215/* -------------------------------------------------------------------------- */216217/* call umf4sol (sys, x, b, numeric, control, info) */218219void umf4sol_ (Int *sys, double x [ ], double b [ ], void **Numeric,220double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])221{222Control [UMFPACK_IRSTEP] = 0 ;223(void) UMFPACK_solve (*sys, (Int *) NULL, (Int *) NULL, (double *) NULL,224x, b, *Numeric, Control, Info) ;225}226227/* -------------------------------------------------------------------------- */228/* umf4scal: scale a vector using UMFPACK's scale factors */229/* -------------------------------------------------------------------------- */230231/* call umf4scal (x, b, numeric, status) */232233void umf4scal_ (double x [ ], double b [ ], void **Numeric, Int *status)234{235*status = UMFPACK_scale (x, b, *Numeric) ;236}237238/* -------------------------------------------------------------------------- */239/* umf4pinf: print info */240/* -------------------------------------------------------------------------- */241242/* call umf4pinf (control) */243244void umf4pinf_ (double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])245{246fflush (stdout) ;247UMFPACK_report_info (Control, Info) ;248fflush (stdout) ;249}250251/* -------------------------------------------------------------------------- */252/* umf4fnum: free the Numeric object */253/* -------------------------------------------------------------------------- */254255/* call umf4fnum (numeric) */256257void umf4fnum_ (void **Numeric)258{259UMFPACK_free_numeric (Numeric) ;260}261262/* -------------------------------------------------------------------------- */263/* umf4fsym: free the Symbolic object */264/* -------------------------------------------------------------------------- */265266/* call umf4fsym (symbolic) */267268void umf4fsym_ (void **Symbolic)269{270UMFPACK_free_symbolic (Symbolic) ;271}272273/* -------------------------------------------------------------------------- */274/* umf4snum: save the Numeric object to a file */275/* -------------------------------------------------------------------------- */276277/* call umf4snum (numeric, filenum, status) */278279void umf4snum_ (void **Numeric, Int *filenum, Int *status)280{281char filename [LEN] ;282make_filename (*filenum, "n", filename) ;283*status = UMFPACK_save_numeric (*Numeric, filename) ;284}285286/* -------------------------------------------------------------------------- */287/* umf4ssym: save the Symbolic object to a file */288/* -------------------------------------------------------------------------- */289290/* call umf4ssym (symbolic, filenum, status) */291292void umf4ssym_ (void **Symbolic, Int *filenum, Int *status)293{294char filename [LEN] ;295make_filename (*filenum, "s", filename) ;296*status = UMFPACK_save_symbolic (*Symbolic, filename) ;297}298299/* -------------------------------------------------------------------------- */300/* umf4lnum: load the Numeric object from a file */301/* -------------------------------------------------------------------------- */302303/* call umf4lnum (numeric, filenum, status) */304305void umf4lnum_ (void **Numeric, Int *filenum, Int *status)306{307char filename [LEN] ;308make_filename (*filenum, "n", filename) ;309*status = UMFPACK_load_numeric (Numeric, filename) ;310}311312/* -------------------------------------------------------------------------- */313/* umf4lsym: load the Symbolic object from a file */314/* -------------------------------------------------------------------------- */315316/* call umf4lsym (symbolic, filenum, status) */317318void umf4lsym_ (void **Symbolic, Int *filenum, Int *status)319{320char filename [LEN] ;321make_filename (*filenum, "s", filename) ;322*status = UMFPACK_load_symbolic (Symbolic, filename) ;323}324325/* ========================================================================== */326/* === with no underscore =================================================== */327/* ========================================================================== */328329/* IBM AIX. Probably Microsoft Windows and HP Unix as well. */330331/* -------------------------------------------------------------------------- */332/* umf4def: set default control parameters */333/* -------------------------------------------------------------------------- */334335/* call umf4def (control) */336337void umf4def (double Control [UMFPACK_CONTROL])338{339UMFPACK_defaults (Control) ;340}341342/* -------------------------------------------------------------------------- */343/* umf4pcon: print control parameters */344/* -------------------------------------------------------------------------- */345346/* call umf4pcon (control) */347348void umf4pcon (double Control [UMFPACK_CONTROL])349{350fflush (stdout) ;351UMFPACK_report_control (Control) ;352fflush (stdout) ;353}354355/* -------------------------------------------------------------------------- */356/* umf4sym: pre-ordering and symbolic factorization */357/* -------------------------------------------------------------------------- */358359/* call umf4sym (m, n, Ap, Ai, Ax, symbolic, control, info) */360361void umf4sym (Int *m, Int *n, Int Ap [ ], Int Ai [ ],362double Ax [ ], void **Symbolic,363double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])364{365(void) UMFPACK_symbolic (*m, *n, Ap, Ai, Ax, Symbolic, Control, Info) ;366}367368/* -------------------------------------------------------------------------- */369/* umf4num: numeric factorization */370/* -------------------------------------------------------------------------- */371372/* call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info) */373374void umf4num (Int Ap [ ], Int Ai [ ], double Ax [ ],375void **Symbolic, void **Numeric,376double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])377{378(void) UMFPACK_numeric (Ap, Ai, Ax, *Symbolic, Numeric, Control, Info);379}380381/* -------------------------------------------------------------------------- */382/* umf4solr: solve a linear system with iterative refinement */383/* -------------------------------------------------------------------------- */384385/* call umf4solr (sys, Ap, Ai, Ax, x, b, numeric, control, info) */386387void umf4solr (Int *sys, Int Ap [ ], Int Ai [ ], double Ax [ ],388double x [ ], double b [ ], void **Numeric,389double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])390{391(void) UMFPACK_solve (*sys, Ap, Ai, Ax, x, b, *Numeric, Control, Info) ;392}393394/* -------------------------------------------------------------------------- */395/* umf4sol: solve a linear system without iterative refinement */396/* -------------------------------------------------------------------------- */397398/* call umf4sol (sys, x, b, numeric, control, info) */399400void umf4sol (Int *sys, double x [ ], double b [ ], void **Numeric,401double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])402{403Control [UMFPACK_IRSTEP] = 0 ;404(void) UMFPACK_solve (*sys, (Int *) NULL, (Int *) NULL, (double *) NULL,405x, b, *Numeric, Control, Info) ;406}407408/* -------------------------------------------------------------------------- */409/* umf4scal: scale a vector using UMFPACK's scale factors */410/* -------------------------------------------------------------------------- */411412/* call umf4scal (x, b, numeric, status) */413414void umf4scal (double x [ ], double b [ ], void **Numeric, Int *status)415{416*status = UMFPACK_scale (x, b, *Numeric) ;417}418419/* -------------------------------------------------------------------------- */420/* umf4pinf: print info */421/* -------------------------------------------------------------------------- */422423/* call umf4pinf (control) */424425void umf4pinf (double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])426{427fflush (stdout) ;428UMFPACK_report_info (Control, Info) ;429fflush (stdout) ;430}431432/* -------------------------------------------------------------------------- */433/* umf4fnum: free the Numeric object */434/* -------------------------------------------------------------------------- */435436/* call umf4fnum (numeric) */437438void umf4fnum (void **Numeric)439{440UMFPACK_free_numeric (Numeric) ;441}442443/* -------------------------------------------------------------------------- */444/* umf4fsym: free the Symbolic object */445/* -------------------------------------------------------------------------- */446447/* call umf4fsym (symbolic) */448449void umf4fsym (void **Symbolic)450{451UMFPACK_free_symbolic (Symbolic) ;452}453454/* -------------------------------------------------------------------------- */455/* umf4snum: save the Numeric object to a file */456/* -------------------------------------------------------------------------- */457458/* call umf4snum (numeric, filenum, status) */459460void umf4snum (void **Numeric, Int *filenum, Int *status)461{462char filename [LEN] ;463make_filename (*filenum, "n", filename) ;464*status = UMFPACK_save_numeric (*Numeric, filename) ;465}466467/* -------------------------------------------------------------------------- */468/* umf4ssym: save the Symbolic object to a file */469/* -------------------------------------------------------------------------- */470471/* call umf4ssym (symbolic, filenum, status) */472473void umf4ssym (void **Symbolic, Int *filenum, Int *status)474{475char filename [LEN] ;476make_filename (*filenum, "s", filename) ;477*status = UMFPACK_save_symbolic (*Symbolic, filename) ;478}479480/* -------------------------------------------------------------------------- */481/* umf4lnum: load the Numeric object from a file */482/* -------------------------------------------------------------------------- */483484/* call umf4lnum (numeric, filenum, status) */485486void umf4lnum (void **Numeric, Int *filenum, Int *status)487{488char filename [LEN] ;489make_filename (*filenum, "n", filename) ;490*status = UMFPACK_load_numeric (Numeric, filename) ;491}492493/* -------------------------------------------------------------------------- */494/* umf4lsym: load the Symbolic object from a file */495/* -------------------------------------------------------------------------- */496497/* call umf4lsym (symbolic, filenum, status) */498499void umf4lsym (void **Symbolic, Int *filenum, Int *status)500{501char filename [LEN] ;502make_filename (*filenum, "s", filename) ;503*status = UMFPACK_load_symbolic (Symbolic, filename) ;504}505506507