The structures and functions related to vectors are declared in pnl/pnl_vector.h.
Vectors are declared for several basic types : double, int, and dcomplex. In the following declarations, BASE must be replaced by one the previous types and the corresponding vector structures are respectively named PnlVect, PnlVectInt, PnlVectComplex
typedef struct _PnlVect { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlVect pointer to be cast to a PnlObject */ PnlObject object; int size; /*!< size of the vector */ int mem_size; /*!< size of the memory block allocated for array */ double *array; /*!< pointer to store the data */ int owner; /*!< 1 if the object owns its array member, 0 otherwise */ } PnlVect; typedef struct _PnlVectInt { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlVectInt pointer to be cast to a PnlObject */ PnlObject object; int size; /*!< size of the vector */ int mem_size; /*!< size of the memory block allocated for array */ int *array; /*!< pointer to store the data */ int owner; /*!< 1 if the object owns its array member, 0 otherwise */ } PnlVectInt; typedef struct _PnlVectComplex { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlVectComplex pointer to be cast * to a PnlObject */ PnlObject object; int size; /*!< size of the vector */ int mem_size; /*!< size of the memory block allocated for array */ dcomplex *array; /*!< pointer to store the data */ int owner; /*!< 1 if the object owns its array member, 0 otherwise */ } PnlVectComplex;
size is the size of the vector, array is a pointer containing the data and owner is an integer to know if the vector owns its array pointer (owner=1) or shares it with another structure (owner=0). mem_size is the number of elements the vector can hold at most.
General functions These functions exist for all types of vector no matter what the basic type is. The following conventions are used to name functions operating on vectors. Here is the table of prefixes used for the different basic types.
| type | prefix | BASE | 
| double | pnl_vect | double | 
| int | pnl_vect_int | int | 
| dcomplex | pnl_vect_complex | dcomplex | 
In this paragraph, we present the functions operating on PnlVect which exist for all types. To deduce the prototypes of these functions for other basic types, one must replace pnl_vect and double according the above table.
Constructors and destructors There are no special functions to access the size of a vector, instead the field size should be accessed directly.
 PnlVect * pnl_vect_new ()
   Description Create a new PnlVect of size 0.
     
 PnlVect * pnl_vect_create (int size)
   Description Create a new PnlVect pointer.
     
 PnlVect * pnl_vect_create_from_zero (int size)
   Description Create a new PnlVect pointer and sets it to zero.
     
 PnlVect * pnl_vect_create_from_scalar (int size, double x)
   Description Create a new PnlVect pointer and sets all elements t x.
     
 PnlVect * pnl_vect_create_from_ptr (int size, const double *x)
   Description Create a new PnlVect pointer and copies x to array.
     
 PnlVect * pnl_vect_create_from_mat ( const PnlMat *M)
   Description Create a new PnlVect pointer of size M->mn and copy the content of M
     row wise.
                                                                                    
                                                                                    
     
 PnlVect * pnl_vect_create_from_list (int size, ...)
   Description Create  a  new  PnlVect  pointer  of  length  size  filled  with  the  extra
     arguments  passed  to  the  function.  The  number  of  extra  arguments  passed  must
     be  equal  to  size  and  they  must  be  of  the  type  BASE.  Example:  To  create  a
     vector  {1.,  2.},  you  should  enter  pnl_vect_create_from_list(2,  1.0,  2.0)  and  NOT
     pnl_vect_create_from_list(2,  1.0,  2)  or  pnl_vect_create_from_list(2,  1,  2.0).  Be
     aware that this cannot be checked inside the function.
     
 PnlVect * pnl_vect_create_from_file (const char *file)
   Description Read a vector from a file and creates the corresponding PnlVect . The
     data might be stored as a row or column vector. Entries can be separated by spaces,
     tabs, commas or semicolons. Anything after a # or % is ignored up to the end of the
     line.
     
 PnlVect * pnl_vect_copy (const PnlVect *v)
   Description This is a copying constructor. It creates a copy of a PnlVect .
     
 void pnl_vect_clone (PnlVect *clone, const PnlVect *v)
   Description Clone a PnlVect . clone must be an already existing PnlVect . It is resized
     to match the size of v and the data are copied. Future modifications to v will not affect
     clone.
     
   PnlVect   * pnl_vect_create_subvect_with_ind (const   PnlVect   *V,   const
     PnlVectInt *ind)
   Description Create a new vector containing V(ind(:)).
     
  void pnl_vect_extract_subvect_with_ind (PnlVect  *V_sub,  const  PnlVect
     *V, const PnlVectInt *ind)
   Description On exit, V_sub = V(ind(:)).
     
 PnlVect * pnl_vect_create_subvect (const PnlVect *V, int i, int len)
   Description Create a new vector containing V(i:i+len-1). The elements are copied.
                                                                                    
                                                                                    
     
 void pnl_vect_extract_subvect (PnlVect *V_sub, const PnlVect *V, int i, int
     len)
   Description On exit, V_sub = V(i:i+len-1). The elements are copied.
     
 void pnl_vect_set_subblock (PnlVect *dest, const PnlVect *src, int i)
   Description Set dest[i:] = src.
     
 void pnl_vect_free (PnlVect **v)
   Description Free a PnlVect pointer and set the data pointer to NULL
     
 PnlVect  pnl_vect_wrap_array (const double *x, int size)
   Description Create a PnlVect containing the data x. No copy is made. It is just a
     container.
     
 PnlVect  pnl_vect_wrap_subvect (const PnlVect *x, int i, int s)
   Description Create a PnlVect containing x(i:i+s-1). No copy is made. It is just a
     container. The returned PnlVect has size=s and owner=0.
     
 PnlVect  pnl_vect_wrap_subvect_with_last (const PnlVect *x, int i, int j)
   Description Create a PnlVect containing x(i:j). No copy is made. It is just a container.
     
 PnlVect  pnl_vect_wrap_mat (const PnlMat *M)
   Description Return a PnlVect (not a pointer) whose array is the row wise array of M.
     The new vector shares its data with the matrix M, which means that any modification
     to one of them will affect the other.
 int pnl_vect_resize (PnlVect *v, int size)
   Description Resize a PnlVect . It copies as much of the old data to fit in the resized
     object.
     
 int pnl_vect_resize_from_scalar (PnlVect *v, int size, double x)
   Description Resize a PnlVect . Copy as much of the old data as possible and fill the
     new cells with x.
     
 int pnl_vect_resize_from_ptr (PnlVect *v, int size, double *t)
   Description Resize a PnlVect and uses t to fill the vector. t must be of size size.
Accessing elements If it is supported by the compiler, the following functions are declared inline. To speed up these functions, you can define the macro PNL_RANGE_CHECK_OFF, see Section 1.3.2 for an explanation.
Accessing elements of a vector is faster using the following macros
  GET (PnlVect *v, int i)
   Description Return v[i] for reading, eg. x=GET(v,i)
     
  GET_INT (PnlVectInt *v, int i)
   Description Same as GET but for an integer vector.
     
  GET_COMPLEX (PnlVectComplex *v, int i)
   Description Same as GET but for a complex vector.
     
  LET (PnlVect *v, int i)
   Description Return v[i] as a lvalue for writing, eg. LET(v,i)=x
     
  LET_INT (PnlVectInt *v, int i)
   Description Same as LET but for an integer vector.
                                                                                    
                                                                                    
     
  LET_COMPLEX (PnlVectComplex *v, int i)
   Description Same as LET but for a complex vector.
 void pnl_vect_set (PnlVect *v, int i, double x)
   Description Set v[i]=x.
     
 double pnl_vect_get (const PnlVect *v, int i)
   Description Return the value of v[i].
     
 void pnl_vect_lget (PnlVect *v, int i)
   Description Return the address of v[i].
     
 void pnl_vect_set_all (PnlVect *v, double x)
   Description Set all elements to x.
     
 void pnl_vect_set_zero (PnlVect *v)
   Description Set all elements to zero.
 void pnl_vect_print (const PnlVect *V)
   Description Print a PnlVect as a column vector
     
 void pnl_vect_fprint (FILE *fic, const PnlVect *V)
   Description Print a PnlVect in file fic as a column vector. The file can be read by
     pnl_vect_create_from_file.
                                                                                    
                                                                                    
     
 void pnl_vect_print_asrow (const PnlVect *V)
   Description Print a PnlVect as a row vector
     
 void pnl_vect_fprint_asrow (FILE *fic, const PnlVect *V)
   Description Print  a  PnlVect  in  file  fic  as  a  row  vector.  The  file  can  be  read  by
     pnl_vect_create_from_file.
     
 void pnl_vect_print_nsp (const PnlVect *V)
   Description Print a vector to the standard output in a format compatible with Nsp.
     
 void pnl_vect_fprint_nsp (FILE *fic, const PnlVect *V)
   Description Print a vector to a file in a format compatible with Nsp.
Applying external operation to vectors
 void pnl_vect_minus (PnlVect *lhs)
   Description In-place unary minus
     
 void pnl_vect_plus_scalar (PnlVect *lhs, double x)
   Description In-place vector scalar addition
     
 void pnl_vect_minus_scalar (PnlVect *lhs, double x)
   Description In-place vector scalar substraction
     
 void pnl_vect_mult_scalar (PnlVect *lhs, double x)
   Description In-place vector scalar multiplication
                                                                                    
                                                                                    
     
 void pnl_vect_div_scalar (PnlVect *lhs, double x)
   Description In-place vector scalar division
 void pnl_vect_plus_vect (PnlVect *lhs, const PnlVect *rhs)
   Description In-place vector vector addition
     
 void pnl_vect_minus_vect (PnlVect *lhs, const PnlVect *rhs)
   Description In-place vector vector substraction
     
 void pnl_vect_inv_term (PnlVect *lhs)
   Description In-place term by term vector inversion
     
 void pnl_vect_div_vect_term (PnlVect *lhs, const PnlVect *rhs)
   Description In-place term by term vector division
     
 void pnl_vect_mult_vect_term (PnlVect *lhs, const PnlVect *rhs)
   Description In-place vector vector term by term multiplication
     
 void pnl_vect_map (PnlVect *lhs, const PnlVect *rhs, double(*f)(double))
   Description lhs = f(rhs)
     
 void pnl_vect_map_inplace (PnlVect *lhs, double(*f)(double))
   Description lhs = f(lhs)
                                                                                    
                                                                                    
     
 void pnl_vect_map_vect (PnlVect *lhs, const PnlVect *rhs1, const PnlVect *rhs2,
     double(*f)(double, double))
   Description lhs = f(rhs1, rhs2)
     
       void pnl_vect_map_vect_inplace (PnlVect       *lhs,       PnlVect       *rhs,
     double(*f)(double,double))
   Description lhs = f(lhs,rhs)
     
 void pnl_vect_axpby (double a, const PnlVect *x, double b, PnlVect *y)
   Description Compute y : = a x + b y. When b==0, the content of y is not used on
     input and instead y is resized to match x.
     
 double pnl_vect_sum (const PnlVect *lhs)
   Description Return the sum of all the elements of a vector
     
 void pnl_vect_cumsum (PnlVect *lhs)
   Description Compute the cumulative sum of all the elements of a vector. The original
     vector is modified
     
 double pnl_vect_prod (const PnlVect *V)
   Description Return the product of all the elements of a vector
     
 void pnl_vect_cumprod (PnlVect *lhs)
   Description Compute the cumulative product of all the elements of a vector. The
     original vector is modified
 double pnl_vect_norm_two (const PnlVect *V)
   Description Return the two norm of a vector
                                                                                    
                                                                                    
     
 double pnl_vect_norm_one (const PnlVect *V)
   Description Return the one norm of a vector
     
 double pnl_vect_norm_infty (const PnlVect *V)
   Description Return the infinity norm of a vector
     
 double pnl_vect_scalar_prod (const PnlVect *rhs1, const PnlVect *rhs2)
   Description Compute the scalar product between 2 vectors
     
 int pnl_vect_cross (PnlVect *lhs, const PnlVect *x, const PnlVect *y)
   Description Compute the cross product of x and y and store the result in lhs. The
     vectors x and y must be of size 3 and FAIL is returned otherwise.
     
 double pnl_vect_dist (const PnlVect *x, const PnlVect *y)
   Description Compute the distance between x and y, ie  .
