1 /** \addtogroup utils
2  * @{
3  * Utility functions
4  *
5  * \note All utility functions working with arrays can work inplace (i.e. in == out) without
6  * allocating additional memory internally.
7  */
8 
9 #ifndef _ltfat_ciutils_h
10 #define _ltfat_ciutils_h
11 
12 typedef enum
13 {
14     /** Don't normalize */
15     LTFAT_NORM_NULL = 0,
16     /**  1 norm (divide by the sum of abs. values)  */
17     /**@{*/
18     LTFAT_NORM_AREA,
19     LTFAT_NORM_1 = LTFAT_NORM_AREA,
20     /**@}*/
21     /**  2 norm (divide by the square root of sum of squares of abs. values) */
22     /**@{*/
23     LTFAT_NORM_ENERGY,
24     LTFAT_NORM_2 = LTFAT_NORM_ENERGY,
25     /**@}*/
26     /**  inf norm (divide by the max abs. val.)*/
27     /**@{*/
28     LTFAT_NORM_INF,
29     LTFAT_NORM_PEAK = LTFAT_NORM_INF,
30     /**@}*/
31     // LTFAT_NORM_RMS,
32     // LTFAT_NORM_WAV,
33 } ltfat_norm_t;
34 
35 
36 typedef enum
37 {
38     LTFAT_WHOLEPOINT = 0,
39     LTFAT_HALFPOINT
40 
41 } ltfat_symmetry_t;
42 
43 #endif
44 
45 /** Shift array circularly
46  *
47  *  Works exactly like
48  *  <a href="http://de.mathworks.com/help/matlab/ref/circshift.html">circshift</a>
49  *  from Matlab.
50  *
51  * \param[in]     in  Input array
52  * \param[in]      L  Length of arrays
53  * \param[in]  shift  Shift amount (can be negative)
54  * \param[out]   out  Output array
55  *
56  *  #### Function versions ####
57  *  <tt>
58  *  ltfat_circshift_d(const double in[], ltfat_int L,ltfat_int shift, double out[]);
59  *
60  *  ltfat_circshift_s(const float in[], ltfat_int L,ltfat_int shift, float out[]);
61  *
62  *  ltfat_circshift_dc(const ltfat_complex_d in[], ltfat_int L,ltfat_int shift, ltfat_complex_d out[]);
63  *
64  *  ltfat_circshift_sc(const ltfat_complex_s in[], ltfat_int L,ltfat_int shift, ltfat_complex_s out[]);
65  *  </tt>
66  *
67  * \returns
68  * Status code           | Description
69  * ----------------------|--------------------------------------------
70  * LTFATERR_SUCCESS      | Indicates no error
71  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
72  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
73  */
74 LTFAT_API int
75 LTFAT_NAME(circshift)(const LTFAT_TYPE in[], ltfat_int L,
76                       ltfat_int shift, LTFAT_TYPE out[]);
77 
78 /** Shift columns of a matrix circularly
79  *
80  *  Works like circshift but with entire cols.
81  *
82  * \param[in]     in  Input array
83  * \param[in]      L  Length of cols
84  * \param[in]      W  Number of cols
85  * \param[in]  shift  Shift amount (can be negative)
86  * \param[out]   out  Output array
87  *
88  *  #### Function versions ####
89  *  <tt>
90  *  ltfat_circshiftcols_d(const double in[], ltfat_int L, ltfat_int W, ltfat_int shift, double out[]);
91  *
92  *  ltfat_circshiftcols_s(const float in[], ltfat_int L, ltfat_int W, ltfat_int shift, float out[]);
93  *
94  *  ltfat_circshiftcols_dc(const ltfat_complex_d in[], ltfat_int L, ltfat_int W, ltfat_int shift, ltfat_complex_d out[]);
95  *
96  *  ltfat_circshiftcols_sc(const ltfat_complex_s in[], ltfat_int L, ltfat_int W, ltfat_int shift, ltfat_complex_s out[]);
97  *  </tt>
98  *
99  * \returns
100  * Status code           | Description
101  * ----------------------|--------------------------------------------
102  * LTFATERR_SUCCESS      | Indicates no error
103  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
104  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
105  */
106 LTFAT_API int
107 LTFAT_NAME(circshiftcols)(const LTFAT_TYPE in[], ltfat_int L, ltfat_int W,
108                           ltfat_int shift, LTFAT_TYPE out[]);
109 
110 /** 2D circshift
111  *
112  *  Works exactly like
113  *  <a href="http://de.mathworks.com/help/matlab/ref/circshift.html">circshift</a>
114  *  from Matlab for matrices.
115  *
116  * \param[in]             in  Input array
117  * \param[in]              H  Number of rows
118  * \param[in]              W  Number of columns
119  * \param[in]      shift_row  Shift amount (can be negative)
120  * \param[in]      shift_col  Shift amount (can be negative)
121  * \param[out]   out  Output array
122  *
123  *  #### Function versions ####
124  *  <tt>
125  *  ltfat_circshift2_d(const double in[], ltfat_int H, ltfat_int W, ltfat_int shift_row, ltfat_int shift_col, double out[]);
126  *
127  *  ltfat_circshift2_s(const float in[], ltfat_int H, ltfat_int W, ltfat_int shift_row, ltfat_int shift_col, float out[]);
128  *
129  *  ltfat_circshift2_dc(const ltfat_complex_d in[], ltfat_int H, ltfat_int W, ltfat_int shift_row, ltfat_int shift_col, ltfat_complex_d out[]);
130  *
131  *  ltfat_circshift2_sc(const ltfat_complex_s in[], ltfat_int H, ltfat_int W, ltfat_int shift_row, ltfat_int shift_col, ltfat_complex_s out[]);
132  *  </tt>
133  *
134  * \returns
135  * Status code           | Description
136  * ----------------------|--------------------------------------------
137  * LTFATERR_SUCCESS      | Indicates no error
138  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
139  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
140  */
141 LTFAT_API int
142 LTFAT_NAME(circshift2)(const LTFAT_TYPE in[], ltfat_int H, ltfat_int W,
143                        ltfat_int shift_row, ltfat_int shift_col, LTFAT_TYPE out[]);
144 
145 /** fftshift an array
146  *
147  *  Works exactly like
148  *  <a href="http://de.mathworks.com/help/matlab/ref/fftshift.html">fftshift</a>
149  *  form Matlab for vectors.
150  *
151  * \param[in]     in  Input array
152  * \param[in]      L  Length of arrays
153  * \param[out]   out  Output array
154  *
155  *  #### Function versions ####
156  *  <tt>
157  *  ltfat_fftshift_d(const double in[], ltfat_int L, double out[]);
158  *
159  *  ltfat_fftshift_s(const float in[], ltfat_int L, float out[]);
160  *
161  *  ltfat_fftshift_dc(const ltfat_complex_d in[], ltfat_int L, ltfat_complex_d out[]);
162  *
163  *  ltfat_fftshift_sc(const ltfat_complex_s in[], ltfat_int L, ltfat_complex_s out[]);
164  *  </tt>
165  *
166  * \returns
167  * Status code           | Description
168  * ----------------------|--------------------------------------------
169  * LTFATERR_SUCCESS      | Indicates no error
170  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
171  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
172  */
173 LTFAT_API int
174 LTFAT_NAME(fftshift)(const LTFAT_TYPE in[], ltfat_int L, LTFAT_TYPE out[]);
175 
176 /** ifftshift an array
177  *
178  *  Works exactly like
179  *  <a href="http://de.mathworks.com/help/matlab/ref/ifftshift.html">ifftshift</a>
180  *  form Matlab for vectors. Undoes the action of fftshift
181  *
182  * \param[in]     in  Input array
183  * \param[in]      L  Length of arrays
184  * \param[out]   out  Output array
185  *
186  *  #### Function versions ####
187  *  <tt>
188  *  ltfat_ifftshift_d(const double in[], ltfat_int L, double out[]);
189  *
190  *  ltfat_ifftshift_s(const float in[], ltfat_int L, float out[]);
191  *
192  *  ltfat_ifftshift_dc(const ltfat_complex_d in[], ltfat_int L, ltfat_complex_d out[]);
193  *
194  *  ltfat_ifftshift_sc(const ltfat_complex_s in[], ltfat_int L, ltfat_complex_s out[]);
195  *  </tt>
196  *
197  * \returns
198  * Status code           | Description
199  * ----------------------|--------------------------------------------
200  * LTFATERR_SUCCESS      | Indicates no error
201  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
202  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
203  */
204 LTFAT_API int
205 LTFAT_NAME(ifftshift)(const LTFAT_TYPE in[], ltfat_int L, LTFAT_TYPE out[]);
206 
207 /** Change signal length by inserting zeros in the middle
208  *
209  *  Works exactly like
210  *  <a href="http://ltfat.github.io/doc/fourier/middlepad.html">middlepad</a>
211  *  form LTFAT i.e. extends \a in by inserting zeros in the middle or
212  *  removes the middle part such that the output is \a Lout.
213  *
214  *
215  * \param[in]     in  Input array
216  * \param[in]    Lin  Length of input array
217  * \param[in]    sym  Which symmetry to preserve
218  * \param[in]   Lout  Length of output array
219  * \param[out]   out  Output array
220  *
221  *  #### Function versions ####
222  *  <tt>
223  *  ltfat_middlepad_d(const double in[], ltfat_int Lin, ltfat_symmetry_t sym, ltfat_int Lout, double out[]);
224  *
225  *  ltfat_middlepad_s(const float in[], ltfat_int Lin, ltfat_symmetry_t sym, ltfat_int Lout, float out[]);
226  *
227  *  ltfat_middlepad_dc(const ltfat_complex_d in[], ltfat_int Lin, ltfat_symmetry_t sym, ltfat_int Lout, ltfat_complex_d out[]);
228  *
229  *  ltfat_middlepad_sc(const ltfat_complex_s in[], ltfat_int Lin, ltfat_symmetry_t sym, ltfat_int Lout, ltfat_complex_s out[]);
230  *  </tt>
231  *
232  * \returns
233  * Status code           | Description
234  * ----------------------|--------------------------------------------
235  * LTFATERR_SUCCESS      | Indicates no error
236  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
237  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
238  * LTFATERR_BADREQSIZE   | Output array is shorter than the input array: \a Llong < \a Lfir
239  */
240 LTFAT_API int
241 LTFAT_NAME(middlepad)(const LTFAT_TYPE* in, ltfat_int Lin, ltfat_symmetry_t sym,
242                       ltfat_int Lout, LTFAT_TYPE* out);
243 
244 
245 /** Change signal length by repeating in[0] from both ends
246  *
247  * Intended to be used on windows e.g. from firwin
248  *
249  * \param[in]     in  Input array
250  * \param[in]    Lin  Length of input array
251  * \param[in]   Lout  Length of output array
252  * \param[out]   out  Output array
253  *
254  *  #### Function versions ####
255  *  <tt>
256  *  ltfat_peakpad_d(const double in[], ltfat_int Lin, ltfat_int Lout, double out[]);
257  *
258  *  ltfat_peakpad_s(const float in[], ltfat_int Lin, ltfat_int Lout, float out[]);
259  *
260  *  ltfat_peakpad_dc(const ltfat_complex_d in[], ltfat_int Lin, ltfat_int Lout, ltfat_complex_d out[]);
261  *
262  *  ltfat_peakpad_sc(const ltfat_complex_s in[], ltfat_int Lin, ltfat_int Lout, ltfat_complex_s out[]);
263  *  </tt>
264  *
265  * \returns
266  * Status code           | Description
267  * ----------------------|--------------------------------------------
268  * LTFATERR_SUCCESS      | Indicates no error
269  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
270  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
271  * LTFATERR_BADREQSIZE   | Output array is shorter than the input array: \a Llong < \a Lfir
272  */
273 LTFAT_API int
274 LTFAT_NAME(peakpad)(const LTFAT_TYPE* in, ltfat_int Lin, ltfat_int Lout, LTFAT_TYPE* out);
275 
276 // LTFAT_API int
277 // LTFAT_NAME(middlepadcols)(const LTFAT_TYPE* in, ltfat_int Hin, ltfat_int Win, ltfat_symmetry_t sym,
278 //                           ltfat_int Wout, LTFAT_TYPE* out);
279 //
280 //
281 // LTFAT_API int
282 // LTFAT_NAME(middlepad2d)(const LTFAT_TYPE* in, ltfat_int Hin, ltfat_int Win, ltfat_symmetry_t sym,
283 //                         ltfat_int Hout, ltfat_int Wout, LTFAT_TYPE* out);
284 
285 
286 /** Extend FIR window to long window
287  *
288  *  Works exactly like
289  *  <a href="http://ltfat.github.io/doc/sigproc/fir2long.html">fir2long</a>
290  *  form LTFAT i.e. extends \a in by inserting zeros in the middle.
291  *  \a Llong must be greater or equal to \a Lfir.
292  *
293  * \param[in]     in  Input array
294  * \param[in]   Lfir  Length of input array
295  * \param[in]  Llong  Length of output array
296  * \param[out]   out  Output array
297  *
298  *  #### Function versions ####
299  *  <tt>
300  *  ltfat_fir2long_d(const double in[], ltfat_int Lfir, ltfat_int Llong, double out[]);
301  *
302  *  ltfat_fir2long_s(const float in[], ltfat_int Lfir, ltfat_int Llong, float out[]);
303  *
304  *  ltfat_fir2long_dc(const ltfat_complex_d in[], ltfat_int Lfir, ltfat_int Llong, ltfat_complex_d out[]);
305  *
306  *  ltfat_fir2long_sc(const ltfat_complex_s in[], ltfat_int Lfir, ltfat_int Llong, ltfat_complex_s out[]);
307  *  </tt>
308  *
309  * \returns
310  * Status code           | Description
311  * ----------------------|--------------------------------------------
312  * LTFATERR_SUCCESS      | Indicates no error
313  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
314  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
315  * LTFATERR_BADREQSIZE   | Output array is shorter than the input array: \a Llong < \a Lfir
316  */
317 LTFAT_API int
318 LTFAT_NAME(fir2long)(const LTFAT_TYPE in[], ltfat_int Lfir, ltfat_int Llong,
319                      LTFAT_TYPE out[]);
320 
321 /** Cut long window to a FIR window
322  *
323  *  Works exactly like
324  *  <a href="http://ltfat.github.io/doc/sigproc/long2fir.html">long2fir</a>
325  *  form LTFAT i.e. it removes the middle part.
326  *  Llong must be greater or equal to Lfir.
327  *
328  * \param[in]     in  Input array
329  * \param[in]  Llong  Length of input array
330  * \param[in]   Lfir  Length of output array
331  * \param[out]   out  Output array
332  *
333  *  #### Function versions ####
334  *  <tt>
335  *  ltfat_long2fir_d(const double in[], ltfat_int Llong, ltfat_int Lfir, double out[]);
336  *
337  *  ltfat_long2fir_s(const float in[], ltfat_int Llong, ltfat_int Lfir, float out[]);
338  *
339  *  ltfat_long2fir_dc(const ltfat_complex_d in[], ltfat_int Llong, ltfat_int Lfir, ltfat_complex_d out[]);
340  *
341  *  ltfat_long2fir_sc(const ltfat_complex_s in[], ltfat_int Llong, ltfat_int Lfir, ltfat_complex_s out[]);
342  *  </tt>
343  *
344  * \returns
345  * Status code           | Description
346  * ----------------------|--------------------------------------------
347  * LTFATERR_SUCCESS      | Indicates no error
348  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
349  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
350  * LTFATERR_BADREQSIZE   | Output array is longer than the input array: \a Lfir > \a Llong
351  */
352 LTFAT_API int
353 LTFAT_NAME(long2fir)(const LTFAT_TYPE in[], ltfat_int Llong, ltfat_int Lfir,
354                      LTFAT_TYPE out[]);
355 
356 
357 /** Compute norm of a vector
358  *
359  * \param[in]     in  Input array
360  * \param[in]      L  Length of input array
361  * \param[in]   flag  Norm
362  * \param[out]   out  Computed norm
363  *
364  *  #### Function versions ####
365  *  <tt>
366  *  ltfat_norm_d(const double in[], ltfat_int L, ltfat_norm_t flag, double* out);
367  *
368  *  ltfat_norm_s(const float in[], ltfat_int L, ltfat_norm_t flag flag, float* out);
369  *
370  *  ltfat_norm_dc(const ltfat_complex_d in[], ltfat_int L, ltfat_norm_t flag, double* out);
371  *
372  *  ltfat_norm_sc(const ltfat_complex_s in[], ltfat_int L, ltfat_norm_t flag, float* out);
373  *  </tt>
374  *
375  * \returns
376  * Status code           | Description
377  * ----------------------|--------------------------------------------
378  * LTFATERR_SUCCESS      | Indicates no error
379  * LTFATERR_NULLPOINTER  | Either in or norm is NULL
380  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
381  * LTFATERR_CANNOTHAPPEN | Wrong ltfat_norm_t flag
382  */
383 LTFAT_API int
384 LTFAT_NAME(norm)(const LTFAT_TYPE* in, ltfat_int L,
385                  ltfat_norm_t flag, LTFAT_REAL* norm);
386 
387 /** Compute normalized signal-to-noise
388  *
389  * Such that snr=20*log10(norm(rec,2)/norm(in,2))
390  *
391  * \param[in]     in  Input array
392  * \param[in]    rec  Reconstructed array
393  * \param[in]      L  Length of the arrays
394  * \param[out]   snr  Computed snr
395  *
396  *  #### Function versions ####
397  *  <tt>
398  *  ltfat_snr_d(const double in[], const double rec[], ltfat_int L, double* out);
399  *
400  *  ltfat_snr_s(const float in[], const float rec[], ltfat_int L, float* out);
401  *
402  *  ltfat_snr_dc(const ltfat_complex_d in[], const ltfat_complex_d rec[], ltfat_int L, double* out);
403  *
404  *  ltfat_snr_sc(const ltfat_complex_s in[], const ltfat_complex_s rec[], ltfat_int L, float* out);
405  *  </tt>
406  *
407  * \returns
408  * Status code           | Description
409  * ----------------------|--------------------------------------------
410  * LTFATERR_SUCCESS      | Indicates no error
411  * LTFATERR_NULLPOINTER  | Either in, rec or snr is NULL
412  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
413  */
414 
415 LTFAT_API int
416 LTFAT_NAME(snr)(const LTFAT_TYPE* in, const LTFAT_TYPE* rec,
417                 ltfat_int L, LTFAT_REAL* snr);
418 
419 /** Normalize a vector
420  *
421  * Normalizes the input array such that the chosen norm is 1.
422  *
423  * \param[in]     in  Input array
424  * \param[in]      L  Length of the arrays
425  * \param[in]   flag  Norm
426  * \param[out]   out  Output array
427  *
428  *  #### Function versions ####
429  *  <tt>
430  *  ltfat_normalize_d(const double in[], ltfat_int L, ltfat_norm_t flag, double out[]);
431  *
432  *  ltfat_normalize_s(const float in[], ltfat_int L, ltfat_norm_t flag, float out[]);
433  *
434  *  ltfat_normalize_dc(const ltfat_complex_d in[], ltfat_int L, ltfat_norm_t flag, ltfat_complex_d out[]);
435  *
436  *  ltfat_normalize_sc(const ltfat_complex_s in[], ltfat_int L, ltfat_norm_t flag, ltfat_complex_s out[]);
437  *  </tt>
438  *
439  * \returns
440  * Status code           | Description
441  * ----------------------|--------------------------------------------
442  * LTFATERR_SUCCESS      | Indicates no error
443  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
444  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
445  * LTFATERR_CANNOTHAPPEN | \a flag is not defined in ltfat_norm_t enum.
446  */
447 LTFAT_API int
448 LTFAT_NAME(normalize)(const LTFAT_TYPE in[], ltfat_int L,
449                       ltfat_norm_t flag, LTFAT_TYPE out[]);
450 
451 /** Ensure the array has complex interleaved layout
452  *
453  * This is a convenience function.
454  * Obviously the *_dc and *_sc versions of the function do nothing.
455  *
456  * \param[in]     in  Input array
457  * \param[in]      L  Length of arrays
458  * \param[out]   out  Output array
459  *
460  * #### Function versions ####
461  * <tt>
462  * ltfat_ensurecomplex_array_d(const double in[], ltfat_int L, ltfat_complex_d out[]);
463  *
464  * ltfat_ensurecomplex_array_s(const float in[], ltfat_int L, ltfat_complex_s out[]);
465  *
466  * ltfat_ensurecomplex_array_dc(const ltfat_complex_d in[], ltfat_int L, ltfat_complex_d out[]);
467  *
468  * ltfat_ensurecomplex_array_sc(const ltfat_complex_s in[], ltfat_int L, ltfat_complex_s out[]);
469  * </tt>
470  *
471  * \returns
472  * Status code           | Description
473  * ----------------------|--------------------------------------------
474  * LTFATERR_SUCCESS      | Indicates no error
475  * LTFATERR_NULLPOINTER  | Either of the arrays is NULL
476  * LTFATERR_BADSIZE      | Length of the arrays is less or equal to 0.
477  */
478 LTFAT_API int
479 LTFAT_NAME(ensurecomplex_array)(const LTFAT_TYPE *in, ltfat_int L, LTFAT_COMPLEX *out);
480 
481 /** @}*/
482 
483 LTFAT_API void
484 LTFAT_NAME(dgtphaselockhelper)(LTFAT_TYPE *cin, ltfat_int L,
485                                ltfat_int W, ltfat_int a,
486                                ltfat_int M, ltfat_int M2,
487                                LTFAT_TYPE *cout);
488 
489 LTFAT_API void
490 LTFAT_NAME(dgtphaseunlockhelper)(LTFAT_TYPE *cin, ltfat_int L,
491                                  ltfat_int W, ltfat_int a,
492                                  ltfat_int M, ltfat_int M2,
493                                  LTFAT_TYPE *cout);
494 
495 LTFAT_API int
496 LTFAT_NAME(reverse_array)(const LTFAT_TYPE *in, ltfat_int L, LTFAT_TYPE *out);
497 
498 LTFAT_API int
499 LTFAT_NAME(conjugate_array)(const LTFAT_TYPE *in, ltfat_int L, LTFAT_TYPE *out);
500 
501 LTFAT_API int
502 LTFAT_NAME(periodize_array)(const LTFAT_TYPE *in, ltfat_int Lin,
503                             ltfat_int Lout, LTFAT_TYPE *out );
504 
505 LTFAT_API int
506 LTFAT_NAME(fold_array)(const LTFAT_TYPE *in, ltfat_int Lin,
507                        ltfat_int offset,
508                        ltfat_int Lfold, LTFAT_TYPE *out);
509 
510 LTFAT_API int
511 LTFAT_NAME(reflect)(const LTFAT_TYPE* in, ltfat_int L, LTFAT_TYPE* out);
512 
513 LTFAT_API int
514 LTFAT_NAME(involute)(const LTFAT_TYPE* in, ltfat_int L, LTFAT_TYPE* out);
515 
516 LTFAT_API void
517 LTFAT_NAME(findmaxinarray)(const LTFAT_TYPE *in, ltfat_int L, LTFAT_TYPE* max, ltfat_int* idx);
518 
519 LTFAT_API int
520 LTFAT_NAME(findmaxinarraywrtmask)(const LTFAT_TYPE *in, const int *mask,
521                                   ltfat_int L, LTFAT_TYPE* max, ltfat_int* idx);
522 
523 LTFAT_API void
524 LTFAT_NAME(findmaxincols)(const LTFAT_TYPE* in, ltfat_int M, ltfat_int M2,
525                           ltfat_int N, LTFAT_TYPE* max, ltfat_int* idx);
526