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

« back to all changes in this revision

Viewing changes to CCOLAMD/MATLAB/csymamdmex.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
/* === csymamd mexFunction ================================================== */
 
3
/* ========================================================================== */
 
4
 
 
5
/* ----------------------------------------------------------------------------
 
6
 * CCOLAMD, Copyright (C), Univ. of Florida.  Authors: Timothy A. Davis,
 
7
 * Sivasankaran Rajamanickam, and Stefan Larimore
 
8
 * See License.txt for the Version 2.1 of the GNU Lesser General Public License
 
9
 * http://www.cise.ufl.edu/research/sparse
 
10
 * -------------------------------------------------------------------------- */
 
11
 
 
12
/* 
 
13
 * Usage:
 
14
 *      p = csymamd (A) ;
 
15
 *      [p stats] = csymamd (A, knobs, cmember) ;
 
16
 *
 
17
 * See csymamd.m for a description.
 
18
 */
 
19
 
 
20
/* ========================================================================== */
 
21
/* === Include files ======================================================== */
 
22
/* ========================================================================== */
 
23
 
 
24
#include "ccolamd.h"
 
25
#include "mex.h"
 
26
#include "matrix.h"
 
27
#include <stdlib.h>
 
28
#include "UFconfig.h"
 
29
 
 
30
/* ========================================================================== */
 
31
/* === csymamd mexFunction ================================================== */
 
32
/* ========================================================================== */
 
33
 
 
34
void mexFunction
 
35
(
 
36
    /* === Parameters ======================================================= */
 
37
 
 
38
    int nargout,
 
39
    mxArray *pargout [ ],
 
40
    int nargin,
 
41
    const mxArray *pargin [ ]
 
42
)
 
43
{
 
44
    /* === Local variables ================================================== */
 
45
 
 
46
    UF_long *A ;                /* row indices of input matrix A */
 
47
    UF_long *perm ;             /* column ordering of M and ordering of A */
 
48
    UF_long *cmember ;          /* csymamd's copy of the constraint set */
 
49
    double *in_cmember ;        /* input constraint set */
 
50
    UF_long *p ;                /* column pointers of input matrix A */
 
51
    UF_long cslen ;             /* size of constraint set */
 
52
    UF_long n_col ;             /* number of columns of A */
 
53
    UF_long n_row ;             /* number of rows of A */
 
54
    UF_long full ;              /* TRUE if input matrix full, FALSE if sparse */
 
55
    double knobs [CCOLAMD_KNOBS] ; /* csymamd user-controllable parameters */
 
56
    double *out_perm ;          /* output permutation vector */
 
57
    double *out_stats ;         /* output stats vector */
 
58
    double *in_knobs ;          /* input knobs vector */
 
59
    UF_long i ;                 /* loop counter */
 
60
    mxArray *Ainput ;           /* input matrix handle */
 
61
    UF_long spumoni ;           /* verbosity variable */
 
62
    UF_long stats [CCOLAMD_STATS] ;     /* stats for symamd */
 
63
 
 
64
    /* === Check inputs ===================================================== */
 
65
 
 
66
    if (nargin < 1 || nargin > 3 || nargout < 0 || nargout > 2)
 
67
    {
 
68
        mexErrMsgTxt ("Usage: [p stats] = csymamd (S, knobs, cmember)") ;
 
69
    }
 
70
 
 
71
    /* === Get cmember ====================================================== */
 
72
 
 
73
    cmember = NULL ;
 
74
    cslen = 0 ;
 
75
    if (nargin > 2)
 
76
    {
 
77
        in_cmember = mxGetPr (pargin [2]) ;
 
78
        cslen = mxGetNumberOfElements (pargin [2]) ;
 
79
        if (cslen != 0)
 
80
        {
 
81
            cmember = (UF_long *) mxCalloc (cslen, sizeof (UF_long)) ;
 
82
            for (i = 0 ; i < cslen ; i++)
 
83
            {
 
84
                /* convert cmember from 1-based to 0-based */
 
85
                cmember[i] = ((UF_long) in_cmember [i] - 1) ;
 
86
            }
 
87
        }
 
88
    }
 
89
 
 
90
    /* === Get knobs ======================================================== */
 
91
 
 
92
    ccolamd_l_set_defaults (knobs) ;
 
93
    spumoni = 0 ;
 
94
 
 
95
    /* check for user-passed knobs */
 
96
    i = 0 ;
 
97
    if (nargin > 1)
 
98
    {
 
99
        in_knobs = mxGetPr (pargin [1]) ;
 
100
        i = mxGetNumberOfElements (pargin [1]) ;
 
101
        if (i > 0) knobs [CCOLAMD_DENSE_ROW] = in_knobs [0] ;
 
102
        if (i > 1) knobs [CCOLAMD_AGGRESSIVE] = in_knobs [1] ;
 
103
        if (i > 2) spumoni = (in_knobs [2] != 0) ;
 
104
    }
 
105
 
 
106
    /* print knob settings if spumoni is set */
 
107
    if (spumoni)
 
108
    {
 
109
        mexPrintf ("\ncsymamd version %d.%d, %s:\n",
 
110
            CCOLAMD_MAIN_VERSION, CCOLAMD_SUB_VERSION, CCOLAMD_DATE) ;
 
111
        if (knobs [CCOLAMD_DENSE_ROW] >= 0)
 
112
        {
 
113
            mexPrintf ("knobs(1): %g, rows/cols with > "
 
114
                "max(16,%g*sqrt(size(A,2))) entries removed\n",
 
115
                in_knobs [0], knobs [CCOLAMD_DENSE_ROW]) ;
 
116
        }
 
117
        else
 
118
        {
 
119
            mexPrintf ("knobs(1): %g, no dense rows removed\n",
 
120
                in_knobs [0]) ;
 
121
        }
 
122
        mexPrintf ("knobs(2): %g, aggressive absorption: %s\n",
 
123
            in_knobs [1], (knobs [CCOLAMD_AGGRESSIVE] != 0) ? "yes" : "no") ;
 
124
        mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
 
125
                in_knobs [2]) ;
 
126
    }
 
