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