File: cs_updown_mex.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (111 lines) | stat: -rw-r--r-- 3,832 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// CXSparse/MATLAB/CSparse/cs_updown_mex: sparse Cholesky update/downdate
// CXSparse, Copyright (c) 2006-2022, Timothy A. Davis. All Rights Reserved.
// SPDX-License-Identifier: LGPL-2.1+
#include "cs_mex.h"
/* cs_updown: sparse Cholesky update/downdate (rank-1 or multiple rank) */
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    int64_t ignore, j, k, n, lnz, *parent, sigma = 1, cp [2], ok ;
    char sigma_string [20] ;
    if (nargout > 1 || nargin < 3 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: L = cs_updown(L,C,parent,sigma)") ;
    }
    if (nargin > 3 && mxIsChar (pargin [3]))
    {
        mxGetString (pargin [3], sigma_string, 8) ;
        sigma = (sigma_string [0] == '-') ? (-1) : 1 ;
    }
    n = mxGetN (pargin [0]) ;
    parent = cs_dl_mex_get_int (n, pargin [2], &ignore, 0) ; /* get parent*/

    if (mxIsComplex (pargin [0]) || mxIsComplex (pargin [1]))
    {

#ifndef NCOMPLEX
        cs_cl Lmatrix, *Lin, Cmatrix, *C, *L, Cvector, *Cvec ;
        /* get input L, and copy MATLAB complex to C complex type */
        Lin = cs_cl_mex_get_sparse (&Lmatrix, 1, pargin [0]) ;

        /* make a copy of L (this can take more work than updating L itself) */
        lnz = Lin->p [n] ;
        L = cs_cl_spalloc (n, n, lnz, 0, 0) ;
        for (j = 0 ; j <= n ; j++) L->p [j] = Lin->p [j] ;
        for (k = 0 ; k < lnz ; k++) L->i [k] = Lin->i [k] ;

        /* complex values already copied into Lin->x, use shallow copy for L */
        L->x = Lin->x ;

        cs_mex_check (0, n, -1, 0, 1, 1, pargin [1]) ;     /* get C */
        C = cs_cl_mex_get_sparse (&Cmatrix, 0, pargin [1]) ;

        /* do the update one column at a time */
        Cvec = &Cvector ;
        Cvec->m = n ;
        Cvec->n = 1 ;
        Cvec->p = cp ;
        Cvec->nz = -1 ;
        cp [0] = 0 ;
        for (k = 0 ; k < C->n ; k++)
        {
            /* extract C(:,k) */ 
            cp [1] = C->p [k+1] - C->p [k] ;
            Cvec->nzmax = cp [1] ;
            Cvec->i = C->i + C->p [k] ;
            Cvec->x = C->x + C->p [k] ;
            /* update/downdate */
            ok = cs_cl_updown (L, sigma, Cvec, parent) ;
            if (!ok) mexErrMsgTxt ("matrix is not positive definite") ;
        }
        /* return new L */ 
        pargout [0] = cs_cl_mex_put_sparse (&L) ;

        cs_cl_free (C->x) ;        /* free complex copy of C */
#else
        mexErrMsgTxt ("complex matrices not supported") ;
#endif

    }
    else
    {

        cs_dl Lmatrix, *Lin, Cmatrix, *C, *L, Cvector, *Cvec ;
        /* get input L */
        Lin = cs_dl_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ;
        /* make a copy of L (this can take more work than updating L itself) */
        lnz = Lin->p [n] ;
        L = cs_dl_spalloc (n, n, lnz, 1, 0) ;
        for (j = 0 ; j <= n ; j++) L->p [j] = Lin->p [j] ;
        for (k = 0 ; k < lnz ; k++) L->i [k] = Lin->i [k] ;
        for (k = 0 ; k < lnz ; k++) L->x [k] = Lin->x [k] ;
        cs_mex_check (0, n, -1, 0, 1, 1, pargin [1]) ;     /* get C */
        C = cs_dl_mex_get_sparse (&Cmatrix, 0, 1, pargin [1]) ;

        /* do the update one column at a time */
        Cvec = &Cvector ;
        Cvec->m = n ;
        Cvec->n = 1 ;
        Cvec->p = cp ;
        Cvec->nz = -1 ;
        cp [0] = 0 ;
        for (k = 0 ; k < C->n ; k++)
        {
            /* extract C(:,k) */ 
            cp [1] = C->p [k+1] - C->p [k] ;
            Cvec->nzmax = cp [1] ;
            Cvec->i = C->i + C->p [k] ;
            Cvec->x = C->x + C->p [k] ;
            /* update/downdate */
            ok = cs_dl_updown (L, sigma, Cvec, parent) ;
            if (!ok) mexErrMsgTxt ("matrix is not positive definite") ;
        }
        /* return new L */ 
        pargout [0] = cs_dl_mex_put_sparse (&L) ;
    }
}