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 144 145 146 147 148 149 150 151 152 153 154
|
//------------------------------------------------------------------------------
// GB_iso_unop: apply a unary or binary op (with scalar) with an iso result
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// The input matrix A need not be entirely valid. GB_transpose can be
// transposing the matrix in place, which case the contents of A have already
// been transplanted into T, and only A->x remains.
#include "GB.h"
void GB_iso_unop // Cx [0] = unop (A), binop (s,A) or binop (A,s)
(
// output
GB_void *restrict Cx, // output scalar of iso array
// input
GrB_Type ctype, // type of Cx
GB_iso_code C_code_iso, // defines how C iso value is to be computed
GB_Operator op, // unary/binop operator, if present
GrB_Matrix A, // input matrix
GrB_Scalar scalar // input scalar (may be NULL)
)
{
//--------------------------------------------------------------------------
// get inputs
//--------------------------------------------------------------------------
ASSERT (A != NULL && A->type != NULL) ;
ASSERT_TYPE_OK (ctype, "ctype for GB_iso_unop", GB0) ;
ASSERT (Cx != NULL) ;
GrB_Type stype = (scalar != NULL) ? scalar->type : GrB_BOOL ;
// const size_t csize = ctype->size ;
const size_t asize = A->type->size ;
const size_t ssize = stype->size ;
const GB_Type_code ccode = ctype->code ;
const GB_Type_code acode = A->type->code ;
const GB_Type_code scode = stype->code ;
//--------------------------------------------------------------------------
// compute the C iso value
//--------------------------------------------------------------------------
if (C_code_iso == GB_ISO_1)
{
//----------------------------------------------------------------------
// Cx [0] = (ctype) 1, via the PAIR binary op or ONE unary op
//----------------------------------------------------------------------
GB_cast_one (Cx, ccode) ;
}
else if (C_code_iso == GB_ISO_S)
{
//----------------------------------------------------------------------
// Cx [0] = (ctype) scalar via FIRST(s,A), SECOND(A,s), ANY(..), ...
//----------------------------------------------------------------------
ASSERT_SCALAR_OK (scalar, "scalar for GB_iso_unop", GB0) ;
GB_cast_scalar (Cx, ccode, scalar->x, scode, ssize) ;
}
else
{
//----------------------------------------------------------------------
// Cx [0] depends on the iso value of A
//----------------------------------------------------------------------
ASSERT (A->x != NULL && A->x_size >= asize) ;
ASSERT (A->iso) ;
if (C_code_iso == GB_ISO_A)
{
//------------------------------------------------------------------
// Cx [0] = (ctype) A
//------------------------------------------------------------------
GB_cast_scalar (Cx, ccode, A->x, acode, asize) ;
}
else if (C_code_iso == GB_ISO_OP1_A)
{
//------------------------------------------------------------------
// Cx [0] = unop (A)
//------------------------------------------------------------------
ASSERT_UNARYOP_OK (op, "op for GB_iso_unop", GB0) ;
// x = (xtype) Ax [0]
GB_Type_code xcode = op->xtype->code ;
size_t xsize = op->xtype->size ;
GB_void x [GB_VLA(xsize)] ;
GB_cast_scalar (x, xcode, A->x, acode, asize) ;
// Cx [0] = op (x)
GxB_unary_function fop = op->unop_function ;
fop (Cx, x) ;
}
else
{
//------------------------------------------------------------------
// Cx [0] = binop (scalar,A) or binop (A,scalar)
//------------------------------------------------------------------
ASSERT_BINARYOP_OK (op, "op for GB_iso_unop", GB0) ;
ASSERT_SCALAR_OK (scalar, "scalar for GB_iso_unop binop", GB0) ;
GB_Type_code xcode = op->xtype->code ;
GB_Type_code ycode = op->ytype->code ;
size_t xsize = op->xtype->size ;
size_t ysize = op->ytype->size ;
GxB_binary_function fop = op->binop_function ;
GB_void x [GB_VLA(xsize)] ;
GB_void y [GB_VLA(ysize)] ;
if (C_code_iso == GB_ISO_OP2_SA)
{
//--------------------------------------------------------------
// Cx [0] = binop (scalar, A)
//--------------------------------------------------------------
GB_cast_scalar (x, xcode, scalar->x, scode, ssize) ;
GB_cast_scalar (y, ycode, A->x, acode, asize) ;
}
else // (C_code_iso == GB_ISO_OP2_AS)
{
//--------------------------------------------------------------
// Cx [0] = binop (A, scalar)
//--------------------------------------------------------------
GB_cast_scalar (x, xcode, A->x, acode, asize) ;
GB_cast_scalar (y, ycode, scalar->x, scode, ssize) ;
}
// Cx [0] = binop (x, y)
fop (Cx, x, y) ;
}
}
}
|