summaryrefslogtreecommitdiff
path: root/src/matrix.zig
blob: 41be14e9ee741de28ffbd3bef70b414c007fe2f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const std = @import("std");
const ArrayList = std.ArrayList;
const ArenaAllocator = std.heap.ArenaAllocator;

const matrix = struct {
    h: usize,
    w: usize,
    x: ArrayList(f32),
};

pub fn new(arena: *ArenaAllocator, h: usize, w: usize, x: []f32) matrix {
    var m = matrix{
        .h = h,
        .w = w,
        .x = ArrayList(f32).init(arena.allocator()),
    };

    var i: usize = 0;
    while (i < h * w) : (i += 1) {
        if (m.x.append(x[i])) |_| {} else |_| {}
    }

    return m;
}

pub fn dot(a: []f32, b: []f32, len: usize, step: usize) f32 {
    var x: f32 = 0;
    var j: usize = 0;
    var i: usize = len;
    var k: usize = 0;

    while (i > 0) : (i -= 1) {
        x += a[k] * b[j];
        k += 1;
        j += step;
    }

    return x;
}

pub fn multiply(arena: *ArenaAllocator, a: matrix, b: matrix) matrix {
    var x = ArrayList(f32).init(arena.allocator());
    var i: usize = 0;
    var k: usize = 0;

    while (i < a.h) : (i += 1) {
        var j: usize = 0;
        while (j < b.w) : (j += 1) {
            if (x.append(dot(a.x.items[k..], b.x.items[j..], a.w, b.w))) |_| {} else |_| {}
        }
        k += a.w;
    }

    return new(arena, a.h, b.w, x.items);
}