SMOL, as the name suggests, is a small C library for relatively simple matrix operations on small matrix structures. Most notes in this document are not relevant for the user, but merely serve as a mental note and guidance for myself. The use and development of this library is mainly for educational purposes. There are several, more sophisticated libraries for intensive linear algebra computations, like BLAS and LAPACK.
SMOL operates on what is essentially a pointer to a continous block of (one-dimensional) memory, which is interpreted as a matrix in row-major order (compatible to how multi-dimensional arrays are stored). The interpretation requires usually two further attributes; the number of rows and the number of columns. An entry i,j in the memory array of m rows and n columns is therefore indexed by [i*n+j].
SMOL_Matrix is a struct, which encapsulates the array and the size attribute into a single type. This type can be passed around, copied and assigned like any other first-class type. Have in mind that the internal matrix array is stored as a pointer. This leads to only the pointer being copied on assignment, rather than the memory block the pointer points to. This effect has to be taken into account, if a deep copy is desired.
Depending on the size of the rows and columns of the matrix structure, a SMOL_Matrix can either be interpreted as a zero value (null matrix), a scalar, a proper matrix or a row- or column vector. The type of a matrix can be inferred by either checking its size properties or calling SMOL_TypeOf(&matrix), which will return an SMOL_TYPE enumerated integer value.
It is easy to convert a two-dimensional array into a matrix struct. Given the array arr[3][2], you can do (SMOL_Matrix){.fields=&arr, .nRows=3, .nCols=2} to construct a matrix struct pointing to the given array. If you want a deep copy of the array, you would do a SMOL_CopyMatrix operation on the constructed matrix struct.
Most of the operations follow a losely structured naming convention to convey information to the user about memory allocation and call-by-reference argument alteration. Functions with the suffix Matrix can be generally thought of constructing a new completely matrix. These functions will always allocate memory, which has to be freed at some point. So beware that you do not do something like this: SMOL_Multiply(&A, &SMOL_RandomMatrix());, as you will have no way to retrieve the pointers to the memory allocated by the call to SMOL_RandomMatrix().
Most operations are declared in imperative form, such as Add, Transpose or Multiply. This means, that the operations alters the left-hand side argument - the subject of operation - which is always the first argument passed by reference. The operation A = A * B translates to SMOL_Multiply(&A, &B);. The result of the operation is stored in the left-hand operator.
The test framework consists of the CTest utility of CMake together with a library containing a small set of macros, called minunit. The CMakeLists.txt in the test/ directory contains definitions for test executables, corresponding to single files of collections of test cases. All test cases perform certain assertions and checks and are packed together into a single test suite. This suite is run by the test executable, returning a zero value if everything is OK. Executing make test in the build/ directory will start the CTest process, which in turn executes all defined test executables. CTest will print a short list of passed - and failed - tests. Details about a particular test suite can be obtained by executing the individual test executable manually. This will print out a more detailed view of all the assertions and checks made and also which test cases in particular failed, if any.
This project is licenced under the GNU GPLv3.