psF64 p_psImageGetElementF64(psImage* image,
			     int col,
			     int row)
{
    if (image == NULL) {
        return NAN;
    }
    if (col < 0 || col >= image->numCols) {
        return NAN;
    }
    if (row < 0 || row >= image->numRows) {
        return NAN;
    }

    switch (image->type.type) {
    case PS_TYPE_U8:
        return image->data.U8[row][col];
        break;
    case PS_TYPE_U16:
        return image->data.U16[row][col];
        break;
    case PS_TYPE_U32:
        return image->data.U32[row][col];
        break;
    case PS_TYPE_U64:
        return image->data.U64[row][col];
        break;
    case PS_TYPE_S8:
        return image->data.S8[row][col];
        break;
    case PS_TYPE_S16:
        return image->data.S16[row][col];
        break;
    case PS_TYPE_S32:
        return image->data.S32[row][col];
        break;
    case PS_TYPE_S64:
        return image->data.S64[row][col];
        break;
    case PS_TYPE_F32:
        return image->data.F32[row][col];
        break;
    case PS_TYPE_F64:
        return image->data.F64[row][col];
    default:
        return NAN;
    }
}

bool p_psImagePrint (FILE *f, psImage *a, char *name) {
  
  fprintf (f, "matrix: %s\n", name);

  for (int j = 0; j < a[0].numRows; j++) {
    for (int i = 0; i < a[0].numCols; i++) {
      fprintf (f, "%f  ", p_psImageGetElementF64(a, i, j));
    }
    fprintf (f, "\n");
  }
  fprintf (f, "\n");
  return (true);
}

bool p_psVectorPrint (FILE *f, psVector *a, char *name) {
  
  fprintf (f, "vector: %s\n", name);

  for (int i = 0; i < a[0].n; i++) {
    fprintf (f, "%f\n", p_psVectorGetElementF64(a, i));
  }
  fprintf (f, "\n");
  return (true);
}
