File size: 1,855 Bytes
fb6457c | 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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include "bsh_tensor.hpp"
#include <cstring>
#include <cmath>
namespace bsh {
Tensor::Tensor(size_t rows, size_t cols)
: rows_(rows), cols_(cols), data_(new float[rows * cols]) {
std::memset(data_.get(), 0, rows * cols * sizeof(float));
}
Tensor::~Tensor() = default;
void Tensor::fill(float value) {
for (size_t i = 0; i < rows_ * cols_; ++i) {
data_[i] = value;
}
}
float& Tensor::at(size_t row, size_t col) {
return data_[row * cols_ + col];
}
const float& Tensor::at(size_t row, size_t col) const {
return data_[row * cols_ + col];
}
float* Tensor::data() {
return data_.get();
}
const float* Tensor::data() const {
return data_.get();
}
size_t Tensor::rows() const { return rows_; }
size_t Tensor::cols() const { return cols_; }
size_t Tensor::size() const { return rows_ * cols_; }
Tensor Tensor::transpose() const {
Tensor result(cols_, rows_);
for (size_t i = 0; i < rows_; ++i) {
for (size_t j = 0; j < cols_; ++j) {
result.at(j, i) = this->at(i, j);
}
}
return result;
}
void Tensor::softmax(Tensor& output) const {
if (output.rows() != rows_ || output.cols() != cols_) {
throw std::runtime_error("Output tensor dimension mismatch");
}
for (size_t i = 0; i < rows_; ++i) {
float max_val = data_[i * cols_];
for (size_t j = 0; j < cols_; ++j) {
if (data_[i * cols_ + j] > max_val) {
max_val = data_[i * cols_ + j];
}
}
float sum = 0.0f;
for (size_t j = 0; j < cols_; ++j) {
output.data_[i * cols_ + j] = std::exp(data_[i * cols_ + j] - max_val);
sum += output.data_[i * cols_ + j];
}
for (size_t j = 0; j < cols_; ++j) {
output.data_[i * cols_ + j] /= sum;
}
}
}
} // namespace bsh
|