2

So, I have to use this function from GSL. This one:

gsl_matrix_view_array (double * base, size_t n1, size_t n2)

The first argument (double * base) is the matrix I need to pass to it, which is read as input from the user.

I'm dynamically allocating it this way:

double **base;
base = malloc(size*sizeof(double*));

for(i=0;i<size;i++)
base[i] = malloc(size*sizeof(double));

Where size is given by the user. But then, when the code runs, it warns this :

  "passing arg 1 of gsl_matrix_view_array from incompatible pointer type".

What is happening?

Sunny
  • 3,185
  • 8
  • 34
  • 66
Marconato
  • 49
  • 4
  • Don't cast the result of malloc in C: http://stackoverflow.com/q/605845/1025391 – moooeeeep May 30 '14 at 11:21
  • 3
    Perhaps show the actual line of code *that is flagging the error* ? And I'm assuming your fundamental problem is you should be allocating a `double[]` that is magnitude `n1*n2`, your matrix in row-major storage order. I've never used the API, but the parameter list certainly suggests that is the case. The [documentation](http://www.gnu.org/software/gsl/manual/html_node/Matrix-views.html) for the function notes even shows it as row-major stored : `m'(i,j) = base[i*n2 + j]` – WhozCraig May 30 '14 at 11:25

2 Answers2

2

The function expects a flat array, e.g., double arr[size*size];.

Here's an example from the documentation that I have slightly modified to use a matrix view:

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

int main(void) {
  int i, j; 

  double *arr = malloc(10 * 3 * sizeof*arr);
  gsl_matrix_view mv = gsl_matrix_view_array(arr, 10, 3);
  gsl_matrix * m = &(mv.matrix);

  for (i=0; i<10; i++)
    for (j=0; j<3; j++)
      gsl_matrix_set(m, i, j, 0.23 + 100*i + j);

  for (i=0; i<10; i++)
    for (j=0; j<3; j++)
      printf("m(%d,%d) = %g\n", i, j, gsl_matrix_get(m, i, j));

  free(arr);

  return 0;
}

Note that you can also directly allocate memory for the matrix using the provided API.

Here's the original example:

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

int main(void)
{
  int i, j; 

  gsl_matrix * m = gsl_matrix_alloc(10, 3);

  for (i=0; i<10; i++)
    for (j=0; j<3; j++)
      gsl_matrix_set(m, i, j, 0.23 + 100*i + j);

  for (i=0; i<10; i++)
    for (j=0; j<3; j++)
      printf("m(%d,%d) = %g\n", i, j, gsl_matrix_get(m, i, j));

  gsl_matrix_free(m);

  return 0;
}

For reference:

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
1

gsl_matrix_view_array expects your matrix as a contiguous single allocation in row-major order. You should be allocating your array like this:

double (*ar)[size] = malloc(sizeof(ar[size]) * size);

Then (after populating it)

gsl_matrix_view_array(ar[0], size, size);

Finally, free your allocation when done with a single call:

free(ar);

Note: Don't try this with C++, as VLA's aren't standard-supported for that language.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • shouldn't it be just `double * ar = malloc(sizeof(double) * size * size);` ? – moooeeeep May 30 '14 at 11:55
  • @moooeeeep if you want to do the math yourself for row/column indexing, you certainly can. (as their documentation shows). either work, this just adds the ability to use `ar[i][j]` addressing, but certainly you can just use a `double*` and address with `ar[i*size+j]` instead (and in fact it would be portable across C and C++). – WhozCraig May 30 '14 at 12:05
  • Apparantly it is intended to use the GSL functions for element access `gsl_matrix_set()`, `gsl_matrix_get()` etc. on the matrix view: http://www.gnu.org/software/gsl/manual/gsl-ref_8.html#SEC186 – moooeeeep May 30 '14 at 12:14
  • 1
    @moooeeeep for a `gsl_matrix` that would certainly make sense. I would hope they implemented that as a macro or inlined, or the performance would be hideous. For a double base array the linear backdrop presented form of the allocation in this answer, or a raw `double*`, will be the same, and is standard-compliant. Think they have enough ways in that lib to make/access a matrix? =P. +1 on your answer btw, GJ seeing the question that wasn't asked, but should have been! – WhozCraig May 30 '14 at 16:30