如何为 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 中的 tda
和 block
值。有谁知道这会不会有问题?
第二种方法很好用,但是在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 视图。
如果我有一个已分配内存的 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 中的 tda
和 block
值。有谁知道这会不会有问题?
第二种方法很好用,但是在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 视图。