1/* -*- mode: C -*-  */
2/*
3   IGraph library.
4   Copyright (C) 2003-2012  Gabor Csardi <csardi.gabor@gmail.com>
5   334 Harvard street, Cambridge, MA 02139 USA
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20   02110-1301 USA
21
22*/
23
24#include "igraph_memory.h"
25#include "igraph_random.h"
26#include "igraph_error.h"
27
28#include <assert.h>
29#include <string.h>         /* memcpy & co. */
30#include <stdlib.h>
31
32/**
33 * \section about_igraph_matrix_t_objects About \type igraph_matrix_t objects
34 *
35 * <para>This type is just an interface to \type igraph_vector_t.</para>
36 *
37 * <para>The \type igraph_matrix_t type usually stores n
38 * elements in O(n) space, but not always. See the documentation of
39 * the vector type.</para>
40 */
41
42/**
43 * \section igraph_matrix_constructor_and_destructor Matrix constructors and
44 * destructors
45 */
46
47/**
48 * \ingroup matrix
49 * \function igraph_matrix_init
50 * \brief Initializes a matrix.
51 *
52 * </para><para>
53 * Every matrix needs to be initialized before using it. This is done
54 * by calling this function. A matrix has to be destroyed if it is not
55 * needed any more; see \ref igraph_matrix_destroy().
56 * \param m Pointer to a not yet initialized matrix object to be
57 *        initialized.
58 * \param nrow The number of rows in the matrix.
59 * \param ncol The number of columns in the matrix.
60 * \return Error code.
61 *
62 * Time complexity: usually O(n),
63 * n is the
64 * number of elements in the matrix.
65 */
66
67int FUNCTION(igraph_matrix, init)(TYPE(igraph_matrix) *m, long int nrow, long int ncol) {
68    int ret1;
69    ret1 = FUNCTION(igraph_vector, init)(&m->data, nrow * ncol);
70    m->nrow = nrow;
71    m->ncol = ncol;
72    return ret1;
73}
74
75const TYPE(igraph_matrix) *FUNCTION(igraph_matrix, view)(const TYPE(igraph_matrix) *m,
76        const BASE *data,
77        long int nrow,
78        long int ncol) {
79    TYPE(igraph_matrix) *m2 = (TYPE(igraph_matrix)*)m;
80    FUNCTION(igraph_vector, view)(&m2->data, data, nrow * ncol);
81    m2->nrow = nrow;
82    m2->ncol = ncol;
83    return m;
84}
85
86/**
87 * \ingroup matrix
88 * \function igraph_matrix_destroy
89 * \brief Destroys a matrix object.
90 *
91 * </para><para>
92 * This function frees all the memory allocated for a matrix
93 * object. The destroyed object needs to be reinitialized before using
94 * it again.
95 * \param m The matrix to destroy.
96 *
97 * Time complexity: operating system dependent.
98 */
99
100void FUNCTION(igraph_matrix, destroy)(TYPE(igraph_matrix) *m) {
101    FUNCTION(igraph_vector, destroy)(&m->data);
102}
103
104/**
105 * \ingroup matrix
106 * \function igraph_matrix_capacity
107 * \brief Returns the number of elements allocated for a matrix.
108 *
109 * Note that this might be different from the size of the matrix (as
110 * queried by \ref igraph_matrix_size(), and specifies how many elements
111 * the matrix can hold, without reallocation.
112 * \param v Pointer to the (previously initialized) matrix object
113 *          to query.
114 * \return The allocated capacity.
115 *
116 * \sa \ref igraph_matrix_size(), \ref igraph_matrix_nrow(),
117 * \ref igraph_matrix_ncol().
118 *
119 * Time complexity: O(1).
120 */
121
122long int FUNCTION(igraph_matrix, capacity)(const TYPE(igraph_matrix) *m) {
123    return FUNCTION(igraph_vector, capacity)(&m->data);
124}
125
126
127/**
128 * \section igraph_matrix_accessing_elements Accessing elements of a matrix
129 */
130
131/**
132 * \ingroup matrix
133 * \function igraph_matrix_resize
134 * \brief Resizes a matrix.
135 *
136 * </para><para>
137 * This function resizes a matrix by adding more elements to it.
138 * The matrix contains arbitrary data after resizing it.
139 * That is, after calling this function you cannot expect that element
140 * (i,j) in the matrix remains the
141 * same as before.
142 * \param m Pointer to an already initialized matrix object.
143 * \param nrow The number of rows in the resized matrix.
144 * \param ncol The number of columns in the resized matrix.
145 * \return Error code.
146 *
147 * Time complexity: O(1) if the
148 * matrix gets smaller, usually O(n)
149 * if it gets larger, n is the
150 * number of elements in the resized matrix.
151 */
152
153int FUNCTION(igraph_matrix, resize)(TYPE(igraph_matrix) *m, long int nrow, long int ncol) {
154    FUNCTION(igraph_vector, resize)(&m->data, nrow * ncol);
155    m->nrow = nrow;
156    m->ncol = ncol;
157    return 0;
158}
159
160/**
161 * \ingroup matrix
162 * \function igraph_matrix_resize_min
163 * \brief Deallocates unused memory for a matrix.
164 *
165 * </para><para>
166 * Note that this function might fail if there is not enough memory
167 * available.
168 *
169 * </para><para>
170 * Also note, that this function leaves the matrix intact, i.e.
171 * it does not destroy any of the elements. However, usually it involves
172 * copying the matrix in memory.
173 * \param m Pointer to an initialized matrix.
174 * \return Error code.
175 *
176 * \sa \ref igraph_matrix_resize().
177 *
178 * Time complexity: operating system dependent.
179 */
180
181int FUNCTION(igraph_matrix, resize_min)(TYPE(igraph_matrix) *m) {
182    TYPE(igraph_vector) tmp;
183    long int size = FUNCTION(igraph_matrix, size)(m);
184    long int capacity = FUNCTION(igraph_matrix, capacity)(m);
185    if (size == capacity) {
186        return 0;
187    }
188
189    IGRAPH_CHECK(FUNCTION(igraph_vector, init)(&tmp, size));
190    FUNCTION(igraph_vector, update)(&tmp, &m->data);
191    FUNCTION(igraph_vector, destroy)(&m->data);
192    m->data = tmp;
193
194    return 0;
195}
196
197
198/**
199 * \ingroup matrix
200 * \function igraph_matrix_size
201 * \brief The number of elements in a matrix.
202 *
203 * \param m Pointer to an initialized matrix object.
204 * \return The size of the matrix.
205 *
206 * Time complexity: O(1).
207 */
208
209long int FUNCTION(igraph_matrix, size)(const TYPE(igraph_matrix) *m) {
210    return (m->nrow) * (m->ncol);
211}
212
213/**
214 * \ingroup matrix
215 * \function igraph_matrix_nrow
216 * \brief The number of rows in a matrix.
217 *
218 * \param m Pointer to an initialized matrix object.
219 * \return The number of rows in the matrix.
220 *
221 * Time complexity: O(1).
222 */
223
224long int FUNCTION(igraph_matrix, nrow)(const TYPE(igraph_matrix) *m) {
225    return m->nrow;
226}
227
228/**
229 * \ingroup matrix
230 * \function igraph_matrix_ncol
231 * \brief The number of columns in a matrix.
232 *
233 * \param m Pointer to an initialized matrix object.
234 * \return The number of columns in the matrix.
235 *
236 * Time complexity: O(1).
237 */
238
239long int FUNCTION(igraph_matrix, ncol)(const TYPE(igraph_matrix) *m) {
240    return m->ncol;
241}
242
243/**
244 * \ingroup matrix
245 * \function igraph_matrix_copy_to
246 * \brief Copies a matrix to a regular C array.
247 *
248 * </para><para>
249 * The matrix is copied columnwise, as this is the format most
250 * programs and languages use.
251 * The C array should be of sufficient size; there are (of course) no
252 * range checks.
253 * \param m Pointer to an initialized matrix object.
254 * \param to Pointer to a C array; the place to copy the data to.
255 * \return Error code.
256 *
257 * Time complexity: O(n),
258 * n is the number of
259 * elements in the matrix.
260 */
261
262void FUNCTION(igraph_matrix, copy_to)(const TYPE(igraph_matrix) *m, BASE *to) {
263    FUNCTION(igraph_vector, copy_to)(&m->data, to);
264}
265
266/**
267 * \ingroup matrix
268 * \function igraph_matrix_null
269 * \brief Sets all elements in a matrix to zero.
270 *
271 * \param m Pointer to an initialized matrix object.
272 *
273 * Time complexity: O(n),
274 * n is the number of  elements in
275 * the matrix.
276 */
277
278void FUNCTION(igraph_matrix, null)(TYPE(igraph_matrix) *m) {
279    FUNCTION(igraph_vector, null)(&m->data);
280}
281
282/**
283 * \ingroup matrix
284 * \function igraph_matrix_add_cols
285 * \brief Adds columns to a matrix.
286 * \param m The matrix object.
287 * \param n The number of columns to add.
288 * \return Error code, \c IGRAPH_ENOMEM if there is
289 *   not enough memory to perform the operation.
290 *
291 * Time complexity: linear with the number of elements of the new,
292 * resized matrix.
293 */
294
295int FUNCTION(igraph_matrix, add_cols)(TYPE(igraph_matrix) *m, long int n) {
296    FUNCTION(igraph_matrix, resize)(m, m->nrow, m->ncol + n);
297    return 0;
298}
299
300/**
301 * \ingroup matrix
302 * \function igraph_matrix_add_rows
303 * \brief Adds rows to a matrix.
304 * \param m The matrix object.
305 * \param n The number of rows to add.
306 * \return Error code, \c IGRAPH_ENOMEM if there
307 *   isn't enough memory for the operation.
308 *
309 * Time complexity: linear with the number of elements of the new,
310 * resized matrix.
311 */
312
313int FUNCTION(igraph_matrix, add_rows)(TYPE(igraph_matrix) *m, long int n) {
314    long int i;
315    FUNCTION(igraph_vector, resize)(&m->data, (m->ncol) * (m->nrow + n));
316    for (i = m->ncol - 1; i >= 0; i--) {
317        FUNCTION(igraph_vector, move_interval2)(&m->data, (m->nrow)*i, (m->nrow) * (i + 1),
318                                                (m->nrow + n)*i);
319    }
320    m->nrow += n;
321    return 0;
322}
323
324/**
325 * \ingroup matrix
326 * \function igraph_matrix_remove_col
327 * \brief Removes a column from a matrix.
328 *
329 * \param m The matrix object.
330 * \param col The column to remove.
331 * \return Error code, always returns with success.
332 *
333 * Time complexity: linear with the number of elements of the new,
334 * resized matrix.
335 */
336
337int FUNCTION(igraph_matrix, remove_col)(TYPE(igraph_matrix) *m, long int col) {
338    FUNCTION(igraph_vector, remove_section)(&m->data, (m->nrow)*col, (m->nrow) * (col + 1));
339    m->ncol--;
340    return 0;
341}
342
343/**
344 * \ingroup matrix
345 * \function igraph_matrix_permdelete_rows
346 * \brief Removes rows from a matrix (for internal use).
347 *
348 * Time complexity: linear with the number of elements of the original
349 * matrix.
350 */
351
352int FUNCTION(igraph_matrix, permdelete_rows)(TYPE(igraph_matrix) *m, long int *index, long int nremove) {
353    long int i, j;
354    for (j = 0; j < m->nrow; j++) {
355        if (index[j] != 0) {
356            for (i = 0; i < m->ncol; i++) {
357                MATRIX(*m, index[j] - 1, i) = MATRIX(*m, j, i);
358            }
359        }
360    }
361    /* Remove unnecessary elements from the end of each column */
362    for (i = 0; i < m->ncol; i++)
363        FUNCTION(igraph_vector, remove_section)(&m->data,
364                                                (i + 1) * (m->nrow - nremove), (i + 1) * (m->nrow - nremove) + nremove);
365    FUNCTION(igraph_matrix, resize)(m, m->nrow - nremove, m->ncol);
366
367    return 0;
368}
369
370/**
371 * \ingroup matrix
372 * \function igraph_matrix_delete_rows_neg
373 * \brief Removes columns from a matrix (for internal use).
374 *
375 * Time complexity: linear with the number of elements of the original
376 * matrix.
377 */
378
379int FUNCTION(igraph_matrix, delete_rows_neg)(TYPE(igraph_matrix) *m,
380        const igraph_vector_t *neg, long int nremove) {
381    long int i, j, idx = 0;
382    for (i = 0; i < m->ncol; i++) {
383        for (j = 0; j < m->nrow; j++) {
384            if (VECTOR(*neg)[j] >= 0) {
385                MATRIX(*m, idx++, i) = MATRIX(*m, j, i);
386            }
387        }
388        idx = 0;
389    }
390    FUNCTION(igraph_matrix, resize)(m, m->nrow - nremove, m->ncol);
391
392    return 0;
393}
394
395/**
396 * \ingroup matrix
397 * \function igraph_matrix_copy
398 * \brief Copies a matrix.
399 *
400 * </para><para>
401 * Creates a matrix object by copying from an existing matrix.
402 * \param to Pointer to an uninitialized matrix object.
403 * \param from The initialized matrix object to copy.
404 * \return Error code, \c IGRAPH_ENOMEM if there
405 *   isn't enough memory to allocate the new matrix.
406 *
407 * Time complexity: O(n), the number
408 * of elements in the matrix.
409 */
410
411int FUNCTION(igraph_matrix, copy)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from) {
412    to->nrow = from->nrow;
413    to->ncol = from->ncol;
414    return FUNCTION(igraph_vector, copy)(&to->data, &from->data);
415}
416
417#ifndef NOTORDERED
418
419/**
420 * \function igraph_matrix_max
421 *
422 * Returns the maximal element of a matrix.
423 * \param m The matrix object.
424 * \return The maximum element. For empty matrix the returned value is
425 * undefined.
426 *
427 * Added in version 0.2.</para><para>
428 *
429 * Time complexity: O(n), the number of elements in the matrix.
430 */
431
432igraph_real_t FUNCTION(igraph_matrix, max)(const TYPE(igraph_matrix) *m) {
433    return FUNCTION(igraph_vector, max)(&m->data);
434}
435
436#endif
437
438/**
439 * \function igraph_matrix_scale
440 *
441 * Multiplies each element of the matrix by a constant.
442 * \param m The matrix.
443 * \param by The constant.
444 *
445 * Added in version 0.2.</para><para>
446 *
447 * Time complexity: O(n), the number of elements in the matrix.
448 */
449
450void FUNCTION(igraph_matrix, scale)(TYPE(igraph_matrix) *m, BASE by) {
451    FUNCTION(igraph_vector, scale)(&m->data, by);
452}
453
454/**
455 * \function igraph_matrix_select_rows
456 * \brief Select some rows of a matrix.
457 *
458 * This function selects some rows of a matrix and returns them in a
459 * new matrix. The result matrix should be initialized before calling
460 * the function.
461 * \param m The input matrix.
462 * \param res The result matrix. It should be initialized and will be
463 *    resized as needed.
464 * \param rows Vector; it contains the row indices (starting with
465 *    zero) to extract. Note that no range checking is performed.
466 * \return Error code.
467 *
468 * Time complexity: O(nm), n is the number of rows, m the number of
469 * columns of the result matrix.
470 */
471
472int FUNCTION(igraph_matrix, select_rows)(const TYPE(igraph_matrix) *m,
473        TYPE(igraph_matrix) *res,
474        const igraph_vector_t *rows) {
475    long int norows = igraph_vector_size(rows);
476    long int i, j, ncols = FUNCTION(igraph_matrix, ncol)(m);
477
478    IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(res, norows, ncols));
479    for (i = 0; i < norows; i++) {
480        for (j = 0; j < ncols; j++) {
481            MATRIX(*res, i, j) = MATRIX(*m, (long int)VECTOR(*rows)[i], j);
482        }
483    }
484
485    return 0;
486}
487
488/**
489 * \function igraph_matrix_select_rows_cols
490 * \brief Select some rows and columns of a matrix.
491 *
492 * This function selects some rows and columns of a matrix and returns
493 * them in a new matrix. The result matrix should be initialized before
494 * calling the function.
495 * \param m The input matrix.
496 * \param res The result matrix. It should be initialized and will be
497 *    resized as needed.
498 * \param rows Vector; it contains the row indices (starting with
499 *    zero) to extract. Note that no range checking is performed.
500 * \param cols Vector; it contains the column indices (starting with
501 *    zero) to extract. Note that no range checking is performed.
502 * \return Error code.
503 *
504 * Time complexity: O(nm), n is the number of rows, m the number of
505 * columns of the result matrix.
506 */
507
508int FUNCTION(igraph_matrix, select_rows_cols)(const TYPE(igraph_matrix) *m,
509        TYPE(igraph_matrix) *res,
510        const igraph_vector_t *rows,
511        const igraph_vector_t *cols) {
512    long int nrows = igraph_vector_size(rows);
513    long int ncols = igraph_vector_size(cols);
514    long int i, j;
515
516    IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(res, nrows, ncols));
517    for (i = 0; i < nrows; i++) {
518        for (j = 0; j < ncols; j++) {
519            MATRIX(*res, i, j) = MATRIX(*m, (long int)VECTOR(*rows)[i],
520                                        (long int)VECTOR(*cols)[j]);
521        }
522    }
523
524    return 0;
525}
526
527/**
528 * \function igraph_matrix_get_col
529 * \brief Select a column.
530 *
531 * Extract a column of a matrix and return it as a vector.
532 * \param m The input matrix.
533 * \param res The result will we stored in this vector. It should be
534 *   initialized and will be resized as needed.
535 * \param index The index of the column to select.
536 * \return Error code.
537 *
538 * Time complexity: O(n), the number of rows in the matrix.
539 */
540
541int FUNCTION(igraph_matrix, get_col)(const TYPE(igraph_matrix) *m,
542                                     TYPE(igraph_vector) *res,
543                                     long int index) {
544    long int nrow = FUNCTION(igraph_matrix, nrow)(m);
545
546    if (index >= m->ncol) {
547        IGRAPH_ERROR("Index out of range for selecting matrix column", IGRAPH_EINVAL);
548    }
549    IGRAPH_CHECK(FUNCTION(igraph_vector, get_interval)(&m->data, res,
550                 nrow * index, nrow * (index + 1)));
551    return 0;
552}
553
554/**
555 * \function igraph_matrix_sum
556 * \brief Sum of elements.
557 *
558 * Returns the sum of the elements of a matrix.
559 * \param m The input matrix.
560 * \return The sum of the elements.
561 *
562 * Time complexity: O(mn), the number of elements in the matrix.
563 */
564
565BASE FUNCTION(igraph_matrix, sum)(const TYPE(igraph_matrix) *m) {
566    return FUNCTION(igraph_vector, sum)(&m->data);
567}
568
569/**
570 * \function igraph_matrix_all_e
571 * \brief Are all elements equal?
572 *
573 * \param lhs The first matrix.
574 * \param rhs The second matrix.
575 * \return Positive integer (=true) if the elements in the \p lhs are all
576 *    equal to the corresponding elements in \p rhs. Returns \c 0
577 *    (=false) if the dimensions of the matrices don't match.
578 *
579 * Time complexity: O(nm), the size of the matrices.
580 */
581
582igraph_bool_t FUNCTION(igraph_matrix, all_e)(const TYPE(igraph_matrix) *lhs,
583        const TYPE(igraph_matrix) *rhs) {
584    return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow &&
585           FUNCTION(igraph_vector, all_e)(&lhs->data, &rhs->data);
586}
587
588igraph_bool_t
589FUNCTION(igraph_matrix, is_equal)(const TYPE(igraph_matrix) *lhs,
590                                  const TYPE(igraph_matrix) *rhs) {
591    return FUNCTION(igraph_matrix, all_e)(lhs, rhs);
592}
593
594#ifndef NOTORDERED
595
596/**
597 * \function igraph_matrix_all_l
598 * \brief Are all elements less?
599 *
600 * \param lhs The first matrix.
601 * \param rhs The second matrix.
602 * \return Positive integer (=true) if the elements in the \p lhs are all
603 *    less than the corresponding elements in \p rhs. Returns \c 0
604 *    (=false) if the dimensions of the matrices don't match.
605 *
606 * Time complexity: O(nm), the size of the matrices.
607 */
608
609igraph_bool_t FUNCTION(igraph_matrix, all_l)(const TYPE(igraph_matrix) *lhs,
610        const TYPE(igraph_matrix) *rhs) {
611    return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow &&
612           FUNCTION(igraph_vector, all_l)(&lhs->data, &rhs->data);
613}
614
615/**
616 * \function igraph_matrix_all_g
617 * \brief Are all elements greater?
618 *
619 * \param lhs The first matrix.
620 * \param rhs The second matrix.
621 * \return Positive integer (=true) if the elements in the \p lhs are all
622 *    greater than the corresponding elements in \p rhs. Returns \c 0
623 *    (=false) if the dimensions of the matrices don't match.
624 *
625 * Time complexity: O(nm), the size of the matrices.
626 */
627
628igraph_bool_t FUNCTION(igraph_matrix, all_g)(const TYPE(igraph_matrix) *lhs,
629        const TYPE(igraph_matrix) *rhs) {
630    return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow &&
631           FUNCTION(igraph_vector, all_g)(&lhs->data, &rhs->data);
632}
633
634/**
635 * \function igraph_matrix_all_le
636 * \brief Are all elements less or equal?
637 *
638 * \param lhs The first matrix.
639 * \param rhs The second matrix.
640 * \return Positive integer (=true) if the elements in the \p lhs are all
641 *    less than or equal to the corresponding elements in \p
642 *    rhs. Returns \c 0 (=false) if the dimensions of the matrices
643 *    don't match.
644 *
645 * Time complexity: O(nm), the size of the matrices.
646 */
647
648igraph_bool_t
649FUNCTION(igraph_matrix, all_le)(const TYPE(igraph_matrix) *lhs,
650                                const TYPE(igraph_matrix) *rhs) {
651    return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow &&
652           FUNCTION(igraph_vector, all_le)(&lhs->data, &rhs->data);
653}
654
655/**
656 * \function igraph_matrix_all_ge
657 * \brief Are all elements greater or equal?
658 *
659 * \param lhs The first matrix.
660 * \param rhs The second matrix.
661 * \return Positive integer (=true) if the elements in the \p lhs are all
662 *    greater than or equal to the corresponding elements in \p
663 *    rhs. Returns \c 0 (=false) if the dimensions of the matrices
664 *    don't match.
665 *
666 * Time complexity: O(nm), the size of the matrices.
667 */
668
669igraph_bool_t
670FUNCTION(igraph_matrix, all_ge)(const TYPE(igraph_matrix) *lhs,
671                                const TYPE(igraph_matrix) *rhs) {
672    return lhs->ncol == rhs->ncol && lhs->nrow == rhs->nrow &&
673           FUNCTION(igraph_vector, all_ge)(&lhs->data, &rhs->data);
674}
675
676#endif
677
678#ifndef NOTORDERED
679
680/**
681 * \function igraph_matrix_maxdifference
682 * \brief Maximum absolute difference between two matrices.
683 *
684 * Calculate the maximum absolute difference of two matrices. Both matrices
685 * must be non-empty. If their dimensions differ then a warning is given and
686 * the comparison is performed by vectors columnwise from both matrices.
687 * The remaining elements in the larger vector are ignored.
688 * \param m1 The first matrix.
689 * \param m2 The second matrix.
690 * \return The element with the largest absolute value in \c m1 - \c m2.
691 *
692 * Time complexity: O(mn), the elements in the smaller matrix.
693 */
694
695igraph_real_t FUNCTION(igraph_matrix, maxdifference)(const TYPE(igraph_matrix) *m1,
696        const TYPE(igraph_matrix) *m2) {
697    long int col1 = FUNCTION(igraph_matrix, ncol)(m1);
698    long int col2 = FUNCTION(igraph_matrix, ncol)(m2);
699    long int row1 = FUNCTION(igraph_matrix, nrow)(m1);
700    long int row2 = FUNCTION(igraph_matrix, nrow)(m2);
701    if (col1 != col2 || row1 != row2) {
702        IGRAPH_WARNING("Comparing non-conformant matrices");
703    }
704    return FUNCTION(igraph_vector, maxdifference)(&m1->data, &m2->data);
705}
706
707#endif
708
709/**
710 * \function igraph_matrix_transpose
711 * \brief Transpose a matrix.
712 *
713 * Calculate the transpose of a matrix. Note that the function
714 * reallocates the memory used for the matrix.
715 * \param m The input (and output) matrix.
716 * \return Error code.
717 *
718 * Time complexity: O(mn), the number of elements in the matrix.
719 */
720
721int FUNCTION(igraph_matrix, transpose)(TYPE(igraph_matrix) *m) {
722    long int nrow = m->nrow;
723    long int ncol = m->ncol;
724    if (nrow > 1 && ncol > 1) {
725        TYPE(igraph_vector) newdata;
726        long int i, size = nrow * ncol, mod = size - 1;
727        FUNCTION(igraph_vector, init)(&newdata, size);
728        IGRAPH_FINALLY(FUNCTION(igraph_vector, destroy), &newdata);
729        for (i = 0; i < size; i++) {
730            VECTOR(newdata)[i] = VECTOR(m->data)[ (i * nrow) % mod ];
731        }
732        VECTOR(newdata)[size - 1] = VECTOR(m->data)[size - 1];
733        FUNCTION(igraph_vector, destroy)(&m->data);
734        IGRAPH_FINALLY_CLEAN(1);
735        m->data = newdata;
736    }
737    m->nrow = ncol;
738    m->ncol = nrow;
739
740    return 0;
741}
742
743/**
744 * \function igraph_matrix_e
745 * Extract an element from a matrix.
746 *
747 * Use this if you need a function for some reason and cannot use the
748 * \ref MATRIX macro. Note that no range checking is performed.
749 * \param m The input matrix.
750 * \param row The row index.
751 * \param col The column index.
752 * \return The element in the given row and column.
753 *
754 * Time complexity: O(1).
755 */
756
757BASE FUNCTION(igraph_matrix, e)(const TYPE(igraph_matrix) *m,
758                                long int row, long int col) {
759    return MATRIX(*m, row, col);
760}
761
762/**
763 * \function igraph_matrix_e_ptr
764 * Pointer to an element of a matrix.
765 *
766 * The function returns a pointer to an element. No range checking is
767 * performed.
768 * \param m The input matrix.
769 * \param row The row index.
770 * \param col The column index.
771 * \return Pointer to the element in the given row and column.
772 *
773 * Time complexity: O(1).
774 */
775
776BASE* FUNCTION(igraph_matrix, e_ptr)(const TYPE(igraph_matrix) *m,
777                                     long int row, long int col) {
778    return &MATRIX(*m, row, col);
779}
780
781/**
782 * \function igraph_matrix_set
783 * Set an element.
784 *
785 * Set an element of a matrix. No range checking is performed.
786 * \param m The input matrix.
787 * \param row The row index.
788 * \param col The column index.
789 * \param value The new value of the element.
790 *
791 * Time complexity: O(1).
792 */
793
794void FUNCTION(igraph_matrix, set)(TYPE(igraph_matrix)* m, long int row, long int col,
795                                  BASE value) {
796    MATRIX(*m, row, col) = value;
797}
798
799/**
800 * \function igraph_matrix_fill
801 * Fill with an element.
802 *
803 * Set the matrix to a constant matrix.
804 * \param m The input matrix.
805 * \param e The element to set.
806 *
807 * Time complexity: O(mn), the number of elements.
808 */
809
810void FUNCTION(igraph_matrix, fill)(TYPE(igraph_matrix) *m, BASE e) {
811    FUNCTION(igraph_vector, fill)(&m->data, e);
812}
813
814/**
815 * \function igraph_matrix_update
816 * Update from another matrix.
817 *
818 * This function replicates \p from in the matrix \p to.
819 * Note that \p to must be already initialized.
820 * \param to The result matrix.
821 * \param from The matrix to replicate; it is left unchanged.
822 * \return Error code.
823 *
824 * Time complexity: O(mn), the number of elements.
825 */
826
827int FUNCTION(igraph_matrix, update)(TYPE(igraph_matrix) *to,
828                                    const TYPE(igraph_matrix) *from) {
829
830    IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(to, from->nrow, from->ncol));
831    FUNCTION(igraph_vector, update)(&to->data, &from->data);
832    return 0;
833}
834
835/**
836 * \function igraph_matrix_rbind
837 * Combine two matrices rowwise.
838 *
839 * This function places the rows of \p from below the rows of \c to
840 * and stores the result in \p to. The number of columns in the two
841 * matrices must match.
842 * \param to The upper matrix; the result is also stored here.
843 * \param from The lower matrix. It is left unchanged.
844 * \return Error code.
845 *
846 * Time complexity: O(mn), the number of elements in the newly created
847 * matrix.
848 */
849
850int FUNCTION(igraph_matrix, rbind)(TYPE(igraph_matrix) *to,
851                                   const TYPE(igraph_matrix) *from) {
852    long int tocols = to->ncol, fromcols = from->ncol;
853    long int torows = to->nrow, fromrows = from->nrow;
854    long int offset, c, r, index, offset2;
855    if (tocols != fromcols) {
856        IGRAPH_ERROR("Cannot do rbind, number of columns do not match", IGRAPH_EINVAL);
857    }
858
859    IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(&to->data,
860                 tocols * (fromrows + torows)));
861    to->nrow += fromrows;
862
863    offset = (tocols - 1) * fromrows;
864    index = tocols * torows - 1;
865    for (c = tocols - 1; c > 0; c--) {
866        for (r = 0; r < torows; r++, index--) {
867            VECTOR(to->data)[index + offset] = VECTOR(to->data)[index];
868        }
869        offset -= fromrows;
870    }
871
872    offset = torows; offset2 = 0;
873    for (c = 0; c < tocols; c++) {
874        memcpy(VECTOR(to->data) + offset, VECTOR(from->data) + offset2,
875               sizeof(BASE) * (size_t) fromrows);
876        offset += fromrows + torows;
877        offset2 += fromrows;
878    }
879    return 0;
880}
881
882/**
883 * \function igraph_matrix_cbind
884 * Combine matrices columnwise.
885 *
886 * This function places the columns of \p from on the right of \p to,
887 * and stores the result in \p to.
888 * \param to The left matrix; the result is stored here too.
889 * \param from The right matrix. It is left unchanged.
890 * \return Error code.
891 *
892 * Time complexity: O(mn), the number of elements on the new matrix.
893 */
894
895int FUNCTION(igraph_matrix, cbind)(TYPE(igraph_matrix) *to,
896                                   const TYPE(igraph_matrix) *from) {
897
898    long int tocols = to->ncol, fromcols = from->ncol;
899    long int torows = to->nrow, fromrows = from->nrow;
900    if (torows != fromrows) {
901        IGRAPH_ERROR("Cannot do rbind, number of rows do not match", IGRAPH_EINVAL);
902    }
903    IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(to, torows, tocols + fromcols));
904    FUNCTION(igraph_vector, copy_to)(&from->data, VECTOR(to->data) + tocols * torows);
905    return 0;
906}
907
908/**
909 * \function igraph_matrix_swap
910 * Swap two matrices.
911 *
912 * The contents of the two matrices will be swapped. They must have the
913 * same dimensions.
914 * \param m1 The first matrix.
915 * \param m2 The second matrix.
916 * \return Error code.
917 *
918 * Time complexity: O(mn), the number of elements in the matrices.
919 */
920
921int FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2) {
922    if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) {
923        IGRAPH_ERROR("Cannot swap non-conformant matrices", IGRAPH_EINVAL);
924    }
925    return FUNCTION(igraph_vector, swap)(&m1->data, &m2->data);
926}
927
928/**
929 * \function igraph_matrix_get_row
930 * Extract a row.
931 *
932 * Extract a row from a matrix and return it as a vector.
933 * \param m The input matrix.
934 * \param res Pointer to an initialized vector; it will be resized if
935 *   needed.
936 * \param index The index of the row to select.
937 * \return Error code.
938 *
939 * Time complexity: O(n), the number of columns in the matrix.
940 */
941
942int FUNCTION(igraph_matrix, get_row)(const TYPE(igraph_matrix) *m,
943                                     TYPE(igraph_vector) *res, long int index) {
944    long int rows = m->nrow, cols = m->ncol;
945    long int i, j;
946
947    if (index >= rows) {
948        IGRAPH_ERROR("Index out of range for selecting matrix row", IGRAPH_EINVAL);
949    }
950    IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, cols));
951
952    for (i = index, j = 0; j < cols; i += rows, j++) {
953        VECTOR(*res)[j] = VECTOR(m->data)[i];
954    }
955    return 0;
956}
957
958/**
959 * \function igraph_matrix_set_row
960 * Set a row from a vector.
961 *
962 * Sets the elements of a row with the given vector. This has the effect of
963 * setting row \c index to have the elements in the vector \c v. The length of
964 * the vector and the number of columns in the matrix must match,
965 * otherwise an error is triggered.
966 * \param m The input matrix.
967 * \param v The vector containing the new elements of the row.
968 * \param index Index of the row to set.
969 * \return Error code.
970 *
971 * Time complexity: O(n), the number of columns in the matrix.
972 */
973
974int FUNCTION(igraph_matrix, set_row)(TYPE(igraph_matrix) *m,
975                                     const TYPE(igraph_vector) *v, long int index) {
976    long int rows = m->nrow, cols = m->ncol;
977    long int i, j;
978
979    if (index >= rows) {
980        IGRAPH_ERROR("Index out of range for selecting matrix row", IGRAPH_EINVAL);
981    }
982    if (FUNCTION(igraph_vector, size)(v) != cols) {
983        IGRAPH_ERROR("Cannot set matrix row, invalid vector length", IGRAPH_EINVAL);
984    }
985    for (i = index, j = 0; j < cols; i += rows, j++) {
986        VECTOR(m->data)[i] = VECTOR(*v)[j];
987    }
988    return 0;
989}
990
991/**
992 * \function igraph_matrix_set_col
993 * Set a column from a vector.
994 *
995 * Sets the elements of a column with the given vector. In effect, column
996 * \c index will be set with elements from the vector \c v. The length of
997 * the vector and the number of rows in the matrix must match,
998 * otherwise an error is triggered.
999 * \param m The input matrix.
1000 * \param v The vector containing the new elements of the column.
1001 * \param index Index of the column to set.
1002 * \return Error code.
1003 *
1004 * Time complexity: O(m), the number of rows in the matrix.
1005 */
1006
1007int FUNCTION(igraph_matrix, set_col)(TYPE(igraph_matrix) *m,
1008                                     const TYPE(igraph_vector) *v, long int index) {
1009    long int rows = m->nrow, cols = m->ncol;
1010    long int i, j;
1011
1012    if (index >= cols) {
1013        IGRAPH_ERROR("Index out of range for setting matrix column", IGRAPH_EINVAL);
1014    }
1015    if (FUNCTION(igraph_vector, size)(v) != rows) {
1016        IGRAPH_ERROR("Cannot set matrix column, invalid vector length", IGRAPH_EINVAL);
1017    }
1018    for (i = index * rows, j = 0; j < rows; i++, j++) {
1019        VECTOR(m->data)[i] = VECTOR(*v)[j];
1020    }
1021    return 0;
1022}
1023
1024/**
1025 * \function igraph_matrix_swap_rows
1026 * Swap two rows.
1027 *
1028 * Swap two rows in the matrix.
1029 * \param m The input matrix.
1030 * \param i The index of the first row.
1031 * \param j The index of the second row.
1032 * \return Error code.
1033 *
1034 * Time complexity: O(n), the number of columns.
1035 */
1036
1037int FUNCTION(igraph_matrix, swap_rows)(TYPE(igraph_matrix) *m,
1038                                       long int i, long int j) {
1039    long int ncol = m->ncol, nrow = m->nrow;
1040    long int n = nrow * ncol;
1041    long int index1, index2;
1042    if (i >= nrow || j >= nrow) {
1043        IGRAPH_ERROR("Cannot swap rows, index out of range", IGRAPH_EINVAL);
1044    }
1045    if (i == j) {
1046        return 0;
1047    }
1048    for (index1 = i, index2 = j; index1 < n; index1 += nrow, index2 += nrow) {
1049        BASE tmp;
1050        tmp = VECTOR(m->data)[index1];
1051        VECTOR(m->data)[index1] = VECTOR(m->data)[index2];
1052        VECTOR(m->data)[index2] = tmp;
1053    }
1054    return 0;
1055}
1056
1057/**
1058 * \function igraph_matrix_swap_cols
1059 * Swap two columns.
1060 *
1061 * Swap two columns in the matrix.
1062 * \param m The input matrix.
1063 * \param i The index of the first column.
1064 * \param j The index of the second column.
1065 * \return Error code.
1066 *
1067 * Time complexity: O(m), the number of rows.
1068 */
1069
1070int FUNCTION(igraph_matrix, swap_cols)(TYPE(igraph_matrix) *m,
1071                                       long int i, long int j) {
1072    long int ncol = m->ncol, nrow = m->nrow;
1073    long int k, index1, index2;
1074    if (i >= ncol || j >= ncol) {
1075        IGRAPH_ERROR("Cannot swap columns, index out of range", IGRAPH_EINVAL);
1076    }
1077    if (i == j) {
1078        return 0;
1079    }
1080    for (index1 = i * nrow, index2 = j * nrow, k = 0; k < nrow; k++, index1++, index2++) {
1081        BASE tmp = VECTOR(m->data)[index1];
1082        VECTOR(m->data)[index1] = VECTOR(m->data)[index2];
1083        VECTOR(m->data)[index2] = tmp;
1084    }
1085    return 0;
1086}
1087
1088/**
1089 * \function igraph_matrix_add_constant
1090 * Add a constant to every element.
1091 *
1092 * \param m The input matrix.
1093 * \param plud The constant to add.
1094 *
1095 * Time complexity: O(mn), the number of elements.
1096 */
1097
1098void FUNCTION(igraph_matrix, add_constant)(TYPE(igraph_matrix) *m, BASE plus) {
1099    FUNCTION(igraph_vector, add_constant)(&m->data, plus);
1100}
1101
1102/**
1103 * \function igraph_matrix_add
1104 * Add two matrices.
1105 *
1106 * Add \p m2 to \p m1, and store the result in \p m1. The dimensions of the
1107 * matrices must match.
1108 * \param m1 The first matrix; the result will be stored here.
1109 * \param m2 The second matrix; it is left unchanged.
1110 * \return Error code.
1111 *
1112 * Time complexity: O(mn), the number of elements.
1113 */
1114
1115int FUNCTION(igraph_matrix, add)(TYPE(igraph_matrix) *m1,
1116                                 const TYPE(igraph_matrix) *m2) {
1117    if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) {
1118        IGRAPH_ERROR("Cannot add non-conformant matrices", IGRAPH_EINVAL);
1119    }
1120    return FUNCTION(igraph_vector, add)(&m1->data, &m2->data);
1121}
1122
1123/**
1124 * \function igraph_matrix_sub
1125 * Difference of two matrices.
1126 *
1127 * Subtract \p m2 from \p m1 and store the result in \p m1.
1128 * The dimensions of the two matrices must match.
1129 * \param m1 The first matrix; the result is stored here.
1130 * \param m2 The second matrix; it is left unchanged.
1131 * \return Error code.
1132 *
1133 * Time complexity: O(mn), the number of elements.
1134 */
1135
1136int FUNCTION(igraph_matrix, sub)(TYPE(igraph_matrix) *m1,
1137                                 const TYPE(igraph_matrix) *m2) {
1138    if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) {
1139        IGRAPH_ERROR("Cannot subtract non-conformant matrices", IGRAPH_EINVAL);
1140    }
1141    return FUNCTION(igraph_vector, sub)(&m1->data, &m2->data);
1142}
1143
1144/**
1145 * \function igraph_matrix_mul_elements
1146 * Elementwise multiplication.
1147 *
1148 * Multiply \p m1 by \p m2 elementwise and store the result in \p m1.
1149 * The dimensions of the two matrices must match.
1150 * \param m1 The first matrix; the result is stored here.
1151 * \param m2 The second matrix; it is left unchanged.
1152 * \return Error code.
1153 *
1154 * Time complexity: O(mn), the number of elements.
1155 */
1156
1157int FUNCTION(igraph_matrix, mul_elements)(TYPE(igraph_matrix) *m1,
1158        const TYPE(igraph_matrix) *m2) {
1159    if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) {
1160        IGRAPH_ERROR("Cannot multiply non-conformant matrices", IGRAPH_EINVAL);
1161    }
1162    return FUNCTION(igraph_vector, mul)(&m1->data, &m2->data);
1163}
1164
1165/**
1166 * \function igraph_matrix_div_elements
1167 * Elementwise division.
1168 *
1169 * Divide \p m1 by \p m2 elementwise and store the result in \p m1.
1170 * The dimensions of the two matrices must match.
1171 * \param m1 The dividend. The result is store here.
1172 * \param m2 The divisor. It is left unchanged.
1173 * \return Error code.
1174 *
1175 * Time complexity: O(mn), the number of elements.
1176 */
1177
1178int FUNCTION(igraph_matrix, div_elements)(TYPE(igraph_matrix) *m1,
1179        const TYPE(igraph_matrix) *m2) {
1180    if (m1->nrow != m2->nrow || m1->ncol != m2->ncol) {
1181        IGRAPH_ERROR("Cannot divide non-conformant matrices", IGRAPH_EINVAL);
1182    }
1183    return FUNCTION(igraph_vector, div)(&m1->data, &m2->data);
1184}
1185
1186#ifndef NOTORDERED
1187
1188/**
1189 * \function igraph_matrix_min
1190 * Minimum element.
1191 *
1192 * Returns the smallest element of a non-empty matrix.
1193 * \param m The input matrix.
1194 * \return The smallest element.
1195 *
1196 * Time complexity: O(mn), the number of elements.
1197 */
1198
1199igraph_real_t FUNCTION(igraph_matrix, min)(const TYPE(igraph_matrix) *m) {
1200    return FUNCTION(igraph_vector, min)(&m->data);
1201}
1202
1203/**
1204 * \function igraph_matrix_which_min
1205 * Indices of the minimum.
1206 *
1207 * Gives the indices of the (first) smallest element in a non-empty
1208 * matrix.
1209 * \param m The matrix.
1210 * \param i Pointer to a <type>long int</type>. The row index of the
1211 *   minimum is stored here.
1212 * \param j Pointer to a <type>long int</type>. The column index of
1213 *   the minimum is stored here.
1214 * \return Error code.
1215 *
1216 * Time complexity: O(mn), the number of elements.
1217 */
1218
1219int FUNCTION(igraph_matrix, which_min)(const TYPE(igraph_matrix) *m,
1220                                       long int *i, long int *j) {
1221    long int vmin = FUNCTION(igraph_vector, which_min)(&m->data);
1222    *i = vmin % m->nrow;
1223    *j = vmin / m->nrow;
1224    return 0;
1225}
1226
1227/**
1228 * \function igraph_matrix_which_max
1229 * Indices of the maximum.
1230 *
1231 * Gives the indices of the (first) largest element in a non-empty
1232 * matrix.
1233 * \param m The matrix.
1234 * \param i Pointer to a <type>long int</type>. The row index of the
1235 *   maximum is stored here.
1236 * \param j Pointer to a <type>long int</type>. The column index of
1237 *   the maximum is stored here.
1238 * \return Error code.
1239 *
1240 * Time complexity: O(mn), the number of elements.
1241 */
1242
1243int FUNCTION(igraph_matrix, which_max)(const TYPE(igraph_matrix) *m,
1244                                       long int *i, long int *j) {
1245    long int vmax = FUNCTION(igraph_vector, which_max)(&m->data);
1246    *i = vmax % m->nrow;
1247    *j = vmax / m->nrow;
1248    return 0;
1249}
1250
1251/**
1252 * \function igraph_matrix_minmax
1253 * Minimum and maximum
1254 *
1255 * The maximum and minimum elements of a non-empty matrix.
1256 * \param m The input matrix.
1257 * \param min Pointer to a base type. The minimum is stored here.
1258 * \param max Pointer to a base type. The maximum is stored here.
1259 * \return Error code.
1260 *
1261 * Time complexity: O(mn), the number of elements.
1262 */
1263
1264int FUNCTION(igraph_matrix, minmax)(const TYPE(igraph_matrix) *m,
1265                                    BASE *min, BASE *max) {
1266    return FUNCTION(igraph_vector, minmax)(&m->data, min, max);
1267}
1268
1269/**
1270 * \function igraph_matrix_which_minmax
1271 * Indices of the minimum and maximum
1272 *
1273 * Find the positions of the smallest and largest elements of a
1274 * non-empty matrix.
1275 * \param m The input matrix.
1276 * \param imin Pointer to a <type>long int</type>, the row index of
1277 *   the minimum is stored here.
1278 * \param jmin Pointer to a <type>long int</type>, the column index of
1279 *   the minimum is stored here.
1280 * \param imax Pointer to a <type>long int</type>, the row index of
1281 *   the maximum is stored here.
1282 * \param jmax Pointer to a <type>long int</type>, the column index of
1283 *   the maximum is stored here.
1284 * \return Error code.
1285 *
1286 * Time complexity: O(mn), the number of elements.
1287 */
1288
1289int FUNCTION(igraph_matrix, which_minmax)(const TYPE(igraph_matrix) *m,
1290        long int *imin, long int *jmin,
1291        long int *imax, long int *jmax) {
1292    long int vmin, vmax;
1293    FUNCTION(igraph_vector, which_minmax)(&m->data, &vmin, &vmax);
1294    *imin = vmin % m->nrow;
1295    *jmin = vmin / m->nrow;
1296    *imax = vmax % m->nrow;
1297    *jmax = vmax / m->nrow;
1298    return 0;
1299}
1300
1301#endif
1302
1303/**
1304 * \function igraph_matrix_isnull
1305 * Check for a null matrix.
1306 *
1307 * Checks whether all elements are zero.
1308 * \param m The input matrix.
1309 * \return Boolean, \c TRUE is \p m contains only zeros and \c FALSE
1310 *   otherwise.
1311 *
1312 * Time complexity: O(mn), the number of elements.
1313 */
1314
1315igraph_bool_t FUNCTION(igraph_matrix, isnull)(const TYPE(igraph_matrix) *m) {
1316    return FUNCTION(igraph_vector, isnull)(&m->data);
1317}
1318
1319/**
1320 * \function igraph_matrix_empty
1321 * Check for an empty matrix.
1322 *
1323 * It is possible to have a matrix with zero rows or zero columns, or
1324 * even both. This functions checks for these.
1325 * \param m The input matrix.
1326 * \return Boolean, \c TRUE if the matrix contains zero elements, and
1327 *    \c FALSE otherwise.
1328 *
1329 * Time complexity: O(1).
1330 */
1331
1332igraph_bool_t FUNCTION(igraph_matrix, empty)(const TYPE(igraph_matrix) *m) {
1333    return FUNCTION(igraph_vector, empty)(&m->data);
1334}
1335
1336/**
1337 * \function igraph_matrix_is_symmetric
1338 * Check for symmetric matrix.
1339 *
1340 * A non-square matrix is not symmetric by definition.
1341 * \param m The input matrix.
1342 * \return Boolean, \c TRUE if the matrix is square and symmetric, \c
1343 *    FALSE otherwise.
1344 *
1345 * Time complexity: O(mn), the number of elements. O(1) for non-square
1346 * matrices.
1347 */
1348
1349igraph_bool_t FUNCTION(igraph_matrix, is_symmetric)(const TYPE(igraph_matrix) *m) {
1350
1351    long int n = m->nrow;
1352    long int r, c;
1353    if (m->ncol != n) {
1354        return 0;
1355    }
1356    for (r = 1; r < n; r++) {
1357        for (c = 0; c < r; c++) {
1358            BASE a1 = MATRIX(*m, r, c);
1359            BASE a2 = MATRIX(*m, c, r);
1360#ifdef EQ
1361            if (!EQ(a1, a2)) {
1362                return 0;
1363            }
1364#else
1365            if (a1 != a2) {
1366                return 0;
1367            }
1368#endif
1369        }
1370    }
1371    return 1;
1372}
1373
1374/**
1375 * \function igraph_matrix_prod
1376 * Product of the elements.
1377 *
1378 * Note this function can result in overflow easily, even for not too
1379 * big matrices.
1380 * \param m The input matrix.
1381 * \return The product of the elements.
1382 *
1383 * Time complexity: O(mn), the number of elements.
1384 */
1385
1386BASE FUNCTION(igraph_matrix, prod)(const TYPE(igraph_matrix) *m) {
1387    return FUNCTION(igraph_vector, prod)(&m->data);
1388}
1389
1390/**
1391 * \function igraph_matrix_rowsum
1392 * Rowwise sum.
1393 *
1394 * Calculate the sum of the elements in each row.
1395 * \param m The input matrix.
1396 * \param res Pointer to an initialized vector; the result is stored
1397 *   here. It will be resized if necessary.
1398 * \return Error code.
1399 *
1400 * Time complexity: O(mn), the number of elements in the matrix.
1401 */
1402
1403int FUNCTION(igraph_matrix, rowsum)(const TYPE(igraph_matrix) *m,
1404                                    TYPE(igraph_vector) *res) {
1405    long int nrow = m->nrow, ncol = m->ncol;
1406    long int r, c;
1407    BASE sum;
1408    IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, nrow));
1409    for (r = 0; r < nrow; r++) {
1410        sum = ZERO;
1411        for (c = 0; c < ncol; c++) {
1412#ifdef SUM
1413            SUM(sum, sum, MATRIX(*m, r, c));
1414#else
1415            sum += MATRIX(*m, r, c);
1416#endif
1417        }
1418        VECTOR(*res)[r] = sum;
1419    }
1420    return 0;
1421}
1422
1423/**
1424 * \function igraph_matrix_colsum
1425 * Columnwise sum.
1426 *
1427 * Calculate the sum of the elements in each column.
1428 * \param m The input matrix.
1429 * \param res Pointer to an initialized vector; the result is stored
1430 *   here. It will be resized if necessary.
1431 * \return Error code.
1432 *
1433 * Time complexity: O(mn), the number of elements in the matrix.
1434 */
1435
1436int FUNCTION(igraph_matrix, colsum)(const TYPE(igraph_matrix) *m,
1437                                    TYPE(igraph_vector) *res) {
1438    long int nrow = m->nrow, ncol = m->ncol;
1439    long int r, c;
1440    BASE sum;
1441    IGRAPH_CHECK(FUNCTION(igraph_vector, resize)(res, ncol));
1442    for (c = 0; c < ncol; c++) {
1443        sum = ZERO;
1444        for (r = 0; r < nrow; r++) {
1445#ifdef SUM
1446            SUM(sum, sum, MATRIX(*m, r, c));
1447#else
1448            sum += MATRIX(*m, r, c);
1449#endif
1450        }
1451        VECTOR(*res)[c] = sum;
1452    }
1453    return 0;
1454}
1455
1456/**
1457 * \function igraph_matrix_contains
1458 * Search for an element.
1459 *
1460 * Search for the given element in the matrix.
1461 * \param m The input matrix.
1462 * \param e The element to search for.
1463 * \return Boolean, \c TRUE if the matrix contains \p e, \c FALSE
1464 * otherwise.
1465 *
1466 * Time complexity: O(mn), the number of elements.
1467 */
1468
1469igraph_bool_t FUNCTION(igraph_matrix, contains)(const TYPE(igraph_matrix) *m,
1470        BASE e) {
1471    return FUNCTION(igraph_vector, contains)(&m->data, e);
1472}
1473
1474/**
1475 * \function igraph_matrix_search
1476 * Search from a given position.
1477 *
1478 * Search for an element in a matrix and start the search from the
1479 * given position. The search is performed columnwise.
1480 * \param m The input matrix.
1481 * \param from The position to search from, the positions are
1482 *    enumerated columnwise.
1483 * \param what The element to search for.
1484 * \param pos Pointer to a <type>long int</type>. If the element is
1485 *    found, then this is set to the position of its first appearance.
1486 * \param row Pointer to a <type>long int</type>. If the element is
1487 *    found, then this is set to its row index.
1488 * \param col Pointer to a <type>long int</type>. If the element is
1489 *    found, then this is set to its column index.
1490 * \return Boolean, \c TRUE if the element is found, \c FALSE
1491 *    otherwise.
1492 *
1493 * Time complexity: O(mn), the number of elements.
1494 */
1495
1496igraph_bool_t FUNCTION(igraph_matrix, search)(const TYPE(igraph_matrix) *m,
1497        long int from, BASE what,
1498        long int *pos,
1499        long int *row, long int *col) {
1500    igraph_bool_t find = FUNCTION(igraph_vector, search)(&m->data, from, what, pos);
1501    if (find) {
1502        *row = *pos % m->nrow;
1503        *col = *pos / m->nrow;
1504    }
1505    return find;
1506}
1507
1508/**
1509 * \function igraph_matrix_remove_row
1510 * Remove a row.
1511 *
1512 * A row is removed from the matrix.
1513 * \param m The input matrix.
1514 * \param row The index of the row to remove.
1515 * \return Error code.
1516 *
1517 * Time complexity: O(mn), the number of elements in the matrix.
1518 */
1519
1520int FUNCTION(igraph_matrix, remove_row)(TYPE(igraph_matrix) *m, long int row) {
1521
1522    long int c, r, index = row + 1, leap = 1, n = m->nrow * m->ncol;
1523    if (row >= m->nrow) {
1524        IGRAPH_ERROR("Cannot remove row, index out of range", IGRAPH_EINVAL);
1525    }
1526
1527    for (c = 0; c < m->ncol; c++) {
1528        for (r = 0; r < m->nrow - 1 && index < n; r++) {
1529            VECTOR(m->data)[index - leap] = VECTOR(m->data)[index];
1530            index++;
1531        }
1532        leap++;
1533        index++;
1534    }
1535    m->nrow--;
1536    FUNCTION(igraph_vector, resize)(&m->data, m->nrow * m->ncol);
1537    return 0;
1538}
1539
1540/**
1541 * \function igraph_matrix_select_cols
1542 * \brief Select some columns of a matrix.
1543 *
1544 * This function selects some columns of a matrix and returns them in a
1545 * new matrix. The result matrix should be initialized before calling
1546 * the function.
1547 * \param m The input matrix.
1548 * \param res The result matrix. It should be initialized and will be
1549 *    resized as needed.
1550 * \param cols Vector; it contains the column indices (starting with
1551 *    zero) to extract. Note that no range checking is performed.
1552 * \return Error code.
1553 *
1554 * Time complexity: O(nm), n is the number of rows, m the number of
1555 * columns of the result matrix.
1556 */
1557
1558int FUNCTION(igraph_matrix, select_cols)(const TYPE(igraph_matrix) *m,
1559        TYPE(igraph_matrix) *res,
1560        const igraph_vector_t *cols) {
1561    long int ncols = igraph_vector_size(cols);
1562    long int nrows = m->nrow;
1563    long int i, j;
1564
1565    IGRAPH_CHECK(FUNCTION(igraph_matrix, resize)(res, nrows, ncols));
1566    for (i = 0; i < nrows; i++) {
1567        for (j = 0; j < ncols; j++) {
1568            MATRIX(*res, i, j) = MATRIX(*m, i, (long int)VECTOR(*cols)[j]);
1569        }
1570    }
1571    return 0;
1572}
1573
1574#ifdef OUT_FORMAT
1575
1576#ifndef USING_R
1577int FUNCTION(igraph_matrix, print)(const TYPE(igraph_matrix) *m) {
1578
1579    long int nr = FUNCTION(igraph_matrix, nrow)(m);
1580    long int nc = FUNCTION(igraph_matrix, ncol)(m);
1581    long int i, j;
1582    for (i = 0; i < nr; i++) {
1583        for (j = 0; j < nc; j++) {
1584            if (j != 0) {
1585                putchar(' ');
1586            }
1587            printf(OUT_FORMAT, MATRIX(*m, i, j));
1588        }
1589        printf("\n");
1590    }
1591
1592    return 0;
1593}
1594
1595int FUNCTION(igraph_matrix, printf)(const TYPE(igraph_matrix) *m,
1596                                    const char *format) {
1597    long int nr = FUNCTION(igraph_matrix, nrow)(m);
1598    long int nc = FUNCTION(igraph_matrix, ncol)(m);
1599    long int i, j;
1600    for (i = 0; i < nr; i++) {
1601        for (j = 0; j < nc; j++) {
1602            if (j != 0) {
1603                putchar(' ');
1604            }
1605            printf(format, MATRIX(*m, i, j));
1606        }
1607        printf("\n");
1608    }
1609
1610    return 0;
1611}
1612
1613#endif
1614
1615int FUNCTION(igraph_matrix, fprint)(const TYPE(igraph_matrix) *m,
1616                                    FILE *file) {
1617
1618    long int nr = FUNCTION(igraph_matrix, nrow)(m);
1619    long int nc = FUNCTION(igraph_matrix, ncol)(m);
1620    long int i, j;
1621    for (i = 0; i < nr; i++) {
1622        for (j = 0; j < nc; j++) {
1623            if (j != 0) {
1624                fputc(' ', file);
1625            }
1626            fprintf(file, OUT_FORMAT, MATRIX(*m, i, j));
1627        }
1628        fprintf(file, "\n");
1629    }
1630
1631    return 0;
1632}
1633
1634#endif
1635