如何为 GSL 矩阵重新分配内存(例如添加一行)?

How can you reallocate memory (e.g. add a row) to a GSL matrix?

如果我有一个已分配内存的 GSL 矩阵,是否有一种简单的方法可以重新分配该内存,例如,添加另一行?

我能想到的两种方法是:

size_t n = 2;
gsl_matrix invV = gsl_matrix_alloc(n, n);
// do something with matrix
...
// try and add another row (of length n) by reallocating data in the structure
invV->data = realloc(invV->data, sizeof(double)*(n*n + n));
invV->size1++;

或(使用矩阵视图):

size_t n = 2;
double *invV = malloc(sizeof(double)*n*n)
gsl_matrix_view invVview = gsl_matrix_view_array(invV, n, n);
// do something with &invVview.matrix
...
// try adding another row or length n
invV = realloc(invV, invV->data, sizeof(double)*(n*n + n));
invView = gsl_matrix_view_array(invV, n+1, n);

我不知道第一种方法是否存在问题,因为没有更改 gsl_matrix structure 中的 tdablock 值。有谁知道这会不会有问题?

第二种方法很好用,但是在double数组和矩阵视图之间来回切换很痛苦。

欢迎提出其他建议。

更新:

我有一个简单的测试代码,使用我的第一个选项的版本(例如,称为 testgsl.c):

#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_matrix.h>

gsl_matrix *matrix_add_row( gsl_matrix *m);

gsl_matrix *matrix_add_row( gsl_matrix *m ){
  if ( !m ){
    fprintf(stderr, "gsl_matrix must have already been initialised before adding new rows" );
    return NULL;
  }  

  size_t n = m->tda; /* current number of columns in matrix */

  /* reallocate the memory of the block */
  m->block->data = (double *)realloc(m->block->data, sizeof(double)*(m->block->size + n));
  if( !m->block->data ){
    fprintf(stderr, "Could not reallocate memory for gsl_matrix!");
    exit(1);
  }
  m->block->size += n;      /* update block size (number of elements) */
  m->size1++;               /* update number of rows */
  m->data = m->block->data; /* point data to block->data */
  return m;
}

int main( int argc, char **argv){
  size_t nrows = 4;
  size_t ncols = 1000;
  gsl_matrix *invV = gsl_matrix_alloc(nrows, ncols);

  //gsl_matrix *testmatrix = gsl_matrix_alloc(1000, 4000);

  /* set to zeros */
  gsl_matrix_set_zero( invV );

  /* try adding a row */
  invV = matrix_add_row( invV );

  fprintf(stderr, "nrows = %zu, ncols = %zu\n", invV->size1, invV->size2);

  /* set some values */
  gsl_matrix_set_zero( invV );
  gsl_matrix_set( invV, 4, 0, 2.3 );
  gsl_matrix_set( invV, 4, 1, 1.2 );

  gsl_matrix_free( invV );
  //gsl_matrix_free( testmatrix );

  return 0;
}

这似乎工作正常(尽管我认为可能会出现一些潜在的内存分配问题)。

Brian Gough, one of the authors of the gsl_matrix code, seems to suggest 我的第二个选择 - 重新分配数组并在必要时仅使用 vector/matrix 视图。