File: gbargsort.c

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 506; asm: 369; python: 125; awk: 10
file content (143 lines) | stat: -rw-r--r-- 4,866 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//------------------------------------------------------------------------------
// gbargsort: sort a GraphBLAS matrix
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// usage:

// [C,P] = gbargsort (A, dim, direction)

// where dim = 1 to sort the columns of A, dim = 2 to the rows of A.
// direction is 'ascend' or 'descend'.

#include "gb_interface.h"

#define USAGE "usage: [C,P] = gbargsort (A, dim, direction)"

void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{

    //--------------------------------------------------------------------------
    // check inputs
    //--------------------------------------------------------------------------

    gb_usage (nargin == 3 && (nargout == 2 || nargout == 1), USAGE) ;

    //--------------------------------------------------------------------------
    // find the arguments and determine the sort direction
    //--------------------------------------------------------------------------

    GrB_Matrix A = gb_get_shallow (pargin [0]) ;
    int dim = (int) mxGetScalar (pargin [1]) ;
    CHECK_ERROR (dim < 0 || dim > 2, "invalid dim") ;

    #define LEN 256
    char direction [LEN+2] ;
    gb_mxstring_to_string (direction, LEN, pargin [2], "direction") ;

    GrB_Type type ;
    OK (GxB_Matrix_type (&type, A)) ;

    GrB_BinaryOp op ;
    if (MATCH (direction, "ascend"))
    { 
        // ascending sort
        if      (type == GrB_BOOL  ) op = GrB_LT_BOOL   ;
        else if (type == GrB_INT8  ) op = GrB_LT_INT8   ;
        else if (type == GrB_INT16 ) op = GrB_LT_INT16  ;
        else if (type == GrB_INT32 ) op = GrB_LT_INT32  ;
        else if (type == GrB_INT64 ) op = GrB_LT_INT64  ;
        else if (type == GrB_UINT8 ) op = GrB_LT_UINT8  ;
        else if (type == GrB_UINT16) op = GrB_LT_UINT16 ;
        else if (type == GrB_UINT32) op = GrB_LT_UINT32 ;
        else if (type == GrB_UINT64) op = GrB_LT_UINT64 ;
        else if (type == GrB_FP32  ) op = GrB_LT_FP32   ;
        else if (type == GrB_FP64  ) op = GrB_LT_FP64   ;
        else ERROR ("unsupported type") ;
    }
    else if (MATCH (direction, "descend"))
    { 
        // descending sort
        if      (type == GrB_BOOL  ) op = GrB_GT_BOOL   ;
        else if (type == GrB_INT8  ) op = GrB_GT_INT8   ;
        else if (type == GrB_INT16 ) op = GrB_GT_INT16  ;
        else if (type == GrB_INT32 ) op = GrB_GT_INT32  ;
        else if (type == GrB_INT64 ) op = GrB_GT_INT64  ;
        else if (type == GrB_UINT8 ) op = GrB_GT_UINT8  ;
        else if (type == GrB_UINT16) op = GrB_GT_UINT16 ;
        else if (type == GrB_UINT32) op = GrB_GT_UINT32 ;
        else if (type == GrB_UINT64) op = GrB_GT_UINT64 ;
        else if (type == GrB_FP32  ) op = GrB_GT_FP32   ;
        else if (type == GrB_FP64  ) op = GrB_GT_FP64   ;
        else ERROR ("unsupported type") ;
    }
    else
    { 
        ERROR2 ("unrecognized direction: %s\n", direction) ;
    }

    GrB_Descriptor desc ;
    if (dim == 1)
    { 
        // sort the columns of A
        desc = GrB_DESC_T0 ;
    }
    else // dim == 2
    { 
        // sort the rows of A
        desc = NULL ;
    }

    //--------------------------------------------------------------------------
    // create the outputs C and P
    //--------------------------------------------------------------------------

    GrB_Matrix C = NULL, P = NULL ;
    GrB_Index nrows, ncols ;
    OK (GrB_Matrix_nrows (&nrows, A)) ;
    OK (GrB_Matrix_ncols (&ncols, A)) ;
    OK (GrB_Matrix_new (&C, type, nrows, ncols)) ;
    if (nargout > 1)
    { 
        OK (GrB_Matrix_new (&P, GrB_INT64, nrows, ncols)) ;
    }

    //--------------------------------------------------------------------------
    // sort the matrix
    //--------------------------------------------------------------------------

    OK (GxB_Matrix_sort (C, P, op, A, desc)) ;

    //--------------------------------------------------------------------------
    // add 1 to the entries in P, to convert to 1-based indexing
    //--------------------------------------------------------------------------

    if (P != NULL)
    { 
        OK (GrB_Matrix_apply_BinaryOp2nd_INT64 (P, NULL, NULL, GrB_PLUS_INT64,
            P, (int64_t) 1, NULL)) ;
    }

    //--------------------------------------------------------------------------
    // return result
    //--------------------------------------------------------------------------

    OK (GrB_Matrix_free (&A)) ;
    pargout [0] = gb_export (&C, KIND_GRB) ;
    if (nargout > 1)
    { 
        pargout [1] = gb_export (&P, KIND_GRB) ;
    }
    GB_WRAPUP ;
}