~ubuntu-branches/ubuntu/natty/suitesparse/natty

« back to all changes in this revision

Viewing changes to COLAMD/colamdmex.c

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme
  • Date: 2007-05-29 09:36:29 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529093629-zowquo0b7slkk6nc
Tags: 3.0.0-2
* suitesparse builds properly twice in a row
* Bug fix: "suitesparse - FTBFS: Broken build depens: libgfortran1-dev",
  thanks to Bastian Blank (Closes: #426349).
* Bug fix: "suitesparse_3.0.0-1: FTBFS: build-depends on
  libgfortran1-dev", thanks to Steve Langasek (Closes: #426354).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ========================================================================== */
2
 
/* === colamd mexFunction =================================================== */
3
 
/* ========================================================================== */
4
 
 
5
 
/* COLAMD Version 2.5
6
 
 
7
 
    Usage:
8
 
 
9
 
        P = colamd (A) ;
10
 
        [ P, stats ] = colamd (A, knobs) ;
11
 
 
12
 
    see colamd.m for a description.
13
 
 
14
 
    Authors:
15
 
 
16
 
        The authors of the code itself are Stefan I. Larimore and Timothy A.
17
 
        Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
18
 
        developed in collaboration with John Gilbert, Xerox PARC, and Esmond
19
 
        Ng, Oak Ridge National Laboratory.
20
 
 
21
 
    Acknowledgements:
22
 
 
23
 
        This work was supported by the National Science Foundation, under
24
 
        grants DMS-9504974 and DMS-9803599.
25
 
 
26
 
    Notice:
27
 
 
28
 
        Copyright (c) 1998-2006, Timothy A. Davis, All Rights Reserved.
29
 
 
30
 
        See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c
31
 
        file) for the License.
32
 
 
33
 
    Availability:
34
 
 
35
 
        The colamd/symamd library is available at
36
 
 
37
 
            http://www.cise.ufl.edu/research/sparse/colamd/
38
 
 
39
 
        This is the http://www.cise.ufl.edu/research/sparse/colamd/colamdmex.c
40
 
        file.  It requires the colamd.c and colamd.h files.
41
 
 
42
 
*/
43
 
 
44
 
/* ========================================================================== */
45
 
/* === Include files ======================================================== */
46
 
/* ========================================================================== */
47
 
 
48
 
#include "colamd.h"
49
 
#include "mex.h"
50
 
#include "matrix.h"
51
 
#include <stdlib.h>
52
 
#include <string.h>
53
 
 
54
 
/* ========================================================================== */
55
 
/* === colamd mexFunction =================================================== */
56
 
/* ========================================================================== */
57
 
 
58
 
void mexFunction
59
 
(
60
 
    /* === Parameters ======================================================= */
61
 
 
62
 
    int nlhs,                   /* number of left-hand sides */
63
 
    mxArray *plhs [],           /* left-hand side matrices */
64
 
    int nrhs,                   /* number of right--hand sides */
65
 
    const mxArray *prhs []      /* right-hand side matrices */
66
 
)
67
 
{
68
 
    /* === Local variables ================================================== */
69
 
 
70
 
    int *A ;                    /* colamd's copy of the matrix, and workspace */
71
 
    int *p ;                    /* colamd's copy of the column pointers */
72
 
    int Alen ;                  /* size of A */
73
 
    int n_col ;                 /* number of columns of A */
74
 
    int n_row ;                 /* number of rows of A */
75
 
    int nnz ;                   /* number of entries in A */
76
 
    int full ;                  /* TRUE if input matrix full, FALSE if sparse */
77
 
    double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */
78
 
    double *out_perm ;          /* output permutation vector */
79
 
    double *out_stats ;         /* output stats vector */
80
 
    double *in_knobs ;          /* input knobs vector */
81
 
    int i ;                     /* loop counter */
82
 
    mxArray *Ainput ;           /* input matrix handle */
83
 
    int spumoni ;               /* verbosity variable */
84
 
    int stats [COLAMD_STATS] ;  /* stats for colamd */
85
 
 
86
 
    colamd_printf = mexPrintf ; /* COLAMD printf routine */
87
 
 
88
 
    /* === Check inputs ===================================================== */
89
 
 
90
 
    if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2)
91
 
    {
92
 
        mexErrMsgTxt (
93
 
        "colamd: incorrect number of input and/or output arguments") ;
94
 
    }
95
 
 
96
 
    /* === Get knobs ======================================================== */
97
 
 
98
 
    colamd_set_defaults (knobs) ;
99
 
    spumoni = 0 ;
100
 
 
101
 
    /* check for user-passed knobs */
102
 
    if (nrhs == 2)
103
 
    {
104
 
        in_knobs = mxGetPr (prhs [1]) ;
105
 
        i = mxGetNumberOfElements (prhs [1]) ;
106
 
        if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ;
107
 
        if (i > 1) knobs [COLAMD_DENSE_COL] = in_knobs [1] ;
108
 
        if (i > 2) spumoni = (int) (in_knobs [2] != 0) ;
109
 
    }
110
 
 
111
 
    /* print knob settings if spumoni is set */
112
 
    if (spumoni)
113
 
    {
114
 
        mexPrintf ("\ncolamd version %d.%d, %s:\n",
115
 
            COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ;
116
 
        if (knobs [COLAMD_DENSE_ROW] >= 0)
117
 
        {
118
 
            mexPrintf ("knobs(1): %g, rows with > max(16,%g*sqrt(size(A,2)))"
119
 
                " entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ;
120
 
        }
121
 
        else
122
 
        {
123
 
            mexPrintf ("knobs(1): %g, only completely dense rows removed\n",
124
 
                in_knobs [0]) ;
125
 
        }
126
 
        if (knobs [COLAMD_DENSE_COL] >= 0)
127
 
        {
128
 
            mexPrintf ("knobs(2): %g, cols with > max(16,%g*sqrt(min(size(A)))"
129
 
                " entries removed\n", in_knobs [1], knobs [COLAMD_DENSE_COL]) ;
130
 
        }
131
 
        else
132
 
        {
133
 
            mexPrintf ("knobs(2): %g, only completely dense columns removed\n",
134
 
                in_knobs [1]) ;
135
 
        }
136
 
        mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
137
 
            in_knobs [2]) ;
138
 
    }
139
 
 
140
 
    /* === If A is full, convert to a sparse matrix ========================= */
141
 
 
142
 
    Ainput = (mxArray *) prhs [0] ;
143
 
    if (mxGetNumberOfDimensions (Ainput) != 2)
144
 
    {
145
 
        mexErrMsgTxt ("colamd: input matrix must be 2-dimensional") ;
146
 
    }
147
 
    full = !mxIsSparse (Ainput) ;
148
 
    if (full)
149
 
    {
150
 
        mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ;
151
 
    }
152
 
 
153
 
    /* === Allocate workspace for colamd ==================================== */
154
 
 
155
 
    /* get size of matrix */
156
 
    n_row = mxGetM (Ainput) ;
157
 
    n_col = mxGetN (Ainput) ;
158
 
 
159
 
    /* get column pointer vector so we can find nnz */
160
 
    p = (int *) mxCalloc (n_col+1, sizeof (int)) ;
161
 
    (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (int)) ;
162
 
    nnz = p [n_col] ;
163
 
    Alen = (int) colamd_recommended (nnz, n_row, n_col) ;
164
 
    if (Alen == 0)
165
 
    {
166
 
        mexErrMsgTxt ("colamd: problem too large") ;
167
 
    }
168
 
 
169
 
    /* === Copy input matrix into workspace ================================= */
170
 
 
171
 
    A = (int *) mxCalloc (Alen, sizeof (int)) ;
172
 
    (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (int)) ;
173
 
 
174
 
    if (full)
175
 
    {
176
 
        mxDestroyArray (Ainput) ;
177
 
    }
178
 
 
179
 
    /* === Order the columns (destroys A) =================================== */
180
 
 
181
 
    if (!colamd (n_row, n_col, Alen, A, p, knobs, stats))
182
 
    {
183
 
        colamd_report (stats) ;
184
 
        mexErrMsgTxt ("colamd error!") ;
185
 
    }
186
 
    mxFree (A) ;
187
 
 
188
 
    /* === Return the permutation vector ==================================== */
189
 
 
190
 
    plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
191
 
    out_perm = mxGetPr (plhs [0]) ;
192
 
    for (i = 0 ; i < n_col ; i++)
193
 
    {
194
 
        /* colamd is 0-based, but MATLAB expects this to be 1-based */
195
 
        out_perm [i] = p [i] + 1 ;
196
 
    }
197
 
    mxFree (p) ;
198
 
 
199
 
    /* === Return the stats vector ========================================== */
200
 
 
201
 
    /* print stats if spumoni is set */
202
 
    if (spumoni)
203
 
    {
204
 
        colamd_report (stats) ;
205
 
    }
206
 
 
207
 
    if (nlhs == 2)
208
 
    {
209
 
        plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ;
210
 
        out_stats = mxGetPr (plhs [1]) ;
211
 
        for (i = 0 ; i < COLAMD_STATS ; i++)
212
 
        {
213
 
            out_stats [i] = stats [i] ;
214
 
        }
215
 
 
216
 
        /* fix stats (5) and (6), for 1-based information on jumbled matrix. */
217
 
        /* note that this correction doesn't occur if symamd returns FALSE */
218
 
        out_stats [COLAMD_INFO1] ++ ; 
219
 
        out_stats [COLAMD_INFO2] ++ ; 
220
 
    }
221
 
}