~logan/ubuntu/trusty/suitesparse/4.2.1-3ubuntu1

« back to all changes in this revision

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