.
 int pnl_vect_isequal (const PnlVect *V1, const PnlVect *V2, double err)
   Description Test if two vectors are equal up to err component–wise. The error err
     is either relative or absolute depending on the magnitude of the components. Return
     TRUE or FALSE.
     
 int pnl_vect_isequal_abs (const PnlVect *V1, const PnlVect *V2, double abserr)
   Description Test   if   two   vectors   are   equal   up   to   an   absolute   error   abserr
     component–wise. Return TRUE or FALSE.
                                                                                    
                                                                                    
     
 int pnl_vect_isequal_rel (const PnlVect *V1, const PnlVect *V2, double relerr)
   Description Test if two vectors are equal up to a relative error relerr component–wise.
     Return TRUE or FALSE.
     
 int pnl_vect_eq_all (const PnlVect *v, double x)
   Description Test if all the components of v are equal to x. Return TRUE or FALSE.
Ordering functions The following functions are not defined for PnlVectComplex because there is no total ordering on Complex numbers
 double pnl_vect_max (const PnlVect *V)
   Description Return the maximum of a a vector
     
 double pnl_vect_min (const PnlVect *V)
   Description Return the minimum of a vector
     
 void pnl_vect_minmax (double *m, double *M, const PnlVect *)
   Description Compute the minimum and maximum of a vector which are returned in
     m and M respectively.
     
 void pnl_vect_min_index (double *m, int *im, const PnlVect *)
   Description Compute the minimum of a vector and its index stored in sets m and im
     respectively.
     
 void pnl_vect_max_index (double *M, int *iM, const PnlVect *)
   Description Compute the maximum of a vector and its index stored in sets m and
     im respectively.
                                                                                    
                                                                                    
     
 void pnl_vect_minmax_index (double *m, double *M, int *im, int *iM, const
     PnlVect *)
   Description Compute the minimum and maximum of a vector and the corresponding
     indices stored respectively in m, M, im and iM.
     
 void pnl_vect_qsort (PnlVect *, char order)
   Description Sort a vector using a quick sort algorithm according to order (’i’ for
     increasing or ’d’ for decreasing).
     
 void pnl_vect_qsort_index (PnlVect *, PnlVectInt *index, char order)
   Description Sort a vector using a quick sort algorithm according to order (’i’ for
     increasing or ’d’ for decreasing ). On output, index contains the permutation used to
     sort the vector.
     
 int pnl_vect_find (PnlVectInt *ind, char *type, int(*f)(double *t), …)
   Description f is a function taking a C array as argument and returning an integer. type is a
     string composed by the letters ’r’ and ’v’ and is used to describe the types of the arguments
     appearing after f. This function aims at simulating Scilab’s find function. Here are a
     few examples (capital letters are used for vectors and small letters for real values)
     
ind = find ( a < X )
int isless ( double *t ) { return t[0] < t[1]; } pnl_vect_find ( ind, "rv", isless, a, X );
ind = find (X <= Y)
int isless ( double *t ) { return t[0] <= t[1]; } pnl_vect_find ( ind, "vv", isless, X, Y );
ind = find ((a < X) && (X <= Y))
int cmp ( double *t ) { return (t[0] <= t[1]) && (t[1] <= t[2]); } pnl_vect_find ( ind, "rvv", cmp, a, X, Y );
ind contains on exit the indices i for which the function f returned 1. This function returns OK or FAIL when something went wrong (size mismatch between matrices, invalid string type).
 void pnl_vect_swap_elements (PnlVect *v, int i, int j)
   Description Exchange v[i] and v[j].
     
 void pnl_vect_reverse (PnlVect *v)
   Description Perform a mirror operation on v. On output v[i] = v[n-1-i] for i=0,…,n-1
     where n is the length of the vector.
 void pnl_vect_complex_mult_double (PnlVectComplex *lhs, double x)
   Description In-place multiplication by a double.
     
   PnlVectComplex* pnl_vect_complex_create_from_array (int   size,   const
     double *re, const double *im)
   Description Create  a  PnlVectComplex  given  the  arrays  of  the  real  parts  re  and
     imaginary parts im.
     
 void pnl_vect_complex_split_in_array (const PnlVectComplex *v, double *re,
     double *im)
   Description Split a complex vector into two C arrays : the real parts of the elements
     of v are stored into re and the imaginary parts into im.
                                                                                    
                                                                                    
     
 void pnl_vect_complex_split_in_vect (const PnlVectComplex *v, PnlVect *re,
     PnlVect *im)
   Description Split a complex vector into two PnlVect ’s : the real parts of the elements
     of v are stored into re and the imaginary parts into im.
There exist functions to directly access the real or imaginary parts of an element of a complex vector. These functions also have inlined versions that are used if the variable HAVE_INLINE was declared at compilation time.
 double pnl_vect_complex_get_real (const PnlVectComplex *v, int i)
   Description Return the real part of v[i].
     
 double pnl_vect_complex_get_imag (const PnlVectComplex *v, int i)
   Description Return the imaginary part of v[i].
     
 double* pnl_vect_complex_lget_real (const PnlVectComplex *v, int i)
   Description Return the real part of v[i] as a lvalue.
     
 double* pnl_vect_complex_lget_imag (const PnlVectComplex *v, int i)
   Description Return the imaginary part of v[i] as a lvalue.
     
 void pnl_vect_complex_set_real (const PnlVectComplex *v, int i, double re)
   Description Set the real part of v[i] to re.
     
 void pnl_vect_complex_set_imag (const PnlVectComplex *v, int i, double im)
   Description Set the imaginary part of v[i] to im.
Equivalently to these functions, there exist macros. When the compiler is able to handle inline code, there is no gain in using macros instead of inlined functions at least in principle.
  GET_IMAG (v, i)
   Description Return the imaginary part of v[i].
     
  LET_REAL (v, i)
   Description Return the real part of v[i] as a lvalue.
     
  LET_IMAG (v, i)
   Description Return the imaginary part of v[i] as a lvalue.
typedef struct PnlVectCompact { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlVectCompact pointer to be cast to a PnlObject */ PnlObject object; int size; /* size of the vector */ double val; /* single value */ double *array; /* Pointer to double values */ char convert; /* ’a’, ’d’ : array, double */ } PnlVectCompact;
 PnlVectCompact * pnl_vect_compact_new ()
   Description Create a PnlVectCompact of size 0.
                                                                                    
                                                                                    
     
 PnlVectCompact * pnl_vect_compact_create (int n, double x)
   Description Create a PnlVectCompact filled in with x
     
 PnlVectCompact * pnl_vect_compact_create_from_ptr (int n, double *x)
   Description Create a PnlVectCompact filled in with the content of x. Note that x
     must have at least n elements.
     
 int pnl_vect_compact_resize (PnlVectCompact *v, int size, double x)
   Description Resize a PnlVectCompact .
     
 PnlVectCompact * pnl_vect_compact_copy (const PnlVectCompact *v)
   Description Copy a PnlVectCompact
     
 void pnl_vect_compact_free (PnlVectCompact **v)
   Description Free a PnlVectCompact
     
 PnlVect * pnl_vect_compact_to_pnl_vect (const PnlVectCompact *C)
   Description Convert a PnlVectCompact pointer to a PnlVect pointer.
     
 double pnl_vect_compact_get (const PnlVectCompact *C, int i)
   Description Access function
     
 void pnl_vect_compact_set_all (PnlVectCompact *C, double x)
   Description Set all elements of C to x. C is converted to a compact storage.
     
 void pnl_vect_compact_set_ptr (PnlVectCompact *C, double *ptr)
   Description Copy the array ptr into C. We assume that the sizes match. C is converted
     to a non compact storage.
