1 //------------------------------------------------------------------------------
2 // gbnorm: norm (A,kind)
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7 
8 //------------------------------------------------------------------------------
9 
10 #include "gb_matlab.h"
11 
12 #define USAGE "usage: s = gbnorm (A, kind)"
13 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])14 void mexFunction
15 (
16     int nargout,
17     mxArray *pargout [ ],
18     int nargin,
19     const mxArray *pargin [ ]
20 )
21 {
22 
23     //--------------------------------------------------------------------------
24     // check inputs
25     //--------------------------------------------------------------------------
26 
27     gb_usage (nargin == 2 && nargout <= 1, USAGE) ;
28 
29     //--------------------------------------------------------------------------
30     // get the inputs
31     //--------------------------------------------------------------------------
32 
33     GrB_Matrix A = gb_get_shallow (pargin [0]) ;
34     int64_t norm_kind = gb_norm_kind (pargin [1]) ;
35 
36     GrB_Type atype ;
37     OK (GxB_Matrix_type (&atype, A)) ;
38 
39     GrB_Index anrows, ancols ;
40     OK (GrB_Matrix_nrows (&anrows, A)) ;
41     OK (GrB_Matrix_ncols (&ancols, A)) ;
42 
43     int sparsity ;
44     OK (GxB_Matrix_Option_get (A, GxB_SPARSITY_STATUS, &sparsity)) ;
45 
46     //--------------------------------------------------------------------------
47     // s = norm (A,kind)
48     //--------------------------------------------------------------------------
49 
50     double s ;
51 
52     if (norm_kind == INT64_MIN && !GB_is_dense (A))
53     {
54         // norm (A,-inf) is zero if A is not full
55         s = 0 ;
56     }
57     else if ((atype == GrB_FP32 || atype == GrB_FP64)
58         && (sparsity != GxB_BITMAP)
59         && (anrows == 1 || ancols == 1 || norm_kind == 0))
60     {
61         // s = norm (A,p) where A is an FP32 or FP64 vector,
62         // or when p = 0 (for Frobenius norm).  A cannot be bitmap.
63         GrB_Index anz ;
64         OK (GrB_Matrix_nvals (&anz, A)) ;
65         s = GB_matlab_helper10 (A->x, NULL, atype, norm_kind, anz) ;
66         if (s < 0) ERROR ("unknown norm") ;
67     }
68     else
69     {
70         // s = norm (A, norm_kind)
71         s = gb_norm (A, norm_kind) ;
72     }
73 
74     //--------------------------------------------------------------------------
75     // free workspace and return result
76     //--------------------------------------------------------------------------
77 
78     OK (GrB_Matrix_free (&A)) ;
79     pargout [0] = mxCreateDoubleScalar (s) ;
80     GB_WRAPUP ;
81 }
82 
83