127
 
 
128
    /* === If A is full, convert to a sparse matrix ========================= */
 
129
 
 
130
    Ainput = (mxArray *) pargin [0] ;
 
131
    if (mxGetNumberOfDimensions (Ainput) != 2)
 
132
    {
 
133
        mexErrMsgTxt ("csymamd: input matrix must be 2-dimensional.") ;
 
134
    }
 
135
    full = !mxIsSparse (Ainput) ;
 
136
    if (full)
 
137
    {
 
138
        mexCallMATLAB (1, &Ainput, 1, (mxArray **) pargin, "sparse") ;
 
139
    }
 
140
 
 
141
    /* === Allocate workspace for csymamd =================================== */
 
142
 
 
143
    /* get size of matrix */
 
144
    n_row = mxGetM (Ainput) ;
 
145
    n_col = mxGetN (Ainput) ;
 
146
    if (n_col != n_row)
 
147
    {
 
148
        mexErrMsgTxt ("csymamd: matrix must be square.") ;
 
149
    }
 
150
 
 
151
    if (cmember != NULL && cslen != n_col)
 
152
    {
 
153
        mexErrMsgTxt ("csymamd: cmember must be of length equal to #cols of A");
 
154
    }
 
155
 
 
156
    A = (UF_long *) mxGetIr (Ainput) ;
 
157
    p = (UF_long *) mxGetJc (Ainput) ;
 
158
    perm = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
 
159
 
 
160
    /* === Order the rows and columns of A (does not destroy A) ============= */
 
161
 
 
162
    if (!csymamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree,
 
163
            cmember, -1))
 
164
    {
 
165
        csymamd_l_report (stats) ;
 
166
        mexErrMsgTxt ("csymamd error!") ;
 
167
    }
 
168
 
 
169
    if (full)
 
170
    {
 
171
        mxDestroyArray (Ainput) ;
 
172
    }
 
173
 
 
174
    /* === Return the permutation vector ==================================== */
 
175
 
 
176
    pargout [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
 
177
    out_perm = mxGetPr (pargout [0]) ;
 
178
    for (i = 0 ; i < n_col ; i++)
 
179
    {
 
180
        /* symamd is 0-based, but MATLAB expects this to be 1-based */
 
181
        out_perm [i] = perm [i] + 1 ;
 
182
    }
 
183
    mxFree (perm) ;
 
184
    mxFree (cmember) ;
 
185
 
 
186
    /* === Return the stats vector ========================================== */
 
187
 
 
188
    /* print stats if spumoni is set */
 
189
    if (spumoni)
 
190
    {
 
191
        csymamd_l_report (stats) ;
 
192
    }
 
193
 
 
194
    if (nargout == 2)
 
195
    {
 
196
        pargout [1] = mxCreateDoubleMatrix (1, CCOLAMD_STATS, mxREAL) ;
 
197
        out_stats = mxGetPr (pargout [1]) ;
 
198
        for (i = 0 ; i < CCOLAMD_STATS ; i++)
 
199
        {
 
200
            out_stats [i] = stats [i] ;
 
201
        }
 
202
 
 
203
        /* fix stats (5) and (6), for 1-based information on jumbled matrix. */
 
204
        /* note that this correction doesn't occur if symamd returns FALSE */
 
205
        out_stats [CCOLAMD_INFO1] ++ ; 
 
206
        out_stats [CCOLAMD_INFO2] ++ ; 
 
207
    }
 
208
}