From 276641b9c643d5edd6ce53ee6428b6d2e7c45e2a Mon Sep 17 00:00:00 2001 From: Riccardo Forese Date: Mon, 2 Feb 2026 17:25:04 +0100 Subject: [PATCH] Aggiunta della struttura neuron e tensor --- src/main.zig | 41 ++++++++++++++++++++++------------------- src/neuron.zig | 43 +++++++++++++++++++++++++++++++++++++++++++ src/tensor.zig | 28 ++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 19 deletions(-) create mode 100644 src/neuron.zig create mode 100644 src/tensor.zig diff --git a/src/main.zig b/src/main.zig index 25b067e..240cf72 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,25 +1,28 @@ const std = @import("std"); -const AI_Zig = @import("AI_Zig"); +const Neuron = @import("neuron.zig").Neuron; +const Tensor = @import("tensor.zig").Tensor; pub fn main() !void { - std.debug.print("All your {s} are belong to us.\n", .{"codebase"}); - try AI_Zig.bufferedPrint(); -} + // 1. Setup dell'allocatore per la memoria + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); -test "simple test" { - const gpa = std.testing.allocator; - var list: std.ArrayList(i32) = .empty; - defer list.deinit(gpa); - try list.append(gpa, 42); - try std.testing.expectEqual(@as(i32, 42), list.pop()); -} + // 2. Creiamo un neurone con 3 ingressi + var my_neuron = try Neuron.init(allocator, 3); + defer my_neuron.deinit(); -test "fuzz example" { - const Context = struct { - fn testOne(context: @This(), input: []const u8) anyerror!void { - _ = context; - try std.testing.expect(!std.mem.eql(u8, "canyoufindme", input)); - } - }; - try std.testing.fuzz(Context{}, Context.testOne, .{}); + // 3. Creiamo dei dati di input di esempio (es. [1.0, 0.5, -2.0]) + var inputs = try Tensor.init(allocator, &[_]usize{3}); + defer inputs.deinit(); + inputs.data[0] = 1.0; + inputs.data[1] = 0.5; + inputs.data[2] = -2.0; + + // 4. Eseguiamo il calcolo + const output = my_neuron.forward(inputs); + + std.debug.print("Input: {any}\n", .{inputs.data}); + std.debug.print("Pesi del neurone: {any}\n", .{my_neuron.weights.data}); + std.debug.print("Risultato (Output): {d:.4}\n", .{output}); } diff --git a/src/neuron.zig b/src/neuron.zig new file mode 100644 index 0000000..12648cd --- /dev/null +++ b/src/neuron.zig @@ -0,0 +1,43 @@ +const std = @import("std"); +const Tensor = @import("tensor.zig").Tensor; + +pub const Neuron = struct { + weights: Tensor, + bias: f32, + + pub fn init(allocator: std.mem.Allocator, input_size: usize) !Neuron { + const weights = try Tensor.init(allocator, &[_]usize{input_size}); + + var seed: u64 = undefined; + try std.posix.getrandom(std.mem.asBytes(&seed)); + + var prng = std.Random.DefaultPrng.init(seed); + const rand = prng.random(); + + for (weights.data) |*w| { + w.* = rand.float(f32) * 2.0 - 1.0; + } + + return Neuron{ + .weights = weights, + .bias = 0.0, + }; + } + + pub fn deinit(self: *Neuron) void { + self.weights.deinit(); + } + + pub fn forward(self: *Neuron, inputs: Tensor) f32 { + std.debug.assert(inputs.data.len == self.weights.data.len); + + var sum: f32 = 0.0; + for (inputs.data, self.weights.data) |x, w| { + sum += x * w; + } + + const z = sum + self.bias; + + return if (z > 0) z else 0; + } +}; diff --git a/src/tensor.zig b/src/tensor.zig new file mode 100644 index 0000000..e6aaf40 --- /dev/null +++ b/src/tensor.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; + +pub const Tensor = struct { + data: []f32, + shape: []const usize, + allocator: Allocator, + + pub fn init(allocator: Allocator, shape: []const usize) !Tensor { + var size: usize = 1; + for (shape) |dim| { + size *= dim; + } + + const data = try allocator.alloc(f32, size); + @memset(data, 0); + + return Tensor{ + .data = data, + .shape = shape, + .allocator = allocator, + }; + } + + pub fn deinit(self: *Tensor) void { + self.allocator.free(self.data); + } +};