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.