Matrix and Vector - osvaldoandrade/ova-lib GitHub Wiki
Matrix and Vector
Read this page when the problem is dense numeric state kept directly in memory.
Constructors
The constructors are:
matrix *create_matrix(int rows, int cols);
vector *create_vector(int size);
create_matrix returns NULL for non-positive dimensions or allocation failure.
create_vector allocates a double *data buffer and installs the public method pointers.
Public Struct Shape
Both matrix and vector use the method-table struct pattern: each struct carries a void *impl (opaque internal storage) and a set of function pointers for every operation. Callers never touch internal fields directly.
| Matrix field | Meaning |
|---|---|
impl |
opaque internal storage — do not access directly |
get(self, row, col) |
read a single element |
set(self, row, col, value) |
write a single element |
rows(self) |
query the current row count |
cols(self) |
query the current column count |
Use m->get(m, row, col) to read and m->set(m, row, col, value) to write. Use m->rows(m) and m->cols(m) to query dimensions.
| Vector field | Meaning |
|---|---|
impl |
opaque internal storage — do not access directly |
get(self, index) |
read a single element |
set(self, index, value) |
write a single element |
size(self) |
query the current element count |
Use v->get(v, index) to read, v->set(v, index, value) to write, and v->size(v) for the element count.
Matrix Operations
| Field | Meaning |
|---|---|
add |
returns a new matrix with elementwise sum |
subtract |
returns a new matrix with elementwise difference |
multiply |
returns a new matrix with matrix product |
determinant |
returns the determinant and writes error state |
transpose |
returns a new transposed matrix |
inverse |
returns a new inverse matrix or NULL |
resize |
resizes in place and returns 0 on success, -1 on failure |
copy |
returns a new duplicate matrix |
print |
prints matrix contents |
free |
frees the matrix |
Shape Rules
Addition and subtraction require equal shapes.
Multiplication requires self->cols == other->rows.
Determinant and inverse require a square matrix.
If a shape rule is violated, the operation returns NULL or reports an error according to the function shape.
Resize Rules
matrix->resize preserves the overlapping rectangle between the old shape and the new shape.
If the matrix grows, new cells are zero-filled.
If resize fails, the shipped tests verify that the original matrix state remains intact.
vector->resize uses realloc. If the vector grows, new elements are zero-filled. On allocation failure it leaves the vector unchanged.
Determinant and Inverse
determinant returns the numeric result and writes *error = 0 on success or *error = 1 on invalid input or working-memory failure.
inverse returns NULL for singular matrices or allocation failure.
Ownership and Cleanup
Matrices own their row allocations and the row-pointer array.
Vectors own their double *data buffer.
Destroy them with matrix->free(matrix) and vector->free(vector).
The new matrices returned by add, subtract, multiply, transpose, inverse, and copy belong to the caller.
Example
#include "matrix.h"
int main(void) {
matrix *a = create_matrix(2, 2);
matrix *b = create_matrix(2, 2);
a->set(a, 0, 0, 1.0); a->set(a, 0, 1, 2.0);
a->set(a, 1, 0, 3.0); a->set(a, 1, 1, 4.0);
b->set(b, 0, 0, 5.0); b->set(b, 0, 1, 6.0);
b->set(b, 1, 0, 7.0); b->set(b, 1, 1, 8.0);
matrix *c = a->multiply(a, b);
double value = c ? c->get(c, 0, 0) : -1.0;
if (c) c->free(c);
a->free(a);
b->free(b);
return value == 19.0 ? 0 : 1;
}
Read Next
If the matrix and vector layer is only a base for a linear program, move to Linear-Programming-Solver.