The structures and functions related to matrices are declared in pnl/pnl_matrix.h.
typedef struct _PnlMat{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlMat pointer to be cast to a PnlObject */ PnlObject object; int m; /*!< nb rows */ int n; /*!< nb columns */ int mn; /*!< product m*n */ int mem_size; /*!< size of the memory block allocated for array */ double *array; /*!< pointer to store the data row-wise */ int owner; /*!< 1 if the object owns its array member, 0 otherwise */ } PnlMat; typedef struct _PnlMatInt{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlMatInt pointer to be cast to a PnlObject */ PnlObject object; int m; /*!< nb rows */ int n; /*!< nb columns */ int mn; /*!< product m*n */ int mem_size; /*!< size of the memory block allocated for array */ int *array; /*!< pointer to store the data row-wise */ int owner; /*!< 1 if the object owns its array member, 0 otherwise */ } PnlMatInt; typedef struct _PnlMatComplex{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlMatComplex pointer to be cast * to a PnlObject */ PnlObject object; int m; /*!< nb rows */ int n; /*!< nb columns */ int mn; /*!< product m*n */ int mem_size; /*!< size of the memory block allocated for array */ dcomplex *array; /*!< pointer to store the data row-wise */ int owner; /*!< 1 if the object owns its array member, 0 otherwise */ } PnlMatComplex;
m is the number of rows, n is the number of columns. array is a pointer containing the data of the matrix stored line wise, The element (i, j) of the matrix is array[i*m+j]. owner is an integer to know if the matrix owns its array pointer (owner=1) or shares it with another structure (owner=0). mem_size is the number of elements the matrix can hold at most.
The following operations are implemented on matrices and vectors. alpha and beta are numbers, A and B are matrices and x and y are vectors.
| pnl_mat_axpy | B := alpha * A + B | 
| pnl_mat_scalar_prod | x’ A y | 
| pnl_mat_dgemm | C := alpha * op (A) * op (B) + beta * C | 
| pnl_mat_mult_vect_transpose_inplace | y = A’ * x | 
| pnl_mat_mult_vect_inplace | y = A * x | 
| pnl_mat_lAxpby | y := lambda * A * x + beta * y | 
| pnl_mat_dgemv | y := alpha * op (A) * x + beta * y | 
| pnl_mat_dger | A := alpha x * y’ + A | 
These functions exist for all types of matrices no matter what the basic type is. The following conventions are used to name functions operating on matrices. Here is the table of prefixes used for the different basic types.
| type | prefix | BASE | 
| double | pnl_mat | double | 
| int | pnl_mat_int | int | 
| dcomplex | pnl_mat_complex | dcomplex | 
In this paragraph we present the functions operating on PnlMat which exist for all types. To deduce the prototypes of these functions for other basic types, one must replace pnl_mat and double according the above table.
Constructors and destructors There are no special functions to access the sizes of a matrix, instead the fields m, n and mn give direct access to the number of rows, columns and the size of the matrix.
 PnlMat * pnl_mat_new ()
   Description Create a PnlMat of size 0
     
 PnlMat * pnl_mat_create (int m, int n)
   Description Create a PnlMat with m rows and n columns.
     
 PnlMat * pnl_mat_create_from_scalar (int m, int n, double x)
   Description Create a PnlMat with m rows and n columns and sets all the elements
     to x.
     
 PnlMat * pnl_mat_create_from_zero (int m, int n)
   Description Create a PnlMat with m rows and n columns and sets all elements to 0.
     
 PnlMat * pnl_mat_create_from_ptr (int m, int n, const double *x)
   Description Create a PnlMat with m rows and n columns and copies the array x to
     the new vector. Be sure that x is long enough to fill all the vector because it cannot be
     checked inside the function.
     
 PnlMat * pnl_mat_create_from_list (int m, int n, ...)
   Description Create a new PnlMat pointer of size m x n filled with the extra arguments
     passed to the function. The number of extra arguments passed must be equal to m x n,
     be aware that this cannot be checked inside the function.
                                                                                    
                                                                                    
     
 PnlMat * pnl_mat_copy (const PnlMat *M)
   Description Create a new PnlMat which is a copy of M.
     
 PnlMat * pnl_mat_create_diag_from_ptr (const double *x, int d)
   Description Create a new squared PnlMat by specifying its size and diagonal terms
     as an array.
     
 PnlMat * pnl_mat_create_diag (const PnlVect *V)
   Description Create  a  new  squared  PnlMat  by  specifying  its  diagonal  terms  in  a
     PnlVect .
     
 PnlMat * pnl_mat_create_from_file (const char *file)
   Description Read a matrix from a file and creates the corresponding PnlMat . One
     row of the matrix corresponds to one line of the file and the elements of a row can be
     separated by spaces, tabs, commas or semicolons. Anything after a # or % is ignored up
     to the end of the line.
     
 void pnl_mat_free (PnlMat **M)
   Description Free a PnlMat and sets *M to NULL
     
 PnlMat  pnl_mat_wrap_array (const double *x, int m, int n)
   Description Create a PnlMat of size m x n which contains x. No copy is made. It is
     just a container.
     
 PnlMat  pnl_mat_wrap_vect (const PnlVect *V)
   Description Return a PnlMat (not a pointer) whose array is the array of V. The new
     matrix shares its data with the vector V, which means that any modification to one of
     them will affect the other.
     
 void pnl_mat_clone (PnlMat *clone, const PnlMat *M)
   Description Clone M into clone. No no new PnlMat is created.
                                                                                    
                                                                                    
     
 int pnl_mat_resize (PnlMat *M, int m, int n)
   Description Resize a PnlMat . The new matrix is of size m x n. The old data are lost.
     
 PnlVect * pnl_vect_create_submat (const PnlMat *M, const PnlVectInt *indi,
     const PnlVectInt *indj)
   Description Create a new vector containing the values M(indi(:), indj(:)). indi and
     indj must be of the same size.
     
  void pnl_vect_extract_submat (PnlVect  *V_sub,  const  PnlMat  *M,  const
     PnlVectInt *indi, const PnlVectInt *indj)
   Description On exit, V_sub = M(indi(:), indj(:)). indi and indj must be of the same
     size.
     
 void pnl_mat_extract_subblock (PnlMat *M_sub, const PnlMat *M, int i, int
     len_i, int j, int len_j)
   Description M_sub = M(i:i+len_i-1, j:j+len_j-1). len_i (resp. len_j) is the number
     of rows (resp. columns) to be extracted.
     
 void pnl_mat_set_subblock (PnlMat *M, const PnlMat *block, int i, int j)
   Description If block is a matrix of size m_block x n_block, the dimensions of M
     must satisfy that M->m >= i + m_block and M->n >= j + n_block. On output
     M(i:i+m_block-1, j:j+n_block-1) = block.
