notRaphael commited on
Commit
69dc359
·
verified ·
1 Parent(s): a43c1c8

Upload core/tensor.hpp

Browse files
Files changed (1) hide show
  1. core/tensor.hpp +140 -0
core/tensor.hpp ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+ #include <vector>
3
+ #include <cassert>
4
+ #include <cmath>
5
+ #include <random>
6
+ #include <iostream>
7
+ #include <iomanip>
8
+ #include <cstring>
9
+ #include <algorithm>
10
+
11
+ namespace newnet {
12
+
13
+ class Tensor {
14
+ public:
15
+ std::vector<float> data;
16
+ std::vector<float> grad;
17
+ std::vector<int> shape;
18
+ bool requires_grad;
19
+
20
+ // --- Constructors ---
21
+
22
+ Tensor() : requires_grad(false) {}
23
+
24
+ // Create tensor with given shape, zero-initialized
25
+ Tensor(std::vector<int> shape_)
26
+ : shape(shape_), requires_grad(false) {
27
+ int size = 1;
28
+ for (int dim : shape) size *= dim;
29
+ data.resize(size, 0.0f);
30
+ }
31
+
32
+ // Create tensor with given shape and initial value
33
+ Tensor(std::vector<int> shape_, float val)
34
+ : shape(shape_), requires_grad(false) {
35
+ int size = 1;
36
+ for (int dim : shape) size *= dim;
37
+ data.resize(size, val);
38
+ }
39
+
40
+ // --- Factory methods ---
41
+
42
+ static Tensor zeros(std::vector<int> shape) {
43
+ return Tensor(shape, 0.0f);
44
+ }
45
+
46
+ static Tensor ones(std::vector<int> shape) {
47
+ return Tensor(shape, 1.0f);
48
+ }
49
+
50
+ // Xavier initialization: good for Dense layers
51
+ // Values drawn from uniform(-limit, limit) where limit = sqrt(6 / (fan_in + fan_out))
52
+ static Tensor xavier(int fan_in, int fan_out) {
53
+ Tensor t({fan_in, fan_out});
54
+ float limit = std::sqrt(6.0f / (fan_in + fan_out));
55
+ std::mt19937 gen(42);
56
+ std::uniform_real_distribution<float> dist(-limit, limit);
57
+ for (int i = 0; i < (int)t.data.size(); i++) {
58
+ t.data[i] = dist(gen);
59
+ }
60
+ t.requires_grad = true;
61
+ return t;
62
+ }
63
+
64
+ // --- Accessors ---
65
+
66
+ int size() const {
67
+ int s = 1;
68
+ for (int dim : shape) s *= dim;
69
+ return s;
70
+ }
71
+
72
+ int rows() const {
73
+ assert(shape.size() >= 1);
74
+ return shape[0];
75
+ }
76
+
77
+ int cols() const {
78
+ assert(shape.size() >= 2);
79
+ return shape[1];
80
+ }
81
+
82
+ // 2D access: tensor(row, col)
83
+ float& operator()(int row, int col) {
84
+ assert((int)shape.size() == 2);
85
+ return data[row * shape[1] + col];
86
+ }
87
+
88
+ const float& operator()(int row, int col) const {
89
+ assert((int)shape.size() == 2);
90
+ return data[row * shape[1] + col];
91
+ }
92
+
93
+ // --- Gradient management ---
94
+
95
+ void init_grad() {
96
+ grad.resize(data.size(), 0.0f);
97
+ }
98
+
99
+ void zero_grad() {
100
+ std::fill(grad.begin(), grad.end(), 0.0f);
101
+ }
102
+
103
+ // --- Debug ---
104
+
105
+ void print(const std::string& name = "") const {
106
+ if (!name.empty()) std::cout << name << " ";
107
+ std::cout << "[";
108
+ for (int i = 0; i < (int)shape.size(); i++) {
109
+ std::cout << shape[i];
110
+ if (i < (int)shape.size() - 1) std::cout << "x";
111
+ }
112
+ std::cout << "]:\n";
113
+
114
+ if ((int)shape.size() == 2) {
115
+ int r = std::min(rows(), 6);
116
+ int c = std::min(cols(), 6);
117
+ for (int i = 0; i < r; i++) {
118
+ std::cout << " ";
119
+ for (int j = 0; j < c; j++) {
120
+ std::cout << std::setw(9) << std::fixed
121
+ << std::setprecision(4) << (*this)(i, j);
122
+ }
123
+ if (cols() > 6) std::cout << " ...";
124
+ std::cout << "\n";
125
+ }
126
+ if (rows() > 6) std::cout << " ...\n";
127
+ } else {
128
+ int n = std::min(size(), 10);
129
+ std::cout << " ";
130
+ for (int i = 0; i < n; i++) {
131
+ std::cout << std::setw(9) << std::fixed
132
+ << std::setprecision(4) << data[i];
133
+ }
134
+ if (size() > 10) std::cout << " ...";
135
+ std::cout << "\n";
136
+ }
137
+ }
138
+ };
139
+
140
+ } // namespace newnet