// Converted from Python by Scyla

// import numpy as np
// import torch
// import torch.nn as nn
// import torch.nn.functional as F
// import math

struct SimpleNet {
    fn new(input_dim, hidden_dim, output_dim) {
        // super().__init__()
        let w1 = t_rand(input_dim, hidden_dim) * 0.01
        let w2 = t_rand(hidden_dim, output_dim) * 0.01
        let bias = t_zeros(hidden_dim)

    }
    fn forward(x) {
        let h = t_matmul(x, w1) + bias
        let h = relu(h)
        let out = t_matmul(h, w2)
        return softmax(out)

    }
}
fn train_step(model, x, target, lr) {
    let output = model.forward(x)
    let loss = cross_entropy(output, target)
    backward(loss)
    return loss

}
fn evaluate(model, x, target) {
    let output = model.forward(x)
    let loss = cross_entropy(output, target)
    return loss

}
fn make_data(n, dim) {
    let x = t_rand(n, dim)
    let y = t_zeros(n)
    return t_create(x), t_create(y)

}
fn main() {
    let model = SimpleNet(64, 128, 10)
    let train_x, train_y = make_data(500, 64)

    for epoch in 0..50 {
        let lr = 0.001 * sqrt(1.0 / (1.0 + epoch))
        let loss = train_step(model, train_x, train_y, lr)

        if epoch % 10 == 0 {
            let val_loss = evaluate(model, train_x, train_y)
            println("Epoch {epoch}: loss={loss:.4f} val={val_loss:.4f}")

        }
    }
    println("Done.")
}