Add get/set to Zig Matrix example
This commit is contained in:
parent
1d70b482de
commit
30cc0d98c6
@ -2,6 +2,7 @@ const std = @import("std");
|
|||||||
|
|
||||||
const MatrixOpError = error{
|
const MatrixOpError = error{
|
||||||
IncompatibleSizes,
|
IncompatibleSizes,
|
||||||
|
OutOfBounds,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Matrix = struct {
|
const Matrix = struct {
|
||||||
@ -9,20 +10,58 @@ const Matrix = struct {
|
|||||||
numbers: []i64,
|
numbers: []i64,
|
||||||
dimensions: []const u64,
|
dimensions: []const u64,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, dimensions: []const u64) !Matrix {
|
pub fn init(allocator: std.mem.Allocator, dimensions: []const u64, init_numbers: []const i64) !Matrix {
|
||||||
var size: u64 = 1;
|
var size: u64 = 1;
|
||||||
|
|
||||||
for (dimensions) |dim| {
|
for (dimensions) |dim| {
|
||||||
size *= dim;
|
size *= dim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var numbers = try allocator.alloc(i64, size);
|
||||||
|
|
||||||
|
for (0.., init_numbers) |i, num| {
|
||||||
|
numbers[i] = num;
|
||||||
|
}
|
||||||
|
|
||||||
return Matrix{
|
return Matrix{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.numbers = try allocator.alloc(i64, size),
|
.numbers = numbers,
|
||||||
.dimensions = dimensions,
|
.dimensions = dimensions,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn position_deep_to_flat(self: Matrix, position: []const u64) u64 {
|
||||||
|
var flat_position: u64 = 0;
|
||||||
|
var curr_volume: u64 = 1;
|
||||||
|
|
||||||
|
for (0.., position) |i, pos| {
|
||||||
|
flat_position += pos * curr_volume;
|
||||||
|
curr_volume *= self.dimensions[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return flat_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(self: Matrix, position: []const u64) !i64 {
|
||||||
|
const flat_position = position_deep_to_flat(self, position);
|
||||||
|
|
||||||
|
if (flat_position >= self.numbers.len) {
|
||||||
|
return error.OutOfBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.numbers[flat_position];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(self: Matrix, position: []const u64, value: i64) !void {
|
||||||
|
const flat_position = position_deep_to_flat(self, position);
|
||||||
|
|
||||||
|
if (flat_position >= self.numbers.len) {
|
||||||
|
return error.OutOfBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.numbers[flat_position] = value;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fill(self: Matrix, number: i64) void {
|
pub fn fill(self: Matrix, number: i64) void {
|
||||||
var i: u64 = 0;
|
var i: u64 = 0;
|
||||||
while (i < self.numbers.len) {
|
while (i < self.numbers.len) {
|
||||||
@ -36,12 +75,11 @@ const Matrix = struct {
|
|||||||
return error.IncompatibleSizes;
|
return error.IncompatibleSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result: Matrix = try Matrix.init(allocator, self.dimensions);
|
var result: Matrix = try Matrix.init(
|
||||||
result.fill(0);
|
allocator,
|
||||||
|
self.dimensions,
|
||||||
for (self.numbers, 0..) |num, idx| {
|
self.numbers,
|
||||||
result.numbers[idx] += num;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
for (other.numbers, 0..) |num, idx| {
|
for (other.numbers, 0..) |num, idx| {
|
||||||
result.numbers[idx] += num;
|
result.numbers[idx] += num;
|
||||||
@ -55,12 +93,11 @@ const Matrix = struct {
|
|||||||
return error.IncompatibleSizes;
|
return error.IncompatibleSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result: Matrix = try Matrix.init(allocator, self.dimensions);
|
var result: Matrix = try Matrix.init(
|
||||||
result.fill(0);
|
allocator,
|
||||||
|
self.dimensions,
|
||||||
for (self.numbers, 0..) |num, idx| {
|
self.numbers,
|
||||||
result.numbers[idx] += num;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
for (other.numbers, 0..) |num, idx| {
|
for (other.numbers, 0..) |num, idx| {
|
||||||
result.numbers[idx] -= num;
|
result.numbers[idx] -= num;
|
||||||
@ -75,18 +112,60 @@ const Matrix = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
std.debug.print("Please use 'zig build test --summary all' to run tests. This example does not have any other runnable code.\n", .{});
|
const help_text =
|
||||||
|
\\Please use 'zig build test --summary all' to run tests.
|
||||||
|
\\This example does not have any other runnable code.\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
std.debug.print(help_text, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "matrix init" {
|
test "matrix init" {
|
||||||
const mat = try Matrix.init(std.testing.allocator, &[_]u64{ 5, 5 });
|
const mat = try Matrix.init(std.testing.allocator, &.{ 5, 5 }, &.{});
|
||||||
defer mat.deinit();
|
defer mat.deinit();
|
||||||
|
|
||||||
try std.testing.expect(mat.numbers.len == 25);
|
try std.testing.expect(mat.numbers.len == 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "matrix get 2 dim" {
|
||||||
|
const mat = try Matrix.init(
|
||||||
|
std.testing.allocator,
|
||||||
|
&.{ 3, 3 },
|
||||||
|
&.{ 1, 2, 3, 4, 5, 6, 7, 8, 9 },
|
||||||
|
);
|
||||||
|
defer mat.deinit();
|
||||||
|
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 0 }) == 1);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 0 }) == 2);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 2, 0 }) == 3);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 1 }) == 4);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 1 }) == 5);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 2, 1 }) == 6);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 2 }) == 7);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 2 }) == 8);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 2, 2 }) == 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "matrix get 3 dim" {
|
||||||
|
const mat = try Matrix.init(
|
||||||
|
std.testing.allocator,
|
||||||
|
&.{ 2, 2, 2 },
|
||||||
|
&.{ 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||||
|
);
|
||||||
|
defer mat.deinit();
|
||||||
|
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 0, 0 }) == 1);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 0, 0 }) == 2);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 1, 0 }) == 3);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 1, 0 }) == 4);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 0, 1 }) == 5);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 0, 1 }) == 6);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 0, 1, 1 }) == 7);
|
||||||
|
try std.testing.expect(try mat.get(&.{ 1, 1, 1 }) == 8);
|
||||||
|
}
|
||||||
|
|
||||||
test "matrix fill" {
|
test "matrix fill" {
|
||||||
const mat = try Matrix.init(std.testing.allocator, &[_]u64{ 5, 5 });
|
const mat = try Matrix.init(std.testing.allocator, &.{ 5, 5 }, &.{});
|
||||||
defer mat.deinit();
|
defer mat.deinit();
|
||||||
mat.fill(123);
|
mat.fill(123);
|
||||||
|
|
||||||
@ -96,9 +175,9 @@ test "matrix fill" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "matrix add" {
|
test "matrix add" {
|
||||||
const mat1 = try Matrix.init(std.testing.allocator, &[_]u64{ 2, 2 });
|
const mat1 = try Matrix.init(std.testing.allocator, &.{ 2, 2 }, &.{});
|
||||||
defer mat1.deinit();
|
defer mat1.deinit();
|
||||||
const mat2 = try Matrix.init(std.testing.allocator, &[_]u64{ 2, 2 });
|
const mat2 = try Matrix.init(std.testing.allocator, &.{ 2, 2 }, &.{});
|
||||||
defer mat2.deinit();
|
defer mat2.deinit();
|
||||||
|
|
||||||
mat1.fill(1);
|
mat1.fill(1);
|
||||||
@ -114,9 +193,9 @@ test "matrix add" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "matrix sub" {
|
test "matrix sub" {
|
||||||
const mat1 = try Matrix.init(std.testing.allocator, &[_]u64{ 2, 2 });
|
const mat1 = try Matrix.init(std.testing.allocator, &.{ 2, 2 }, &.{});
|
||||||
defer mat1.deinit();
|
defer mat1.deinit();
|
||||||
const mat2 = try Matrix.init(std.testing.allocator, &[_]u64{ 2, 2 });
|
const mat2 = try Matrix.init(std.testing.allocator, &.{ 2, 2 }, &.{});
|
||||||
defer mat2.deinit();
|
defer mat2.deinit();
|
||||||
|
|
||||||
mat1.fill(1);
|
mat1.fill(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user