10.1 Dense Matrices

As can be seen from the header file cvxopt.h, a matrix is essentially a structure with four fields. The fields nrows and ncols are two integers that specify the dimensions. The id field controls the type of the matrix and can have values DOUBLE, INT and COMPLEX. The buffer field is an array that contains the matrix elements stored contiguously in column-major order.

The following C functions can be used to create matrices.

matrix* Matrix_New(int nrows, int ncols, int id)
Returns a matrix object of type id with nrows rows and ncols columns. The elements of the matrix are uninitialized.

matrix* Matrix_NewFromMatrix(matrix *src, int id)
Returns a copy of the matrix src converted to type id. The following type conversions are allowed: 'i' to 'd', 'i' to 'z' and 'd' to 'z'.

matrix* Matrix_NewFromSequence(PyListObject *x, int id)
Creates a matrix of type id from the Python sequence type x. The returned matrix has size (len(x),1). The size can be changed by modifying the nrows and ncols fields of the returned matrix.

To illustrate the creation and manipulation of dense matrices (as well as the Python C API), we show the code for the uniform() function from cvxopt.random described in section 2.7.

PyObject * uniform(PyObject *self, PyObject *args, PyObject *kwrds) 
{
  matrix *obj;
  int i, nrows, ncols = 1;
  double a = 0, b = 1;
  char *kwlist[] = {"nrows", "ncols", "a", "b", NULL};

  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "i|idd", kwlist, 
          &nrows, &ncols, &a, &b)) return NULL;
  
  if ((nrows<0) || (ncols<0)) {
    PyErr_SetString(PyExc_TypeError, "dimensions must be non-negative");
    return NULL;
  }
  
  if (!(obj = Matrix_New(nrows, ncols, DOUBLE)))
    return PyErr_NoMemory();
  
  for (i = 0; i < nrows*ncols; i++)
    MAT_BUFD(obj)[i] = Uniform(a,b);
  
  return (PyObject *)obj;
}