Accessing elements. If it is supported by the compiler, the following functions are declared inline. To speed up these functions, you can define the macro PNL_RANGE_CHECK_OFF, see Section 1.3.2 for an explanation.
Accessing elements of a matrix is faster using the following macros
  MGET (PnlMat *M, int i, int j)
   Description Return M[i,j] for reading, eg. x=MGET(M,i,j)
                                                                                    
                                                                                    
     
  MGET_INT (PnlMatInt *M, int i, int j)
   Description Same as MGET but for an integer matrix.
     
  MGET_COMPLEX (PnlMatComplex *M, int i, int j)
   Description Same as MGET but for a complex matrix.
     
  MLET (PnlMat *M, int i, int j)
   Description Return M[i,j] as a lvalue for writing, eg. MLET(M,i,j)=x
     
  MLET_INT (PnlMatInt *M, int i, int j)
   Description Same as MLET but for an integer matrix.
     
  MLET_COMPLEX (PnlMatComplex *M, int i, int j)
   Description Same as MLET but for a complex matrix.
 void pnl_mat_set (PnlMat *M, int i, int j, double x)
   Description Set the value of M[i, j]=x
     
 double pnl_mat_get (const PnlMat *M, int i, int j)
   Description Get the value of M[i, j]
     
 double * pnl_mat_lget (PnlMat *M, int i, int j)
   Description Return the address of M[i, j] for use as a lvalue.
     
 void pnl_mat_set_all (PnlMat *M, double x)
   Description Set all elements of M to x.
                                                                                    
                                                                                    
     
 void pnl_mat_set_zero (PnlMat *M)
   Description Set all elements of M to 0.
     
 void pnl_mat_set_id (PnlMat *M)
   Description Set the matrix M to the identity matrix. M must be a square matrix.
     
 void pnl_mat_set_diag (PnlMat *M, double x, int d)
   Description Set the dth diagonal terms of the matrix M to the value x. M must be a
     square matrix.
     
 void pnl_mat_set_from_ptr (PnlMat *M, const double *x)
   Description Set M row–wise with the values given by x. The array x must be at least
     M->mn long.
     
 void pnl_mat_get_row (PnlVect *V, const PnlMat *M, int i)
   Description Extract and copies the i-th row of M into V.
     
 void pnl_mat_get_col (PnlVect *V, const PnlMat *M, int j)
   Description Extract and copies the j-th column of M into V.
     
 PnlVect  pnl_vect_wrap_mat_row (const PnlMat *M, int i)
   Description Return a PnlVect (not a pointer) whose array is the i-th row of M. The
     new vector shares its data with the matrix M, which means that any modification to
     one of them will affect the other.
     
 PnlMat  pnl_mat_wrap_mat_rows (const PnlMat *M, int i_start, int i_end)
   Description Return a PnlMat (not a pointer) holding rows from i_start to i_end
     (included) of M. The new matrix shares its data with the matrix M, which means that
     any modification to one of them will affect the other.
                                                                                    
                                                                                    
     
 void pnl_mat_swap_rows (PnlMat *M, int i, int j)
   Description Swap two rows of a matrix.
     
 void pnl_mat_set_col (PnlMat *M, const PnlVect *V, int j)
   Description Set the i-th column of a matrix M with the content of V
     
 void pnl_mat_set_col_from_ptr (PnlMat *M, const double *x, int j)
   Description Set the i-th column of M with the content of x.
     
 void pnl_mat_set_row (PnlMat *M, const PnlVect *V, int i)
   Description Set the i-th row of M with the content of V
     
 void pnl_mat_set_row_from_ptr (PnlMat *M, const double *x, int i)
   Description Set the i-th row of M with the content of x
     
 void pnl_mat_add_row (PnlMat *M, int i, const PnlVect *r)
   Description Add a row in matrix M before position i and fill it with the content of r.
     If r == NULL, row i is left uninitialized. The index i may vary between 0 — add a row
     at the top of the matrix — and M->m — add a row after all rows.
     
 void pnl_mat_del_row (PnlMat *M, int i)
   Description Delete the row with index i (between 0 and M->m-1) of the matrix M.
 void pnl_mat_print (const PnlMat *M)
   Description Print a matrix to the standard output.
     
 void pnl_mat_fprint (FILE *fic, const PnlMat *M)
   Description Print a matrix to a file. The saved matrix can be reloaded by the function
     pnl_mat_create_from_file.
     
 void pnl_mat_print_csv (const PnlMat *M, char sep)
   Description Print a matrix to the standard output in the CSV format using separator
     sep.
     
 void pnl_mat_fprint_csv (FILE *fic, const PnlMat *M, char sep)
   Description Print a matrix to a CSV file using separator sep.
     
 void pnl_mat_print_nsp (const PnlMat *M)
   Description Print a matrix to the standard output in a format compatible with Nsp.
     
 void pnl_mat_fprint_nsp (FILE *fic, const PnlMat *M)
   Description Print a matrix to a file in a format compatible with Nsp.
 void pnl_mat_plus_scalar (PnlMat *lhs, double x)
   Description In-place matrix scalar addition
     
 void pnl_mat_minus_scalar (PnlMat *lhs, double x)
   Description In-place matrix scalar substraction
                                                                                    
                                                                                    
     
 void pnl_mat_mult_scalar (PnlMat *lhs, double x)
   Description In-place matrix scalar multiplication
     
 void pnl_mat_div_scalar (PnlMat *lhs, double x)
   Description In-place matrix scalar division
 void pnl_mat_mult_mat_term (PnlMat *lhs, const PnlMat *rhs)
   Description In-place matrix matrix term by term product
     
 void pnl_mat_div_mat_term (PnlMat *lhs, const PnlMat *rhs)
   Description In-place matrix matrix term by term division
     
 void pnl_mat_kron_mat_inplace (PnlMat *res, const PnlMat *B, const PnlMat
     *B)
   Description In-place Kroenecker product of A and B
     
 PnlMat * pnl_mat_kron_mat (const PnlMat *B, const PnlMat *B)
   Description Return the Kroenecker product of A and B
     
 void pnl_mat_map_inplace (PnlMat *lhs, double(*f)(double))
   Description lhs = f(lhs).
     
 void pnl_mat_map (PnlMat *lhs, const PnlMat *rhs, double(*f)(double))
   Description lhs = f(rhs).
                                                                                    
                                                                                    
     
    void pnl_mat_map_mat_inplace (PnlMat    *lhs,    const    PnlMat    *rhs,
     double(*f)(double, double))
   Description lhs = f(lhs, rhs).
     
 void pnl_mat_map_mat (PnlMat *lhs, const PnlMat *rhs1, const PnlMat *rhs2,
     double(*f)(double, double))
   Description lhs = f(rhs1, rhs2).
     
 double pnl_mat_sum (const PnlMat *lhs)
   Description Sum matrix component-wise
     
 void pnl_mat_sum_vect (PnlVect *y, const PnlMat *A, char c)
   Description Sum matrix column or row wise. Argument c can be either ’r’ (to get a
     row vector) or ’c’ (to get a column vector). When c=’r’, y(j) = ∑
  iAij and when c=’rc,
     y(i) = ∑
  jAij.
     
 void pnl_mat_cumsum (PnlMat *A, char c)
   Description Cumulative sum over the rows or columns. Argument c can be either ’r’
     to sum over the rows or ’c’ to sum over the columns. When c=’r’, Aij = ∑
  1≤k≤iAkj
     and when c=’rc, Aij = ∑
  1≤k≤jAik.
     
 double pnl_mat_prod (const PnlMat *lhs)
   Description Product matrix component-wise
     
 void pnl_mat_prod_vect (PnlVect *y, const PnlMat *A, char c)
   Description Prod matrix column or row wise. Argument c can be either ’r’ (to get a
     row vector) or ’c’ (to get a column vector). When c=’r’, y(j) = ∏
  iAij and when c=’rc,
     y(i) = ∏
  jAij.
     
 void pnl_mat_cumprod (PnlMat *A, char c)
   Description Cumulative prod over the rows or columns. Argument c can be either ’r’
     to prod over the rows or ’c’ to prod over the columns. When c=’r’, Aij = ∏
  1≤k≤iAkj
     and when c=’rc, Aij = ∏
  1≤k≤jAik.
 int pnl_mat_isequal (const PnlMat *A, const PnlMat *B, double err)
   Description Test if two matrices are equal up to err component–wise. The error err
     is either relative or absolute depending on the magnitude of the components. Return
     TRUE or FALSE.
     
 int pnl_mat_isequal_abs (const PnlMat *A, const PnlMat *B, double abserr)
   Description Test  if  two  matrices  are  equal  up  to  an  absolute  error  abserr
     component–wise. Return TRUE or FALSE.
     
 int pnl_mat_isequal_rel (const PnlMat *A, const PnlMat *B, double relerr)
   Description Test   if   two   matrices   are   equal   up   to   a   relative   error   relerr
     component–wise. Return TRUE or FALSE.
 void pnl_mat_max ( PnlVect *M, const PnlMat *A, char d)
   Description On exit, M(i) = max j(A(i,j)) when d=’c’ and M(i) = max j(A(j,i))
     when d=’r’ and M(0) = max i,j = A(i,j) when d=’*’.
     
 void pnl_mat_min ( PnlVect *m,const PnlMat *A, char d)
   Description On exit, m(i)  =  min j(A(i,j)) when d=’c’ and m(i)  =  min j(A(j,i))
     when d=’r’ and M(0) = min i,j = A(i,j) when d=’*’.
                                                                                    
                                                                                    
     
 void pnl_mat_minmax ( PnlVect *m, PnlVect *M, const PnlMat *A, char d)
   Description On exit, m(i) = min j(A(i,j)) and M(i) = max j(A(i,j)) when d=’c’
     and m(i) = min j(A(j,i)) and M(i) = min j(A(j,i)) when d=’r’ and M(0) = max i,j =
      A(i,j) and m(0) = min i,j = A(i,j) when d=’*’.
     
 void pnl_mat_min_index ( PnlVect *m, PnlVectInt *im, const PnlMat *A, char
     d)
   Description Idem as pnl_mat_min and index contains the indices of the minima. If
     index==NULL, the indices are not computed.
     
 void pnl_mat_max_index ( PnlVect *M, PnlVectInt *iM, const PnlMat *A, char
     d)
   Description Idem as pnl_mat_max and index contains the indices of the maxima. If
     index==NULL, the indices are not computed.
     
  void pnl_mat_minmax_index (  PnlVect  *m,  PnlVect  *M,  PnlVectInt  *im,
     PnlVectInt *iM, const PnlMat *A, char d)
   Description Idem as pnl_mat_minmax and im contains the indices of the minima
     and iM contains the indices of the minima. If im==NULL (resp. iM==NULL, the
     indices of the minima (resp. maxima) are not computed.
     
 void pnl_mat_qsort (PnlMat *, char dir, char order)
   Description Sort a matrix using a quick sort algorithm according to order (’i’ for
     increasing or ’d’ for decreasing). The parameter dir determines whether the matrix is
     sorted by rows or columns. If dir=’c’, each row is sorted independently of the others
     whereas if dir=’r’, each column is sorted independently of the others.
     
 void pnl_mat_qsort_index (PnlMat *, PnlMatInt *index, char dir, char order)
   Description Sort a matrix using a quick sort algorithm according to order (’i’ for
     increasing or ’d’ for decreasing). The parameter dir determines whether the matrix is
     sorted by rows or columns. If dir=’c’, each row is sorted independently of the others
     whereas if dir=’r’, each column is sorted independently of the others. In addition to the
     function pnl_mat_qsort, the permutation index is computed and stored into index.
                                                                                    
                                                                                    
     
 int pnl_mat_find (PnlVectInt *indi, PnlVectInt indj, char *type, int(*f)(double *t),
     …)
   Description f is a function taking a C array as argument and returning an integer. type is a
     string composed by the letters ’r’ and ’m’ and is used to describe the types of the arguments
     appearing after f : ’r’ for real numbers and ’m’ for matrices. This function aims at simulating
     Scilab’s find function. Here are a few examples (capital letters are used for matrices and small
     letters for real values) 
[indi, indj] = find ( a < X )
int isless ( double *t ) { return t[0] < t[1]; } pnl_mat_find ( indi, indj, "rm", isless, a, X );
ind = find (X <= Y)
int isless ( double *t ) { return t[0] <= t[1]; } pnl_mat_find ( ind, "mm", isless, X, Y );
[indi, indj] = find ((a < X) && (X <= Y))
int cmp ( double *t ) { return (t[0] <= t[1]) && (t[1] <= t[2]); } pnl_mat_find ( indi, indj, "rmm", cmp, a, X, Y );
(indi, indj) contains on exit the indices (i,j) for which the function f returned 1. Note that if indj == NULL on entry, a linear indexing is used for matrices, which means that matrices are seen as large vectors built up be stacking rows. This function returns OK or FAIL if something went wrong (size mismatch between matrices, invalid string type).
 void pnl_mat_plus_mat (PnlMat *lhs, const PnlMat *rhs)
   Description In-place matrix matrix addition
                                                                                    
                                                                                    
     
 void pnl_mat_minus_mat (PnlMat *lhs, const PnlMat *rhs)
   Description In-place matrix matrix substraction
     
 void pnl_mat_sq_transpose (PnlMat *M)
   Description On exit, M is transposed
     
 PnlMat * pnl_mat_transpose (const PnlMat *M)
   Description Create a new matrix which is the transposition of M
     
 void pnl_mat_tr ( PnlMat *tM, const PnlMat *M)
   Description On exit, tM = M’
     
 double pnl_mat_trace (const PnlMat *M)
   Description Return the trace of a square matrix.
     
 void pnl_mat_axpy (double alpha, const PnlMat *A, PnlMat *B)
   Description Compute B := alpha * A + B
     
 void pnl_mat_dger (double alpha, const PnlVect *x, const PnlVect *y, PnlMat *A)
   Description Compute A := alpha x * y’ + A
     
 PnlVect * pnl_mat_mult_vect (const PnlMat *A, const PnlVect *x)
   Description Matrix vector multiplication A * x
     
 void pnl_mat_mult_vect_inplace (PnlVect *y, const PnlMat *A, const PnlVect
     *x)
   Description In place matrix vector multiplication y = A * x. You cannot use the
     same vector for x and y.
                                                                                    
                                                                                    
     
 PnlVect * pnl_mat_mult_vect_transpose (const PnlMat *A, const PnlVect *x)
   Description Matrix vector multiplication A’ * x
     
 void pnl_mat_mult_vect_transpose_inplace (PnlVect *y, const PnlMat *A,
     const PnlVect *x)
   Description In place matrix vector multiplication y = A’ * x. You cannot use the
     same vector for x and y. The vectors x and y must be different.
     
 int pnl_mat_cross (PnlMat *lhs, const PnlMat *A, const PnlMat *B)
   Description Compute the cross products of the vectors given in matrices A and B
     which must have either 3 rows or 3 columns. A row wise computation is first tried, then
     a column wise approach is tested. FAIL is returned in case no dimension equals 3.
     
 void pnl_mat_lAxpby (double lambda, const PnlMat *A, const PnlVect *x, double
     b, PnlVect *y)
   Description Compute y := lambda A x + b y. When b=0, the content of y is not
     used on input and instead y is resized to match A*x. The vectors x and y must be
     different.
     
 void pnl_mat_dgemv (char trans, double lambda, const PnlMat *A, const PnlVect
     *x, double mu, PnlVect *b)
   Description Compute b := lambda op(A) x + mu b, where op (X) = X or op (X) =
     X’. If trans=’N’ or trans=’n’, op (A) = A, whereas if trans=’T’ or trans=’t’, op (A)
     = A’.When mu==0, the content of b is not used and instead b is resized to match
     op(A)*x. The vectors x and b must be different.
     
 void pnl_mat_dgemm (char transA, char transB, double alpha, const PnlMat *A,
     const PnlMat *B, double beta, PnlMat *C)
   Description Compute C := alpha * op(A) * op (B) + beta * C. When beta=0, the
     content of C is unused and instead C is resized to store alpha A *B. If transA=’N’ or
     transA=’n’, op (A) = A, whereas if transA=’T’ or transA=’t’, op (A) = A’. The same
     holds for transB. The matrix C must be different from A and B.
     
 PnlMat * pnl_mat_mult_mat (const PnlMat *rhs1, const PnlMat *rhs2)
   Description Matrix multiplication rhs1 * rhs2
     
  void pnl_mat_mult_mat_inplace (PnlMat  *lhs,  const  PnlMat  *rhs1,  const
     PnlMat *rhs2)
   Description In-place matrix multiplication lhs = rhs1 * rhs2. The matrix lhs must be
     different from rhs1 and rhs2.
     
 double pnl_mat_scalar_prod (const PnlMat *A, const PnlVect *x, const PnlVect
     *y)
   Description Compute x’ * A * y
     
 void pnl_mat_exp (PnlMat *B, const PnlMat *A)
   Description Compute the matrix exponential B = exp(A).
     
 void pnl_mat_log (PnlMat *B, const PnlMat *A)
   Description Compute the matrix logarithm B = log(A). For the moment, this function
     only works if A is diagonalizable.
     
   void pnl_mat_eigen (PnlVect   *v,   PnlMat   *P,   const   PnlMat   *A,   int
     with_eigenvector)
   Description Compute the eigenvalues (stored in v) and optionally the eigenvectors
     stored  column  wise  in  P  when  with_eigenvector==TRUE.  If  A  is  symmetric  or
     Hermitian in the complex case, P is orthonormal. When with_eigenvector=FALSE, P
     can be NULL.
Linear systems and matrix decompositions The following functions are designed to solve linear system of the from A x = b where A is a matrix and b is a vector except in the functions pnl_mat_syslin_mat, pnl_mat_lu_syslin_mat and pnl_mat_chol_syslin_mat which expect the right hand side member to be a matrix too. Whenever the vector b is not needed once the system is solved, you should consider using “inplace” functions.
All the functions described in this paragraph return OK if the computations have been carried out successfully and FAIL otherwise.
 int pnl_mat_chol (PnlMat *M)
   Description Compute the Cholesky decomposition of M. M must be symmetric, the
     positivity is tested in the algorithm. M = L * L’. On exit, the lower part of M contains
     the Cholesky decomposition L and the upper part is set to zero.
     
 int pnl_mat_pchol (PnlMat *M, double tol, int *rank, PnlVectInt *p)
   Description Compute the Cholesky decomposition of M with complete pivoting. P’
     * A * P = L * L’. M must be symmetric positive semi-definite. On exit, the lower part
     of M contains the Cholesky decomposition L and the upper part is set to zero. The
     permutation matrix is stored in an integer vector p : the only non zero elements of P
     are P(p(k),k) = 1
     
 int pnl_mat_lu (PnlMat *A, PnlPermutation *p)
   Description Compute a P A = LU factorization. P must be an already allocated
     PnlPermutation . On exit the decomposition is stored in A, the lower part of A contains
     L while the upper part (including the diagonal terms) contains U. Remember that the
     diagonal elements of L are all 1. Row i of A was interchanged with row p(i).
     
 int pnl_mat_upper_syslin (PnlVect *x, const PnlMat *U, const PnlVect *b)
   Description Solve an upper triangular linear system U x = b
     
 int pnl_mat_lower_syslin (PnlVect *x, const PnlMat *L, const PnlVect *b)
   Description Solve a lower triangular linear system L x = b
     
 int pnl_mat_chol_syslin (PnlVect *x, const PnlMat *chol, const PnlVect *b)
   Description Solve a symmetric definite positive linear system A x = b, in which chol
     is assumed to be the Cholesky decomposition of A computed by pnl_mat_chol
     
 int pnl_mat_chol_syslin_inplace ( const PnlMat *chol, PnlVect *b)
   Description Solve a symmetric definite positive linear system A x = b, in which chol
     is assumed to be the Cholesky decomposition of A computed by pnl_mat_chol. The
     solution of the system is stored in b on exit.
                                                                                    
                                                                                    
     
 int pnl_mat_lu_syslin (PnlVect *x, const PnlMat *LU, const PnlPermutation *p,
     const PnlVect *b)
   Description Solve a linear system A x = b using a LU decomposition. LU and P are
     assumed to be the PA = LU decomposition as computed by pnl_mat_lu. In particular,
     the structure of the matrix LU is the following : the lower part of A contains L while
     the upper part (including the diagonal terms) contains U. Remember that the diagonal
     elements of L are all 1.
     
 int pnl_mat_lu_syslin_inplace (const PnlMat *LU, const PnlPermutation *p,
     PnlVect *b)
   Description Solve a linear system A x = b using a LU decomposition. LU and P are
     assumed to be the PA = LU decomposition as computed by pnl_mat_lu. In particular,
     the structure of the matrix LU is the following : the lower part of A contains L while
     the upper part (including the diagonal terms) contains U. Remember that the diagonal
     elements of L are all 1. The solution of the system is stored in b on exit.
     
 int pnl_mat_syslin (PnlVect *x, const PnlMat *A, const PnlVect *b)
   Description Solve a linear system A x = b using a LU factorization which is computed
     inside this function.
     
 int pnl_mat_syslin_inplace (PnlMat *A, PnlVect *b)
   Description Solve a linear system A x = b using a LU factorization which is computed
     inside this function. The solution of the system is stored in b and A is overwritten by
     its LU decomposition.
     
 int pnl_mat_syslin_mat (PnlMat *A, PnlMat *B)
   Description Solve  a  linear  system  A  X  =  B  using  a  LU  factorization  which  is
     computed inside this function. A and B are matrices. A must be square. The solution
     of the system is stored in B on exit. On exit, A contains the LU decomposition of the
     input matrix which is lost.
     
 int pnl_mat_chol_syslin_mat (const PnlMat *A, PnlMat *B)
   Description Solve  a  linear  system  A  X  =  B  using  a  Cholesky  factorization  of
     the symmetric positive defnite matrix A. A contains the Cholesky decomposition as
     computed by pnl_mat_chol. B is matrix with the same number of rows as A. The
                                                                                    
                                                                                    
     solution of the system is stored in B on exit.
     
  int pnl_mat_lu_syslin_mat (const  PnlMat  *A,  const  PnlPermutation  *p,
     PnlMat *B)
   Description Solve a linear system A X = B using a P A = L U factorization. A
     contains the L U factors and p the associated permutation. A and p must have been
     computed by pnl_mat_lu. B is matrix with the same number of rows as A. The solution
     of the system is stored in B on exit.
The following functions are designed to invert matrices. The authors provide these functions although they cannot find good reasons to use them. Note that to solve a linear system, one must used the syslin functions and not invert the system matrix because it is much longer.
 int pnl_mat_upper_inverse (PnlMat *A, const PnlMat *B)
   Description Inversion of an upper triangular matrix
     
 int pnl_mat_lower_inverse (PnlMat *A, const PnlMat *B)
   Description Inversion of a lower triangular matrix
     
 int pnl_mat_inverse (PnlMat *inverse, const PnlMat *A)
   Description Compute the inverse of a matrix A and stores the result into inverse. A
     LU factorisation of the matrix A is computed inside this function.
     
 int pnl_mat_inverse_with_chol (PnlMat *inverse, const PnlMat *A)
   Description Compute the inverse of a symmetric positive definite matrix A and stores
     the result into inverse. The Cholesky factorisation of the matrix A is computed inside
     this function.
Linear systems and matrix decompositions The following functions are designed to solve linear system of the from A x = b where A is a matrix and b is a vector except in the functions pnl_mat_syslin_mat, pnl_mat_lu_syslin_mat and pnl_mat_chol_syslin_mat which expect the right hand side member to be a matrix too. Whenever the vector b is not needed once the system is solved, you should consider using “inplace” functions.
All the functions described in this paragraph return OK if the computations have been carried out successfully and FAIL otherwise.
 int pnl_mat_qr (PnlMat *Q, PnlMat *R, PnlPermutation *p, const PnlMat *A)
   Description Compute a A P = QR decomposition. If on entry P=NULL, then the
     decomposition is computed without pivoting, i.e A = QR. When P≠NULL, P must be
     an already allocated PnlPermutation . Q is an orthogonal matrix, i.e Q-1 = QT  and
     R is an upper triangular matrix. The use of pivoting improves the numerical stability
     when A is almost rank deficient, i.e when the smallest eigenvalue of A is very close to
     0.
     
 int pnl_mat_qr_syslin (PnlVect *x, const PnlMat *Q, const PnlMat *R, const
     PnlVectInt *p, const PnlVect *b)
   Description Solve a linear system A x = b where A is given by its QR decomposition
     with column pivoting as computed by the function pnl_mat_qr.
     
 int pnl_mat_ls (const PnlMat *A, PnlVect *b)
   Description Solve  a  linear  system  A  x  =  b  in  the  least  square  sense,  i.e.  x  =
     arg min U∥A *u -b∥2. The solution is stored into b on exit. It internally uses a AP =
     QR decomposition.
     
 int pnl_mat_ls_mat (const PnlMat *A, PnlMat *B)
   Description Solve a linear system A X = B with A and B two matrices in the least
     square sense, i.e. X = arg min U∥A *U -B∥2. The solution is stored into B on exit. It
     internally uses a AP = QR decomposition. Same function as pnl_mat_ls but handles
     several r.h.s.
 PnlMatComplex * pnl_mat_complex_create_from_mat (const PnlMat *R)
   Description Create a complex matrix using a real one. The complex parts of the
     entries of the returned matrix are all set to zero.
typedef PnlVectInt PnlPermutation;
The PnlPermutation type is actually nothing else than a vector of integers, i.e. a PnlVectInt. It is used to store the partial pivoting with row interchanges transformation needed in the LU decomposition. We use the Blas convention for storing permutations. Consider a PnlPermutation p generated by a LU decomposition of a matrix A : to compute the decomposition, row i of A was interchanged with row p(i).
 PnlPermutation * pnl_permutation_new ()
   Description Create an empty PnlPermutation .
     
 PnlPermutation * pnl_permutation_create (int n)
   Description Create a PnlPermutation of size n.
     
 void pnl_permutation_free (PnlPermutation **p)
   Description Free a PnlPermutation .
     
 void pnl_permutation_inverse (PnlPermutation *inv, const PnlPermutation *p)
   Description Compute in inv the inverse of the permutation p.
                                                                                    
                                                                                    
     
 void pnl_vect_permute (PnlVect *px, const PnlVect *x, const PnlPermutation *p)
   Description Apply a PnlPermutation to a PnlVect .
     
 void pnl_vect_permute_inplace (PnlVect *x, const PnlPermutation *p)
   Description Apply a PnlPermutation to a PnlVect in-place.
     
   void pnl_vect_permute_inverse (PnlVect   *px,   const   PnlVect   *x,   const
     PnlPermutation *p)
   Description Apply the inverse of PnlPermutation to a PnlVect .
     
  void pnl_vect_permute_inverse_inplace (PnlVect  *x,  const  PnlPermutation
     *p)
   Description Apply the inverse of a PnlPermutation to a PnlVect in-place.
     
    void pnl_mat_col_permute (PnlMat    *pX,    const    PnlMat    *X,    const
     PnlPermutation *p)
   Description Apply a PnlPermutation to the columns of a matrix. pX contains the
     result of the permutation applied to X.
     
    void pnl_mat_row_permute (PnlMat    *pX,    const    PnlMat    *X,    const
     PnlPermutation *p)
   Description Apply a PnlPermutation to the rows of a matrix. pX contains the result
     of the permutation applied to X.
     
 void pnl_permutation_fprint (FILE *fic, const PnlPermutation *p)
   Description Print a permutation to a file.
     
 void pnl_permutation_print (const PnlPermutation *p)
   Description Print a permutation to the standard output.
The structures and functions related to tridiagonal matrices are declared in pnl/pnl_tridiag_matrix.h.
We only store the three main diagonals as three vectors.
typedef struct PnlTridiagMat{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlTridiagMat pointer to be cast to a PnlObject */ PnlObject object; int size; /*!< number of rows, the matrix must be square */ double *D; /*!< diagonal elements */ double *DU; /*!< upper diagonal elements */ double *DL; /*!< lower diagonal elements */ } PnlTridiagMat;
size is the size of the matrix, D is an array of size size containing the diagonal terms. DU, DL are two arrays of size size-1 containing respectively the upper diagonal (Mi,i+1) and the lower diagonal (Mi-1,i).
typedef struct PnlTridiagMatLU{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlTridiagMatLU pointer to be cast to a PnlObject */ PnlObject object; int size; /*!< number of rows, the matrix must be square */ double *D; /*!< diagonal elements */ double *DU; /*!< upper diagonal elements */ double *DU2; /*!< second upper diagonal elements */ double *DL; /*!< lower diagonal elements */ int *ipiv; /*!< Permutation: row i has been interchanged with row ipiv(i) */ };
This type is used to store the LU decomposition of a tridiagonal matrix.
 PnlTridiagMat * pnl_tridiag_mat_new ()
   Description Create a PnlTridiagMat with size 0
     
 PnlTridiagMat * pnl_tridiag_mat_create (int size)
   Description Create a PnlTridiagMat with size size
                                                                                    
                                                                                    
     
 PnlTridiagMat * pnl_tridiag_mat_create_from_scalar (int size, double x)
   Description Create a PnlTridiagMat with the 3 diagonals filled with x
     
 PnlTridiagMat * pnl_tridiag_mat_create_from_two_scalar (int size, double
     x, double y)
   Description Create a PnlTridiagMat with the diagonal filled with x and the upper
     and lower diagonals filled with y
     
  PnlTridiagMat  * pnl_tridiag_mat_create_from_ptr (int  size,  const  double
     *lower_D, const double *D, const double *upper_D)
   Description Create a PnlTridiagMat
     
 PnlTridiagMat * pnl_tridiag_mat_create_from_mat (const PnlMat *mat)
   Description Create a tridiagonal matrix from a full matrix (all the elements but the
     3 diagonal ones are ignored).
     
 PnlMat * pnl_tridiag_mat_to_mat (const PnlTridiagMat *T)
   Description Create a full matrix from a tridiagonal one.
     
 PnlTridiagMat * pnl_tridiag_mat_copy (const PnlTridiagMat *T)
   Description Copy a tridiagonal matrix.
     
 void pnl_tridiag_mat_clone (PnlTridiagMat *clone, const PnlTridiagMat *T)
   Description Copy the content of T into clone
     
 void  pnl_tridiag_mat_free (PnlTridiagMat **v)
   Description Free a PnlTridiagMat
     
 int pnl_tridiag_mat_resize (PnlTridiagMat *v, int size)
   Description Resize a PnlTridiagMat .
Accessing elements. If it is supported by the compiler, the following functions are declared inline. To speed up these functions, you can use the macro constant PNL_RANGE_CHECK_OFF, see Section 1.3.2 for an explanation.
 void pnl_tridiag_mat_set (PnlTridiagMat *self, int d, int up, double x)
   Description Set self[d, d+up] = x, up can be {-1,0,1}.
     
 double pnl_tridiag_mat_get (const PnlTridiagMat *self, int d, int up)
   Description Get self[d, d+up], up can be {-1,0,1}.
     
 double * pnl_tridiag_mat_lget (PnlTridiagMat *self, int d, int up)
   Description Return the address self[d, d+up] = x, up can be {-1,0,1}.
 void pnl_tridiag_mat_fprint (FILE *fic, const PnlTridiagMat *M)
   Description Print a tri-diagonal matrix to a file.
     
 void pnl_tridiag_mat_print (const PnlTridiagMat *M)
   Description Print a tridiagonal matrix to the standard output.
     void pnl_tridiag_mat_plus_tridiag_mat (PnlTridiagMat     *lhs,     const
     PnlTridiagMat *rhs)
   Description In-place matrix matrix addition
                                                                                    
                                                                                    
     
    void pnl_tridiag_mat_minus_tridiag_mat (PnlTridiagMat    *lhs,    const
     PnlTridiagMat *rhs)
   Description In-place matrix matrix substraction
     
 void pnl_tridiag_mat_plus_scalar (PnlTridiagMat *lhs, double x)
   Description In-place matrix scalar addition
     
 void pnl_tridiag_mat_minus_scalar (PnlTridiagMat *lhs, double x)
   Description In-place matrix scalar substraction
     
 void pnl_tridiag_mat_mult_scalar (PnlTridiagMat *lhs, double x)
   Description In-place matrix scalar multiplication
     
 void pnl_tridiag_mat_div_scalar (PnlTridiagMat *lhs, double x)
   Description In-place matrix scalar division
  void pnl_tridiag_mat_mult_tridiag_mat_term (PnlTridiagMat  *lhs,  const
     PnlTridiagMat *rhs)
   Description In-place matrix matrix term by term product
     
   void pnl_tridiag_mat_div_tridiag_mat_term (PnlTridiagMat   *lhs,   const
     PnlTridiagMat *rhs)
   Description In-place matrix matrix term by term division
     
 void pnl_tridiag_mat_map_inplace (PnlTridiagMat *lhs, double(*f)(double))
   Description lhs = f(lhs).
                                                                                    
                                                                                    
     
 void pnl_tridiag_mat_map_tridiag_mat_inplace (PnlTridiagMat *lhs, const
     PnlTridiagMat *rhs, double(*f)(double, double))
   Description lhs = f(lhs, rhs).
Standard matrix operations & Linear systems
 void pnl_tridiag_mat_mult_vect_inplace (PnlVect *lhs, const PnlTridiagMat
     *mat, const PnlVect *rhs)
   Description In place matrix multiplication. The vector lhs must be different from rhs.
     
   PnlVect   * pnl_tridiag_mat_mult_vect (const   PnlTridiagMat   *mat,   const
     PnlVect *vec)
   Description Matrix multiplication
     
 void pnl_tridiag_mat_lAxpby (double lambda, const PnlTridiagMat *A, const
     PnlVect *x, double mu, PnlVect *b)
   Description Compute b := lambda A x + mu b. When mu==0, the content of b is
     not used on input and instead b is resized to match A*x. Note that the vectors x and
     b must be different.
     
  double pnl_tridiag_mat_scalar_prod (const  PnlVect  *x,const  PnlTridiagMat
     *A, const PnlVect *y)
   Description Compute x’ * A * y
     
 void pnl_tridiag_mat_syslin_inplace ( PnlTridiagMat *M, PnlVect *b)
   Description Solve the linear system M x = b. The solution is written into b on exit.
     On exit, M is modified and becomes unusable.
     
 void pnl_tridiag_mat_syslin (PnlVect *x, PnlTridiagMat *M, const PnlVect *b)
   Description Solve the linear system M x = b. On exit, M is modified and becomes
     unusable.
     
 PnlTridiagMatLU * pnl_tridiag_mat_lu_new ()
   Description Create an empty PnlTridiagMatLU
     
 PnlTridiagMatLU * pnl_tridiag_mat_lu_create (int size)
   Description Create a PnlTridiagMatLU with size size
     
 PnlTridiagMatLU * pnl_tridiag_mat_lu_copy (const PnlTridiagMatLU *mat)
   Description Create a new PnlTridiagMatLU which is a copy of mat.
     
        void pnl_tridiag_mat_lu_clone (PnlTridiagMatLU        *clone,        const
     PnlTridiagMatLU *mat)
   Description Clone  a  PnlTridiagMatLU  .  clone  must  already  exist,  no  memory  is
     allocated for the envelope.
     
 void pnl_tridiag_mat_lu_free (PnlTridiagMatLU **m)
   Description Free a PnlTridiagMatLU
     
 int pnl_tridiag_mat_lu_resize (PnlTridiagMatLU *v, int size)
   Description Resize a PnlTridiagMatLU
     
 int pnl_tridiag_mat_lu_compute (PnlTridiagMatLU *LU, const PnlTridiagMat
     *A)
   Description Compute  the  LU  factorisation  of  a  tridiagonal  matrix  A.  LU  must
     have already been created using pnl_tridiag_mat_lu_new. On exit, LU contains the
     decomposition which is suitable for use in pnl_tridiag_mat_lu_syslin.
     
 int pnl_tridiag_mat_lu_syslin_inplace (PnlTridiagMatLU *LU, PnlVect *b)
   Description Solve a linear system A x = b where the matrix LU is given the LU
     decomposition of A previously computed by pnl_tridiag_mat_lu_compute. On exit, b
     is overwritten by the solution x.
     
  int pnl_tridiag_mat_lu_syslin (PnlVect  *x,  PnlTridiagMatLU  *LU,  const
     PnlVect *b)
   Description Solve a linear system A x = b where the matrix LU is given the LU
     decomposition of A previously computed by pnl_tridiag_mat_lu_compute.
typedef struct { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlBandMat pointer to be cast to a PnlObject */ PnlObject object; int m; /*!< nb rows */ int n; /*!< nb columns */ int nu; /*!< nb of upperdiagonals */ int nl; /*!< nb of lowerdiagonals */ int m_band; /*!< nb rows of the band storage */ int n_band; /*!< nb columns of the band storage */ double *array; /*!< a block to store the bands */ } PnlBandMat;
The structures and functions related to band matrices are declared in pnl/pnl_band_matrix.h.
 PnlBandMat * pnl_band_mat_new ()
   Description Create a band matrix of size 0.
     
 PnlBandMat * pnl_band_mat_create (int m, int n, int nl, int nu)
   Description Create a band matrix of size m x n with nl lower diagonals and nu upper
     diagonals.
     
 PnlBandMat * pnl_band_mat_create_from_mat (const PnlMat *BM, int nl,
     int nu)
   Description Extract a band matrix from a PnlMat .
     
 void pnl_band_mat_free (PnlBandMat **)
   Description Free a band matrix.
     
 void pnl_band_mat_clone (PnlBandMat *clone, const PnlBandMat *M)
   Description Copy the band matrix M into clone. No new PnlBandMat is created.
     
 PnlBandMat * pnl_band_mat_copy (PnlBandMat *BM)
   Description Create a new band matrix which is a copy of BM. Each band matrix
     owns its data array.
     
 PnlMat * pnl_band_mat_to_mat (PnlBandMat *BM)
   Description Create a full matrix from a band matrix.
     
 int pnl_band_mat_resize (PnlBandMat *BM, int m, int n, int nl, int nu)
   Description Resize BM to store a m x n band matrix with nu upper diagonals and
     nl lower diagonals.
Accessing elements. If it is supported by the compiler, the following functions are declared inline. To speed up these functions, you can use the macro constant PNL_RANGE_CHECK_OFF, see Section 1.3.2 for an explanation.
 void pnl_band_mat_set (PnlBandMat *M, int i, int j, double x)
   Description Mi,j = x.
                                                                                    
                                                                                    
     
 void pnl_band_mat_get (PnlBandMat *M, int i, int j)
   Description Return Mi,j.
     
 void pnl_band_mat_lget (PnlBandMat *M, int i, int j)
   Description Return the address &(Mi,j).
     
 void pnl_band_mat_set_all (PnlBandMat *M, double x)
   Description Set all the elements of M to x.
     
 void pnl_band_mat_print_as_full (PnlBandMat *M)
   Description Print a band matrix in a full format.
 void pnl_band_mat_plus_scalar (PnlBandMat *lhs, double x)
   Description In-place addition, lhs += x
     
 void pnl_band_mat_minus_scalar (PnlBandMat *lhs, double x)
   Description In-place substraction lhs -= x
     
 void pnl_band_mat_div_scalar (PnlBandMat *lhs, double x)
   Description lhs = lhs ./ x
     
 void pnl_band_mat_mult_scalar (PnlBandMat *lhs, double x)
   Description lhs = lhs * x
                                                                                    
                                                                                    
     
  void pnl_band_mat_plus_band_mat (PnlBandMat  *lhs,  const  PnlBandMat
     *rhs)
   Description In-place addition, lhs += rhs
     
 void pnl_band_mat_minus_band_mat (PnlBandMat *lhs, const PnlBandMat
     *rhs)
   Description In-place substraction lhs -= rhs
     
 void pnl_band_mat_inv_term (PnlBandMat *lhs)
   Description In-place term by term inversion lhs = 1 ./ rhs
     
     void pnl_band_mat_div_band_mat_term (PnlBandMat     *lhs,     const
     PnlBandMat *rhs)
   Description In-place term by term division lhs = lhs ./ rhs
     
    void pnl_band_mat_mult_band_mat_term (PnlBandMat    *lhs,    const
     PnlBandMat *rhs)
   Description In-place term by term multiplication lhs = lhs .* rhs
     
    void pnl_band_mat_map (PnlBandMat    *lhs,    const    PnlBandMat    *rhs,
     double(*f)(double))
   Description lhs = f(rhs)
     
 void pnl_band_mat_map_inplace (PnlBandMat *lhs, double(*f)(double))
   Description lhs = f(lhs)
     
   void pnl_band_mat_map_band_mat_inplace (PnlBandMat   *lhs,   const
     PnlBandMat *rhs, double(*f)(double,double))
   Description lhs = f(lhs,rhs)
Standard matrix operations & Linear system
  void pnl_band_mat_lAxpby (double  lambda,  const  PnlBandMat  *A,  const
     PnlVect *x, double mu, PnlVect *b)
   Description Compute b := lambda A x + mu b. When mu==0, the content of b is
     not used on input and instead b is resized to match the size of A*x.
     
 void pnl_band_mat_mult_vect_inplace (PnlVect *y, const PnlBandMat *BM,
     const PnlVect *x)
   Description y = BM * x
     
 void pnl_band_mat_syslin_inplace (PnlBandMat *M, PnlVect *b)
   Description Solve the linear system M x = b with M a PnlBandMat . Note that M
     is modified on output and becomes unusable. On exit, the solution x is stored in b.
     
 void pnl_band_mat_syslin (PnlVect *x,PnlBandMat *M, PnlVect *b)
   Description Solve the linear system M x = b with M a PnlBandMat . Note that M
     is modified on output and becomes unusable.
     
 void pnl_band_mat_lu (PnlBandMat *BM, PnlVectInt *p)
   Description Compute  the  LU  decomposition  with  partial  pivoting  with  row
     interchanges. On exit, BM is enlarged to store the LU decomposition. On exit, p stores
     the permutation applied to the rows. Note that the Lapack format is used to store p,
     this format differs from the one used by PnlPermutation .
     
 void pnl_band_mat_lu_syslin_inplace (const PnlBandMat *M, PnlVectInt *p,
     PnlVect *b)
   Description Solve the band linear system M x = b where M is the LU decomposition
     computed by pnl_band_mat_lu and p the associated permutation. On exit, the solution
     x is stored in b.
     
 void pnl_band_mat_lu_syslin (PnlVect *x, const PnlBandMat *M, PnlVectInt
     *p, const PnlVect *b)
   Description Solve the band linear system M x = b where M is the LU decomposition
     computed by pnl_band_mat_lu and p the associated permutation.
The structures and functions related to matrices are declared in pnl/pnl_sp_matrix.h.
typedef struct _PnlSpMat { /** * Must be the first element in order for the object mechanism to work * properly. This allows a PnlSpMat pointer to be cast to a PnlObject */ PnlObject object; int m; /*!< number of rows */ int n; /*!< number of columns */ int nz; /*!< number of non-zero elements */ int *J; /*!< column indices, vector of size nzmax */ int *I; /*!< row offset integer vector, array[I[i]] is the first element of row i. Vector of size (m+1) */ double *array; /*!< pointer to store the data of size nzmax*/ int nzmax; /*!< size of the memory block allocated for array */ } PnlSpMat; typedef struct _PnlSpMatInt { /** * Must be the first element in order for the object mechanism to work * properly. This allows a PnlSpMat pointer to be cast to a PnlObject */ PnlObject object; int m; /*!< number of rows */ int n; /*!< number of columns */ int nz; /*!< number of non-zero elements */ int *J; /*!< column indices, vector of size nzmax */ int *I; /*!< row offset integer vector, array[I[i]] is the first element of row i. Vector of size (m+1) */ int *array; /*!< pointer to store the data of size nzmax */ int nzmax; /*!< size of the memory block allocated for array */ } PnlSpMatInt; typedef struct _PnlSpMatComplex { /** * Must be the first element in order for the object mechanism to work * properly. This allows a PnlSpMat pointer to be cast to a PnlObject */ PnlObject object; int m; /*!< number of rows */ int n; /*!< number of columns */ int nz; /*!< number of non-zero elements */ int *J; /*!< column indices, vector of size nzmax */ int *I; /*!< row offset integer vector, array[I[i]] is the first element of row i. Vector of size (m+1) */ dcomplex *array; /*!< pointer to store the data of size nzmax */ int nzmax; /*!< size of the memory block allocated for array */ } PnlSpMatComplex;
The non zero elements of row i are stored in array between the indices I[i] and I[i+1]-1. The array J
contains the column indices of every element of array. 
Sparse matrices are defined using the internal template approach and can be used for integer, float or complex base data according to the following table
| base type | prefix | type | 
| double | pnl_sp_mat | PnlSpMat | 
| int | pnl_sp_mat_int | PnlSpMatInt | 
| dcomplex | pnl_sp_mat_complex | PnlSpMatComplex | 
 PnlSpMat * pnl_sp_mat_new ()
   Description Create an empty sparse matrix.
     
 PnlSpMat * pnl_sp_mat_create (int m, int n, int nzmax)
   Description Create a sparse matrix with size m x n designed to hold at most nzmax
     non zero elements.
     
 void pnl_sp_mat_clone (PnlSpMat *dest, const PnlSpMat *src)
   Description Clone src into dest, which is automatically resized. On output, dest and
     src are equal but independent.
     
 PnlSpMat * pnl_sp_mat_copy (PnlSpMat *src)
   Description Create an independent copy of src.
     
 void pnl_sp_mat_free (PnlSpMat **)
   Description Delete a sparse matrix.
     
 int pnl_sp_mat_resize (PnlSpMat *M, int m, int n, int nzmax)
   Description Resize an existing PnlSpMat to become a m x n sparse matrices holding
     at most nzmax. Note that no old data are kept except if M->m is left unchanged and
     we only call this function to increase M->nzmax. Return OK or FAIL.
     
 PnlMat * pnl_mat_create_from_sp_mat (const PnlSpMat *M)
   Description Create a dense PnlMat from a spare one.
     
 PnlSpMat * pnl_sp_mat_create_from_mat (const PnlMat *M)
   Description Create a sparse matrix from a dense one.
     
 void pnl_sp_mat_create_from_file (char *file)
   Description Read a sparse matrix from the file with name file. We use the Matrix Market
     Exchange Format 
M N L | <--- rows, columns, entries I1 J1 A(I1, J1) | <--+ I2 J2 A(I2, J2) | | I3 J3 A(I3, J3) | |-- L lines . . . | | IL JL A(IL, JL) | <--+
The format (I1, J1) A(I1, J1) is also accepted. Anything after a # or % is ignored up to the end of the line.
 void pnl_sp_mat_set (PnlSpMat *M, int i, int j, double x)
   Description Set M[i,j] = x. This function increases M->nzmax if necessary.
     
 double pnl_sp_mat_get (const PnlSpMat *M, int i, int j)
   Description Return M[i,j]. If M has no entry with such an index, zero is returned.
 void pnl_sp_mat_plus_scalar (PnlSpMat *M, double x)
   Description Add x to all non zero entries of M. To apply the operation to all entries
     including the zero ones, first convert M to a dense matrix and use pnl_mat_plus_scalar.
     
 void pnl_sp_mat_minus_scalar (PnlSpMat *M, double x)
   Description Substract  x  to  all  non  zero  entries  of  M.  To  apply  the  operation
     to  all  entries  including  the  zero  ones,  first  convert  M  to  a  dense  matrix  and  use
     pnl_mat_minus_scalar.
     
 void pnl_sp_mat_mult_scalar (PnlSpMat *M, double x)
   Description In-place matrix scalar multiplication
                                                                                    
                                                                                    
     
 void pnl_sp_mat_div_scalar (PnlSpMat *M, double x)
   Description In-place matrix scalar division
 void pnl_sp_mat_fprint (FILE *fic, const PnlSpMat *M)
   Description Print a sparse matrix to a file descriptor using the format (row, col) –>
     val. The file can be read by pnl_sp_mat_create_from_file.
     
 void pnl_sp_mat_print (const PnlSpMat *M)
   Description Same as pnl_sp_mat_fprint but print to standard output.
     
 void pnl_sp_mat_mult_vect (PnlVect *y, const PnlSpMat *A, const PnlVect *x)
   Description y = A x.
     
 void pnl_sp_mat_lAxpby (double lambda, const PnlSpMat *A, const PnlVect *x,
     double b, PnlVect *y)
   Description Compute y := lambda A x + b y. When b=0, the content of y is not
     used on input and instead y is resized to match A*x. The vectors x and y must be
     different.
     
 void  pnl_sp_mat_plus_sp_mat_inplace (PnlSpMat *res, const PnlSpMat *A,
     const PnlSpMat *B)
   Description In-place addition: res = A + B.
     
 PnlSpMat * pnl_sp_mat_plus_sp_mat (const PnlSpMat *A, const PnlSpMat
     *B)
   Description Return the sum of A and B.
                                                                                    
                                                                                    
     
 void  pnl_sp_mat_kron_inplace (PnlSpMat *result, const PnlSpMat *A, const
     PnlSpMat *B)
   Description In-place Kroenecker product of A and B.
     
 PnlSpMat * pnl_sp_mat_kron (const PnlSpMat *A, const PnlSpMat *B)
   Description Return the Kroenecker product of A and B.
 int pnl_sp_mat_isequal (const PnlSpMat *x, const PnlSpMat *y, double abserr)
   Description Test if two sparse matrices are equal up to err component–wise. The
     error err is either relative or absolute depending on the magnitude of the components.
     Return TRUE or FALSE.
     
 int pnl_sp_mat_isequal_abs (const PnlSpMat *x, const PnlSpMat *y, double
     relerr)
   Description Test if two sparse matrices are equal up to an absolute error abserr
     component–wise. Return TRUE or FALSE.
     
 int pnl_sp_mat_isequal_rel (const PnlSpMat *x, const PnlSpMat *y, double err)
   Description Test  if  two  sparse  matrices  are  equal  up  to  a  relative  error  relerr
     component–wise. Return TRUE or FALSE.
The Hyper matrix types and related functions are defined in the header pnl/pnl_matrix.h.
typedef struct PnlHmat{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlHmat pointer to be cast to a PnlObject */ PnlObject object; int ndim; /*!< nb dimensions */ int *dims; /*!< pointer to store the values of the ndim dimensions */ int mn; /*!< product dim_1 *...*dim_ndim */ int *pdims; /*!< array of size ndim, s.t. pdims[i] = dims[ndim-1] x ... dims[i+1] with pdims[ndim - 1] = 1 */ double *array; /*!< pointer to store */ } PnlHmat; typedef struct PnlHmatInt{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlHmatInt pointer to be cast to a PnlObject */ PnlObject object; int ndim; /*!< nb dimensions */ int *dims; /*!< pointer to store the value of the ndim dimensions */ int mn; /*!< product dim_1 *...*dim_ndim */ int *pdims; /*!< array of size ndim, s.t. pdims[i] = dims[ndim-1] x ... dims[i+1] with pdims[ndim - 1] = 1 */ int *array; /*!< pointer to store */ } PnlHmatInt; typedef struct PnlHmatComplex{ /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlHmatComplex pointer to be cast to a PnlObject */ PnlObject object; int ndim; /*!< nb dimensions */ int *dims; /*!< pointer to store the value of the ndim dimensions */ int mn; /*!< product dim_1 *...*dim_ndim */ int *pdims; /*!< array of size ndim, s.t. pdims[i] = dims[ndim-1] x ... dims[i+1] with pdims[ndim - 1] = 1 */ dcomplex *array; /*!< pointer to store */ } PnlHmatComplex;
ndim is the number of dimensions, dim is an array to store the size of each dimension and nm contains the product of the sizes of each dimension. array is an array of size mn containing the data. The integer array pdims is used to create the one–to–one map between the natural indexing and the linear indexing used in array.
These functions exist for all types of hypermatrices no matter what the basic type is. The following conventions are used to name functions operating on hypermatrices. Here is the table of prefixes used for the different basic types.
| base type | prefix | type | 
| double | pnl_hmat | PnlHmat | 
| int | pnl_hmat_int | PnlHmatInt | 
| dcomplex | pnl_hmat_complex | PnlHmatComplex | 
In this paragraph, we present the functions operating on PnlHmat which exist for all types. To deduce the prototypes of these functions for other basic types, one must replace pnl_hmat and double according the above table.
 PnlHmat * pnl_hmat_new ()
   Description Create an empty PnlHmat .
                                                                                    
                                                                                    
     
 PnlHmat * pnl_hmat_create (int ndim, const int *dims)
   Description Create a PnlHmat with ndim dimensions and the size of each dimension
     is given by the entries of the integer array dims
     
 PnlHmat * pnl_hmat_create_from_scalar (int ndim, const int *dims, double x)
   Description Create a PnlHmat with ndim dimensions given by ∏
  idims[i] filled with
     x.
     
PnlHmat * pnl_hmat_create_from_ptr (int ndim, const int *dims, const double *x)
 PnlHmat * pnl_hmat_copy (const PnlHmat *H)
   Description Copy a PnlHmat .
     
 void pnl_hmat_clone (PnlHmat *clone, const PnlHmat *H)
   Description Clone a PnlHmat .
     
 int pnl_hmat_resize (PnlHmat *H, int ndim, const int *dims)
   Description Resize a PnlHmat .
 void pnl_hmat_set (PnlHmat *self, int *tab, double x)
   Description Set the element of index tab to x.
                                                                                    
                                                                                    
     
 double pnl_hmat_get (const PnlHmat *self, int *tab)
   Description Return the value of the element of index tab
     
 double* pnl_hmat_lget (PnlHmat *self, int *tab)
   Description Return the address of self[tab] for use as a lvalue.
     
 PnlMat  pnl_mat_wrap_hmat (PnlHmat *H, int *t)
   Description Return a true PnlMat not a pointer holding the data H(t,:,:). Note that t
     must be of size ndim-2 and that it cannot be checked within the function. The returned
     matrix shares its data with H, it is only a view not a true copy.
     
 PnlVect  pnl_vect_wrap_hmat (PnlHmat *H, int *t)
   Description Return a true PnlVect not a pointer holding the data H(t,:). Note that t
     must be of size ndim-1 and that it cannot be checked within the function. The returned
     vector shares its data with H, it is only a view not a true copy.
 void pnl_hmat_print (const PnlHmat *H)
   Description Print an hypermatrix.
 void pnl_hmat_plus_hmat (PnlHmat *lhs, const PnlHmat *rhs)
   Description Compute lhs += rhs.
                                                                                    
                                                                                    
     
 void pnl_hmat_mult_scalar (PnlHmat *lhs, double x)
   Description Compute lhs *= x where x is a real number.
The structures and functions related to solvers are declared in pnl/pnl_linalgsolver.h.
typedef struct _PnlIterationBase PnlIterationBase; typedef struct _PnlCgSolver PnlCgSolver; typedef struct _PnlBicgSolver PnlBicgSolver; typedef struct _PnlGmresSolver PnlGmresSolver; struct _PnlIterationBase { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlVectXXX pointer to be cast to a PnlObject */ PnlObject object; int iteration; int max_iter; double normb; double tol_; double resid; int error; /* char * err_msg; */ }; /* When you repeatedly use iterative solvers, do not malloc each time */ struct _PnlCgSolver { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlCgSolver pointer to be cast to a PnlObject */ PnlObject object; PnlVect * r; PnlVect * z; PnlVect * p; PnlVect * q; double rho; double oldrho; double beta; double alpha; PnlIterationBase * iter; } ; struct _PnlBicgSolver { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlBicgSolver pointer to be cast to a PnlObject */ PnlObject object; double rho_1, rho_2, alpha, beta, omega; PnlVect * p; PnlVect * phat; PnlVect * s; PnlVect * shat; PnlVect * t; PnlVect * v; PnlVect * r; PnlVect * rtilde; PnlIterationBase * iter; } ; struct _PnlGmresSolver { /** * Must be the first element in order for the object mechanism to work * properly. This allows any PnlGmresSolver pointer to be cast to a PnlObject */ PnlObject object; int restart; double beta; PnlVect * s; PnlVect * cs; PnlVect * sn; PnlVect * w; PnlVect * r; PnlMat * H; PnlVect * v[MAX_RESTART]; PnlIterationBase *iter; PnlIterationBase *iter_inner; } ;
A Left preconditioner solves the problem :

and whereas right preconditioner solves

More information is given in Saad, Yousef (2003). Iterative methods for sparse linear systems (2nd ed. ed.). SIAM. ISBN 0898715342. OCLC 51266114. The reader will find in this book some discussion about right or/and left preconditioner and a description of the following algorithms.
These algorithms, we implemented with a left preconditioner. Right preconditioner can be easily computed changing matrix vector multiplication operator from M x to M PR x and solving PRy = x at the end of algorithm.
Three methods are implemented : Conjugate Gradient, BICGstab and GMRES with restart. For each of them a structure is created to store temporary vectors used in the algorithm. In some cases, we have to apply iterative methods more than once : for example to solve at each time step a discrete form of an elliptic problem come from parabolic problem. In the cases, do not call the constructor and destructor at each time, but instead use the initialization and solve procedures.
Formally we have,
Create iterative method For each time step Initialisation of iterative method Solve linear system link to elliptic problem end for free iterative method
In these functions, we don’t use any particular matrix structure. We give the matrix vector multiplication as a parameter of the solver.
Conjugate Gradient method Only available for symmetric and positive matrices.
 PnlCgSolver * pnl_cg_solver_new ()
   Description Create an empty PnlCgSolver
     
 PnlCgSolver * pnl_cg_solver_create (int Size, int max-iter, double tolerance)
   Description Create a new PnlCgSolver pointer.
     
 void pnl_cg_solver_initialisation (PnlCgSolver *Solver, const PnlVect *b)
   Description Initialisation of the solver at the beginning of iterative method.
     
 void pnl_cg_solver_free (PnlCgSolver **Solver)
   Description Destructor of iterative solver
     
   int pnl_cg_solver_solve (void(*matrix   vector-product)(const   void   *,   const
     PnlVect  *,  const  double,  const  double,  PnlVect  *),  const  void  *Matrix-Data,
     void(*matrix vector-product-PC)(const void *, const PnlVect *, const double, const
     double, PnlVect *), const void *PC-Data, PnlVect *x, const PnlVect *b, PnlCgSolver
     *Solver)
   Description Solve  the  linear  system  matrix  vector-product  is  the  matrix  vector
     multiplication  function  matrix  vector-product-PC  is  the  preconditionner  function
     Matrix-Data & PC-Data is data to compute matrix vector multiplication.
 PnlBicgSolver * pnl_bicg_solver_new ()
   Description Create an empty PnlBicgSolver.
     
 PnlBicgSolver * pnl_bicg_solver_create (int Size, int max-iter, double tolerance)
   Description Create a new PnlBicgSolver pointer.
     
 void pnl_bicg_solver_initialisation (PnlBicgSolver *Solver, const PnlVect *b)
   Description Initialisation of the solver at the beginning of iterative method.
     
 void pnl_bicg_solver_free (PnlBicgSolver **Solver)
   Description Destructor of iterative solver
     
  int pnl_bicg_solver_solve (void(*matrix  vector-product)(const  void  *,  const
     PnlVect  *,  const  double,  const  double,  PnlVect  *),  const  void  *Matrix-Data,
     void(*matrix vector-product-PC)(const void *, const PnlVect *, const double, const
     double, PnlVect *), const void *PC-Data, PnlVect *x, const PnlVect *b, PnlBicgSolver
     *Solver)
   Description Solve  the  linear  system  matrix  vector-product  is  the  matrix  vector
     multiplication  function  matrix  vector-product-PC  is  the  preconditioner  function
     Matrix-Data & PC-Data is data to compute matrix vector multiplication.
GMRES with restart See Saad, Yousef (2003) for a discussion about the restart parameter. For GMRES we need to store at the p-th iteration p vectors of the same size of the right and side. It could be very expensive in term of memory allocation. So GMRES with restart algorithm stop if p = restart and restarts the algorithm with the previously computed solution as initial guess.
Note that if restart equals m, we have a classical GMRES algorithm.
 PnlGmresSolver * pnl_gmres_solver_new ()
   Description Create an empty PnlGmresSolver
     
 PnlGmresSolver * pnl_gmres_solver_create (int Size, int max-iter, int restart,
     double tolerance)
   Description Create a new PnlGmresSolver pointer.
     
  void pnl_gmres_solver_initialisation (PnlGmresSolver  *Solver,  const  PnlVect
     *b)
   Description Initialisation of the solver at the beginning of iterative method.
     
 void pnl_gmres_solver_free (PnlGmresSolver **Solver)
   Description Destructor of iterative solver
     
  int pnl_gmres_solver_solve (void(*matrix  vector-product)(const  void  *,  const
     PnlVect  *,  const  double,  const  double,  PnlVect  *),  const  void  *Matrix-Data,
                                                                                    
                                                                                    
     void(*matrix vector-product-PC)(const void *, const PnlVect *, const double, const
     double, PnlVect *), const void *PC-Data, PnlVect *x, const PnlVect *b, PnlGmresSolver
     *Solver)
   Description Solve  the  linear  system  matrix  vector-product  is  the  matrix  vector
     multiplication  function  matrix  vector-product-PC  is  the  preconditionner  function
     Matrix-Data & PC-Data is data to compute matrix vector multiplication.
In the next paragraph, we write all the solvers for PnlMat . This will be done as follows: construct an application matrix vector.
static void pnl_mat_mult_vect_applied(const void *mat, const PnlVect *vec, const double a , const double b, PnlVect *lhs) {pnl_mat_lAxpby(a, (PnlMat*)mat, vec, b, lhs);}
and give it as the parameter of the iterative method
int pnl_mat_cg_solver_solve(const PnlMat * Matrix, const PnlMat * PC, PnlVect * x, const PnlVect *b, PnlCgSolver * Solver) { return pnl_cg_solver_solve(pnl_mat_mult_vect_applied, Matrix, pnl_mat_mult_vect_applied, PC, x, b, Solver);}
In practice, we cannot define all iterative methods for all structures. With this implementation, the user can easily :
implement right precondioner,
implement method with sparse matrix and diagonal preconditioner, or special combination of this form …
Iterative algorithms for PnlMat
 int pnl_mat_cg_solver_solve (const PnlMat *M, const PnlMat *PC, PnlVect
     *x, const PnlVect *b, PnlCgSolver *Solver)
   Description Solve the linear system M x = b with preconditionner PC.
     
 int pnl_mat_bicg_solver_solve (const PnlMat *M, const PnlMat *PC, PnlVect
     *x, const PnlVect *b, PnlBicgSolver *Solver)
   Description Solve the linear system M x = b with preconditionner PC.
     
  int pnl_mat_gmres_solver_solve (const  PnlMat  *M,  const  PnlMat  *PC,
     PnlVect *x, PnlVect *b, PnlGmresSolver *Solver)
   Description Solve the linear system M x = b with preconditionner PC.