def __init__(self, array, **kwargs):
    """
    Initializes a new matrix object in one of two ways. If array is a numpy
    ndarray, memory for a matrix with the same dimensions is allocated on
    the GPU. If the copy_to_device flag is set to True, the GPU matrix is
    initialized with the given ndarray. If array is not an ndarray, it must
    be a eigenmat structure (typically the user will never use this way of
    calling __init__).
    """

    if type(array) == np.ndarray:
      # Convert array to float32 in FORTRAN order
      array = reformat(array)

      # Initialize as a ndarray-tied matrix.
      self.mat = eigenmat()
      self.size = self.mat.size
      self.p_mat = ct.pointer(self.mat)
      self.numpy_array = array

      _eigenmat.init_from_array(self.p_mat, array.ctypes.data_as(ct.POINTER(ct.c_float)), ct.c_int(array.shape[0]), ct.c_int(array.shape[1]))
    else:
      # Initialize based on existing eigenmat structure.
      self.mat = array
      self.p_mat = ct.pointer(self.mat)
    self.T = TransposedEigenMatrix(self.mat)

    Initializes a new matrix object in one of two ways. If array is a numpy
    ndarray, memory for a matrix with the same dimensions is allocated on
    the GPU. If the copy_to_device flag is set to True, the GPU matrix is
    initialized with the given ndarray. If array is not an ndarray, it must
    be a eigenmat structure (typically the user will never use this way of
    calling __init__).
    
eigenmat/eigenmat.py