1function test18(fulltest)
2%TEST18 test GrB_eWiseAdd and GrB_eWiseMult
3
4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
5% SPDX-License-Identifier: Apache-2.0
6
7[binops, ~, ~, types, ~, ~] = GB_spec_opsall ;
8bin_ops = binops.all ;
9types = types.all ;
10
11if (nargin < 1)
12    fulltest = 0 ;
13end
14
15if (fulltest == 2)
16    fprintf ('test18 ----------lengthy tests of GrB_eWiseAdd and eWiseMult\n') ;
17    k1test = 1:length(types) ;
18    k4test = randi([0,length(bin_ops)])
19    k6list = [false true] ;
20    k7list = [false true] ;
21    k8list = 0:1 ;
22elseif (fulltest == 1)
23    fprintf ('test18 ------------tests of GrB_eWiseAdd and eWiseMult\n') ;
24    % k1test = [1 2 4 10 11] ;
25    k1test = [ 1 2 11 ] ;
26    k4test = randi([0,length(bin_ops)])
27    k6list = [false true] ;
28    k7list = [false true] ;
29    k8list = 0:1 ;
30else
31    fprintf ('test18 ------------quick tests of GrB_eWiseAdd and eWiseMult\n') ;
32    k1test = [ 1 2 11 12 13] ;
33    k4test = 0 ;
34    k6list = [false] ;
35    k7list = [false] ;
36    k8list = 1 ;
37end
38
39%   mlist = [1 5 10] ;
40%   nlist = [1 5 10] ;
41    mlist = [10] ;
42    nlist = [10] ;
43
44rng ('default') ;
45
46dnn = struct ;
47dtn = struct ( 'inp0', 'tran' ) ;
48dnt = struct ( 'inp1', 'tran' ) ;
49dtt = struct ( 'inp0', 'tran', 'inp1', 'tran' ) ;
50
51n_semirings = 0 ;
52for k1 = k1test % 1:length (types)
53    type = types {k1}  ;
54
55    fprintf ('\n\n========================================= %s:\n', type) ;
56
57    k2test = 1:length(bin_ops) ;
58
59    for k2 = k2test % 1:length(bin_ops)
60        binop = bin_ops {k2}  ;
61
62        fprintf ('\n%s', binop) ;
63
64        op.opname = binop ;
65        op.optype = type ;
66
67        try
68            GB_spec_operator (op) ;
69        catch
70            continue
71        end
72
73        fprintf (' binary op: [ %s %s ] ', binop, type) ;
74        if (contains (type, 'single'))
75            tol = 1e-5 ;
76        elseif (contains (type, 'double'))
77            tol = 1e-12 ;
78        else
79            tol = 0 ;
80        end
81
82        % try some matrices
83        for m = mlist
84            for n = nlist
85
86                % avoid creating nans for testing pow
87                if (isequal (binop, 'pow'))
88                    scale = 2 ;
89                else
90                    scale = 100 ;
91                end
92
93                Amat = sparse (scale * sprandn (m,n, 0.2)) ;
94                Bmat = sparse (scale * sprandn (m,n, 0.2)) ;
95                Cmat = sparse (scale * sprandn (m,n, 0.2)) ;
96                w    = sparse (scale * sprandn (m,1, 0.2)) ;
97                uvec = sparse (scale * sprandn (m,1, 0.2)) ;
98                vvec = sparse (scale * sprandn (m,1, 0.2)) ;
99
100                % these tests do not convert real A and B into complex C for C
101                % = A.^B.  GrB.power handles that case.  So ensure the test
102                % matrices are all positive.
103                if (isequal (binop, 'pow'))
104                    Amat = abs (Amat) ;
105                    Bmat = abs (Bmat) ;
106                    Cmat = abs (Cmat) ;
107                    w    = abs (w) ;
108                    uvec = abs (uvec) ;
109                    vvec = abs (vvec) ;
110                end
111
112                Maskmat = sprandn (m,n,0.2) ~= 0 ;
113                maskvec = sprandn (m,1,0.2) ~= 0 ;
114
115                % create a very sparse matrix mask
116                Maskmat2 = sparse (m,n) ;
117                T = Amat .* Bmat ;
118                [i j x] = find (T) ;
119                if (length (i) > 0)
120                    Maskmat2 (i(1), j(1)) = 1 ;
121                end
122                T = (Amat ~= 0) & (Bmat == 0) ;
123                [i j x] = find (T) ;
124                if (length (i) > 0)
125                    Maskmat2 (i(1), j(1)) = 1 ;
126                end
127                T = (Amat == 0) & (Bmat ~= 0) ;
128                [i j x] = find (T) ;
129                if (length (i) > 0)
130                    Maskmat2 (i(1), j(1)) = 1 ;
131                end
132                clear T i j x
133
134                % create a very sparse vector mask
135                maskvec2 = sparse (m,1) ;
136                T = uvec .* vvec ;
137                [i j x] = find (T) ;
138                if (length (i) > 0)
139                    maskvec2 (i(1), j(1)) = 1 ;
140                end
141                T = (uvec ~= 0) & (vvec == 0) ;
142                [i j x] = find (T) ;
143                if (length (i) > 0)
144                    maskvec2 (i(1), j(1)) = 1 ;
145                end
146                T = (uvec == 0) & (vvec ~= 0) ;
147                [i j x] = find (T) ;
148                if (length (i) > 0)
149                    maskvec2 (i(1), j(1)) = 1 ;
150                end
151                clear T i j x
152
153                ATmat = Amat' ;
154                BTmat = Bmat' ;
155
156                for k4 = k4test
157
158                    clear accum
159                    if (k4 == 0)
160                        accum = ''  ;
161                        ntypes = 1 ;
162                    else
163                        accum.opname = bin_ops {k4}  ;
164                        ntypes = length (types) ;
165                        fprintf ('accum: %s ', accum.opname) ;
166                    end
167
168                    if (GB_spec_is_positional (accum))
169                        continue
170                    end
171
172                    for k5 = randi ([1 ntypes]) % ntypes
173
174                        if (k4 > 0)
175                            accum.optype = types {k5}  ;
176
177                            try
178                                GB_spec_operator (accum) ;
179                            catch
180                                continue
181                            end
182
183                            fprintf ('%s\n', accum.optype) ;
184                        else
185                            fprintf ('\n') ;
186                        end
187
188                        for Mask_complement = k6list
189
190                            if (Mask_complement)
191                                dnn.mask = 'complement' ;
192                                dtn.mask = 'complement' ;
193                                dnt.mask = 'complement' ;
194                                dtt.mask = 'complement' ;
195                            else
196                                dnn.mask = 'default' ;
197                                dtn.mask = 'default' ;
198                                dnt.mask = 'default' ;
199                                dtt.mask = 'default' ;
200                            end
201
202                            for C_replace = k7list
203
204                                if (C_replace)
205                                    dnn.outp = 'replace' ;
206                                    dtn.outp = 'replace' ;
207                                    dnt.outp = 'replace' ;
208                                    dtt.outp = 'replace' ;
209                                else
210                                    dnn.outp = 'default' ;
211                                    dtn.outp = 'default' ;
212                                    dnt.outp = 'default' ;
213                                    dtt.outp = 'default' ;
214                                end
215
216                                for A_is_hyper = 0:1
217                                for A_is_csc   = 0:1
218                                for B_is_hyper = 0:1
219                                for B_is_csc   = 0:1
220                                fprintf ('.') ;
221                                for C_is_hyper = 0 % 0:1
222                                for C_is_csc   = 0 % 0:1
223
224                                for native = k8list
225
226                                clear A
227                                A.matrix = Amat ;
228                                A.is_hyper = A_is_hyper ;
229                                A.is_csc   = A_is_csc   ;
230                                if (native)
231                                    A.class = op.optype ;
232                                end
233
234                                clear AT
235                                AT.matrix = ATmat ;
236                                AT.is_hyper = A_is_hyper ;
237                                AT.is_csc   = A_is_csc   ;
238                                if (native)
239                                    AT.class = op.optype ;
240                                end
241
242                                clear B
243                                B.matrix = Bmat ;
244                                B.is_hyper = B_is_hyper ;
245                                B.is_csc   = B_is_csc   ;
246                                if (native)
247                                    B.class = op.optype ;
248                                end
249
250                                clear BT
251                                BT.matrix = BTmat ;
252                                BT.is_hyper = B_is_hyper ;
253                                BT.is_csc   = B_is_csc   ;
254                                if (native)
255                                    BT.class = op.optype ;
256                                end
257
258                                clear C
259                                C.matrix = Cmat ;
260                                C.is_hyper = C_is_hyper ;
261                                C.is_csc   = C_is_csc   ;
262
263                                clear u
264                                u.matrix = uvec ;
265                                u.is_csc = true ;
266                                if (native)
267                                    u.class = op.optype ;
268                                end
269
270                                clear v
271                                v.matrix = vvec ;
272                                v.is_csc = true ;
273                                if (native)
274                                    v.class = op.optype ;
275                                end
276
277                                %---------------------------------------
278                                % A+B
279                                %---------------------------------------
280
281                                C0 = GB_spec_Matrix_eWiseAdd ...
282                                    (C, [ ], accum, op, A, B, dnn);
283                                C1 = GB_mex_Matrix_eWiseAdd ...
284                                    (C, [ ], accum, op, A, B, dnn);
285                                GB_spec_compare (C0, C1, 0, tol) ;
286
287                                w0 = GB_spec_Vector_eWiseAdd ...
288                                    (w, [ ], accum, op, u, v, dnn);
289                                w1 = GB_mex_Vector_eWiseAdd ...
290                                    (w, [ ], accum, op, u, v, dnn);
291                                GB_spec_compare (w0, w1, 0, tol) ;
292
293                                %---------------------------------------
294                                % A'+B
295                                %---------------------------------------
296
297                                C0 = GB_spec_Matrix_eWiseAdd ...
298                                    (C, [ ], accum, op, AT, B, dtn);
299                                C1 = GB_mex_Matrix_eWiseAdd ...
300                                    (C, [ ], accum, op, AT, B, dtn);
301                                GB_spec_compare (C0, C1, 0, tol) ;
302
303                                %---------------------------------------
304                                % A+B'
305                                %---------------------------------------
306
307                                C0 = GB_spec_Matrix_eWiseAdd ...
308                                    (C, [ ], accum, op, A, BT, dnt);
309                                C1 = GB_mex_Matrix_eWiseAdd ...
310                                    (C, [ ], accum, op, A, BT, dnt);
311                                GB_spec_compare (C0, C1, 0, tol) ;
312
313                                %---------------------------------------
314                                % A'+B'
315                                %---------------------------------------
316
317                                C0 = GB_spec_Matrix_eWiseAdd ...
318                                    (C, [ ], accum, op, AT, BT, dtt);
319                                C1 = GB_mex_Matrix_eWiseAdd ...
320                                    (C, [ ], accum, op, AT, BT, dtt);
321                                GB_spec_compare (C0, C1, 0, tol) ;
322
323                                %---------------------------------------
324                                % A.*B
325                                %---------------------------------------
326
327                                C0 = GB_spec_Matrix_eWiseMult ...
328                                    (C, [ ], accum, op, A, B, dnn);
329                                C1 = GB_mex_Matrix_eWiseMult ...
330                                    (C, [ ], accum, op, A, B, dnn);
331                                GB_spec_compare (C0, C1, 0, tol) ;
332
333                                w0 = GB_spec_Vector_eWiseMult ...
334                                    (w, [ ], accum, op, u, v, dnn);
335                                w1 = GB_mex_Vector_eWiseMult ...
336                                    (w, [ ], accum, op, u, v, dnn);
337                                GB_spec_compare (w0, w1, 0, tol) ;
338
339                                %---------------------------------------
340                                % A'.*B
341                                %---------------------------------------
342
343                                C0 = GB_spec_Matrix_eWiseMult ...
344                                    (C, [ ], accum, op, AT, B, dtn);
345                                C1 = GB_mex_Matrix_eWiseMult ...
346                                    (C, [ ], accum, op, AT, B, dtn);
347                                GB_spec_compare (C0, C1, 0, tol) ;
348
349                                %---------------------------------------
350                                % A.*B'
351                                %---------------------------------------
352
353                                C0 = GB_spec_Matrix_eWiseMult ...
354                                    (C, [ ], accum, op, A, BT, dnt);
355                                C1 = GB_mex_Matrix_eWiseMult ...
356                                    (C, [ ], accum, op, A, BT, dnt);
357                                GB_spec_compare (C0, C1, 0, tol) ;
358
359                                %---------------------------------------
360                                % A'.*B'
361                                %---------------------------------------
362
363                                C0 = GB_spec_Matrix_eWiseMult ...
364                                    (C, [ ], accum, op, AT, BT, dtt);
365                                C1 = GB_mex_Matrix_eWiseMult ...
366                                    (C, [ ], accum, op, AT, BT, dtt);
367                                GB_spec_compare (C0, C1, 0, tol) ;
368
369                                %-----------------------------------------------
370                                % with mask
371                                %-----------------------------------------------
372
373                                for M_is_very_sparse = 0:1
374                                for M_is_hyper = 0:1
375                                for M_is_csc   = 0:1
376
377                                clear Mask mask
378                                if (M_is_very_sparse)
379                                    Mask.matrix = Maskmat2 ;
380                                    mask.matrix = maskvec2 ;
381                                else
382                                    Mask.matrix = Maskmat ;
383                                    mask.matrix = maskvec ;
384                                end
385                                Mask.is_hyper = M_is_hyper ;
386                                Mask.is_csc   = M_is_csc   ;
387                                mask.is_csc = true ;
388
389                                %---------------------------------------
390                                % A+B, with mask
391                                %---------------------------------------
392
393                                C0 = GB_spec_Matrix_eWiseAdd ...
394                                    (C, Mask, accum, op, A, B, dnn);
395                                C1 = GB_mex_Matrix_eWiseAdd ...
396                                    (C, Mask, accum, op, A, B, dnn);
397                                GB_spec_compare (C0, C1, 0, tol) ;
398
399                                w0 = GB_spec_Vector_eWiseAdd ...
400                                    (w, mask, accum, op, u, v, dnn);
401                                w1 = GB_mex_Vector_eWiseAdd ...
402                                    (w, mask, accum, op, u, v, dnn);
403                                GB_spec_compare (w0, w1, 0, tol) ;
404
405                                %---------------------------------------
406                                % A'+B, with mask
407                                %---------------------------------------
408
409                                C0 = GB_spec_Matrix_eWiseAdd ...
410                                    (C, Mask, accum, op, AT, B, dtn);
411                                C1 = GB_mex_Matrix_eWiseAdd ...
412                                    (C, Mask, accum, op, AT, B, dtn);
413                                GB_spec_compare (C0, C1, 0, tol) ;
414
415                                %---------------------------------------
416                                % A+B', with mask
417                                %---------------------------------------
418
419                                C0 = GB_spec_Matrix_eWiseAdd ...
420                                    (C, Mask, accum, op, A, BT, dnt);
421                                C1 = GB_mex_Matrix_eWiseAdd ...
422                                    (C, Mask, accum, op, A, BT, dnt);
423                                GB_spec_compare (C0, C1, 0, tol) ;
424
425                                %---------------------------------------
426                                % A'+B', with mask
427                                %---------------------------------------
428
429                                C0 = GB_spec_Matrix_eWiseAdd ...
430                                    (C, Mask, accum, op, AT, BT, dtt);
431                                C1 = GB_mex_Matrix_eWiseAdd ...
432                                    (C, Mask, accum, op, AT, BT, dtt);
433                                GB_spec_compare (C0, C1, 0, tol) ;
434
435                                %---------------------------------------
436                                % A.*B, with mask
437                                %---------------------------------------
438
439                                C0 = GB_spec_Matrix_eWiseMult ...
440                                    (C, Mask, accum, op, A, B, dnn);
441                                C1 = GB_mex_Matrix_eWiseMult ...
442                                    (C, Mask, accum, op, A, B, dnn);
443                                GB_spec_compare (C0, C1, 0, tol) ;
444
445                                w0 = GB_spec_Vector_eWiseMult ...
446                                    (w, mask, accum, op, u, v, dnn);
447                                w1 = GB_mex_Vector_eWiseMult ...
448                                    (w, mask, accum, op, u, v, dnn);
449                                GB_spec_compare (w0, w1, 0, tol) ;
450
451                                %---------------------------------------
452                                % A'.*B, with mask
453                                %---------------------------------------
454
455                                C0 = GB_spec_Matrix_eWiseMult ...
456                                    (C, Mask, accum, op, AT, B, dtn);
457                                C1 = GB_mex_Matrix_eWiseMult ...
458                                    (C, Mask, accum, op, AT, B, dtn);
459                                GB_spec_compare (C0, C1, 0, tol) ;
460
461                                %---------------------------------------
462                                % A.*B', with mask
463                                %---------------------------------------
464
465                                C0 = GB_spec_Matrix_eWiseMult ...
466                                    (C, Mask, accum, op, A, BT, dnt);
467                                C1 = GB_mex_Matrix_eWiseMult ...
468                                    (C, Mask, accum, op, A, BT, dnt);
469                                GB_spec_compare (C0, C1, 0, tol) ;
470
471                                %---------------------------------------
472                                % A'.*B', with mask
473                                %---------------------------------------
474
475                                C0 = GB_spec_Matrix_eWiseMult ...
476                                    (C, Mask, accum, op, AT, BT, dtt);
477                                C1 = GB_mex_Matrix_eWiseMult ...
478                                    (C, Mask, accum, op, AT, BT, dtt);
479                                GB_spec_compare (C0, C1, 0, tol) ;
480
481                                end
482                                end
483                                end
484                                end
485                                end
486                                end
487                                end
488                                end
489                                end
490                                end
491
492                            end
493                        end
494                    end
495                end
496            end
497        end
498    end
499end
500
501fprintf ('\ntest18: all tests passed\n') ;
502
503