Sync public subset from Flux (private)
This commit is contained in:
0
include/modules/.gitkeep
Normal file
0
include/modules/.gitkeep
Normal file
40
include/modules/field1d.h
Normal file
40
include/modules/field1d.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/vector.h"
|
||||
#include "modules/grid1d.h"
|
||||
|
||||
|
||||
namespace fvm {
|
||||
|
||||
template <typename T>
|
||||
|
||||
struct Field1D{
|
||||
|
||||
const Grid1D* grid = nullptr; // not owning
|
||||
utils::Vector<T> u; // size = grid->N
|
||||
|
||||
Field1D() = default;
|
||||
|
||||
explicit Field1D(const Grid1D& g, double init = 0.0) : grid(&g), u(g.N){
|
||||
|
||||
}
|
||||
|
||||
void generate_vertices(){
|
||||
vertices.resize(N_vertices);
|
||||
vertices[0] = centers[0] - ((centers[1] - centers[0])*0.5);
|
||||
vertices[N_vertices-1] = centers[N_centers-1] + ((centers[N_centers-1] - centers[N_centers-2])*0.5);
|
||||
for (uint64_t i = 1; i < N_centers; ++i){
|
||||
vertices[i] = (centers[i-1] + centers[i])*0.5;
|
||||
}
|
||||
}
|
||||
|
||||
T dx(uint64_t i) const { check(i); return vertices(i+1) - vertices(i); }
|
||||
T center(uint64_t i) const { check(i); return centers(i); }
|
||||
private:
|
||||
void check(uint64_t i) const {
|
||||
if (i >= N_centers) throw std::runtime_error("Grid1D: cell index out of range");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
58
include/modules/finitedifference1d.h
Normal file
58
include/modules/finitedifference1d.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "modules/grid1d.h"
|
||||
|
||||
|
||||
namespace fd1d {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Second derivative (u_xx) at interior cell i, central difference
|
||||
// Works on NON-uniform grids
|
||||
// On uniform: (u[i-1] - 2 u[i] + u[i+1]) / dx^2
|
||||
// -----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void inplace_Build_CentralDerivative_Matrix(const fvm::Grid1D<T>& g, utils::Matrix<T>& A, utils::Vector<T>& b, const utils::Vector<T>& s, const T& c){
|
||||
|
||||
for (uint64_t i = 1; i < g.center_idx; ++i){
|
||||
|
||||
A(i,i-1) = -(c/(g.centers[i] - g.centers[i-1]));
|
||||
A(i,i) = -((c/(g.centers[i+1] - g.centers[i])) + (c/(g.centers[i] - g.centers[i-1])));
|
||||
A(i,i+1) = -(c/(g.centers[i+1] - g.centers[i]));
|
||||
b[i] = -s[i]*(g.vertices[i+1] - g.vertices[i]);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
utils::Matrix<T> Build_CentralDerivative_Matrix(const fvm::Grid1D<T>& g, utils::Vector<T>& b, const utils::Vector<T>& s, const T& c){
|
||||
utils::Matrix<T> A(g.center_idx+1, g.center_idx+1, T{0});
|
||||
inplace_Build_CentralDerivative_Matrix(g, A, b, s, c);
|
||||
return A;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void inplace_BC_Dirichlet(const fvm::Grid1D<T>& g, utils::Matrix<T>& A, utils::Vector<T>& b, const utils::Vector<T>& s, const T& c){
|
||||
|
||||
A(0,0) = -((c/(g.centers[1] - g.centers[0])) + (c/(g.centers[0] - g.vertices[0])));
|
||||
A(0,1) = c/(g.centers[1] - g.centers[0]);
|
||||
|
||||
A(g.center_idx, g.center_idx-1) = c/(g.centers[g.center_idx]-g.centers[g.center_idx-1]);
|
||||
A(g.center_idx, g.center_idx) = -((c/(g.vertices[g.vertices_idx] - g.centers[g.center_idx])) + (c/(g.centers[g.center_idx] - g.centers[g.center_idx-1])));
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void inplace_BC_Neumann(const fvm::Grid1D<T>& g, utils::Matrix<T>& A, const T& c){
|
||||
|
||||
A(0,0) = -c/(g.centers[1]-g.centers[0]);
|
||||
A(0,1) = c/(g.centers[1]-g.centers[0]);
|
||||
|
||||
A(g.center_idx, g.center_idx-1) = c/(g.centers[g.center_idx]-g.centers[g.center_idx-1]);
|
||||
A(g.center_idx, g.center_idx) = -c/(g.centers[g.center_idx]-g.centers[g.center_idx-1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
129
include/modules/fluids/diffusion1d.h
Normal file
129
include/modules/fluids/diffusion1d.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
|
||||
#include "modules/mesh/mesh1d.h"
|
||||
#include "core/global_config.h"
|
||||
#include "utils/matrix.h"
|
||||
#include "utils/vector.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace fluids {
|
||||
|
||||
template <typename T>
|
||||
struct Diffusion1D{
|
||||
const core::Configs<T>& cfg;
|
||||
const mesh::Mesh1D<T>& mesh;
|
||||
T Gamma{1};
|
||||
|
||||
|
||||
|
||||
// Constructor
|
||||
Diffusion1D(const core::Configs<T>& configs, const mesh::Mesh1D<T>& Mesh, T Gamma_const=T(1)): cfg(configs), mesh(Mesh), Gamma(Gamma_const) {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void assemble(utils::Matrix<T>& A, utils::Vector<T>& b, utils::Vector<T>& s){
|
||||
|
||||
uint64_t N = mesh.center_idx + 1;
|
||||
|
||||
if (N < 3){
|
||||
throw std::runtime_error("Diffusion1D: need N>=3");
|
||||
}
|
||||
if (A.rows() != N || A.cols() != N){
|
||||
A = utils::Matrix<T>(N, N, T(0));
|
||||
}
|
||||
if (b.size() != N){
|
||||
b = utils::Vector<T>(N, T(0));
|
||||
}
|
||||
|
||||
|
||||
if (cfg.grid == core::GridKind::Uniform){
|
||||
// Core of A
|
||||
if (cfg.fd == core::FDKind::Central){
|
||||
uniform_central_finite_diffrence_2_order(A,b,s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Left BC of A
|
||||
if (cfg.left.kind == core::BCKind::Dirichlet){
|
||||
BC_uniform_backward_finite_diffrence_2_order_Dirichlet(A,b,s);
|
||||
}else if (cfg.left.kind == core::BCKind::Neumann){
|
||||
BC_uniform_backward_finite_diffrence_2_order_Neumann(A,b,s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uniform_central_finite_diffrence_2_order(utils::Matrix<T>& A, utils::Vector<T>& b, utils::Vector<T>& s){
|
||||
T xm, xc, xp;
|
||||
|
||||
for (uint64_t i = 1; i < mesh.center_idx; ++i){
|
||||
xm = mesh.center(i-1);
|
||||
xc = mesh.center(i);
|
||||
xp = mesh.center(i+1);
|
||||
|
||||
A(i, i-1) = Gamma/(xc - xm);
|
||||
A(i, i) = -((Gamma/(xp - xc)) + (Gamma/(xc - xm)));
|
||||
A(i, i+1) = Gamma/(xp - xc);
|
||||
|
||||
b[i] = -s[i]*mesh.dx(i);
|
||||
}
|
||||
}
|
||||
|
||||
void BC_uniform_backward_finite_diffrence_2_order_Dirichlet(utils::Matrix<T>& A, utils::Vector<T>& b, utils::Vector<T>& s){
|
||||
T xm;
|
||||
T xw = mesh.vertice(0);
|
||||
T xc = mesh.center(0);
|
||||
T xp = mesh.center(1);
|
||||
T xe;
|
||||
uint64_t N = mesh.center_idx;
|
||||
|
||||
A(0, 0) = -((Gamma/(xp - xc)) + (Gamma/(xc - xw)));
|
||||
A(0, 1) = Gamma/(xp - xc);
|
||||
|
||||
b[0] = -s[0]*mesh.dx(0) - Gamma*(cfg.left.value/(xc - xw));
|
||||
|
||||
xm = mesh.center(N-1);
|
||||
xc = mesh.center(N);
|
||||
xe = mesh.vertice(N+1);
|
||||
|
||||
A(N, N-1) = Gamma/(xc - xm);
|
||||
A(N, N) = -((Gamma/(xe - xc)) + (Gamma/(xc - xm)));
|
||||
|
||||
b[N] = -s[N]*mesh.dx(N) - Gamma*(cfg.right.value/(xe - xc));
|
||||
A.print();
|
||||
b.print();
|
||||
}
|
||||
|
||||
void BC_uniform_backward_finite_diffrence_2_order_Neumann(utils::Matrix<T>& A, utils::Vector<T>& b, utils::Vector<T>& s){
|
||||
T xm;
|
||||
T xc = mesh.center(0);
|
||||
T xp = mesh.center(1);
|
||||
|
||||
uint64_t N = mesh.center_idx;
|
||||
|
||||
A(0, 0) = -Gamma/(xp - xc);
|
||||
A(0, 1) = Gamma/(xp - xc);
|
||||
|
||||
b[0] = -s[0]*mesh.dx(0) - (Gamma*cfg.left.value);
|
||||
|
||||
xm = mesh.center(N-1);
|
||||
xc = mesh.center(N);
|
||||
|
||||
A(N, N-1) = Gamma/(xc - xm);
|
||||
A(N, N) = -Gamma/(xc - xm);
|
||||
|
||||
b[N] = -s[N]*mesh.dx(N) - Gamma*(cfg.right.value);
|
||||
|
||||
A.print();
|
||||
b.print();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // end namespace fluids
|
||||
5
include/modules/fluids/fluids.h
Normal file
5
include/modules/fluids/fluids.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "modules/fluids/diffusion1d.h"
|
||||
|
||||
|
||||
4
include/modules/mesh/mesh.h
Normal file
4
include/modules/mesh/mesh.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include "modules/mesh/mesh1d.h"
|
||||
|
||||
42
include/modules/mesh/mesh1d.h
Normal file
42
include/modules/mesh/mesh1d.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/vector.h"
|
||||
|
||||
namespace mesh {
|
||||
|
||||
template <typename T>
|
||||
struct Mesh1D{
|
||||
uint64_t center_idx; // max cell index
|
||||
uint64_t vertices_idx; // max vertice index
|
||||
utils::Vector<T> centers; // size N (unknowns at cell centers)
|
||||
utils::Vector<T> vertices; // size N+1 (face positions)
|
||||
|
||||
Mesh1D() = default;
|
||||
|
||||
explicit Mesh1D(const utils::Vector<T>& midpoints){
|
||||
centers = midpoints;
|
||||
center_idx = centers.size()-1;
|
||||
vertices_idx = centers.size();
|
||||
}
|
||||
|
||||
void generate_vertices(T left, T right){
|
||||
vertices.resize(vertices_idx+1);
|
||||
vertices[0] = left;
|
||||
vertices[vertices_idx] = right;
|
||||
for (uint64_t i = 1; i < center_idx+1; ++i){
|
||||
vertices[i] = (centers[i-1] + centers[i])*0.5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
T dx(uint64_t i) const { check(i); return vertices[i+1] - vertices[i]; }
|
||||
T center(uint64_t i) const { check(i); return centers[i]; }
|
||||
T vertice(uint64_t i) const {; return vertices[i]; }
|
||||
|
||||
void check(uint64_t i) const {
|
||||
if (i > center_idx) throw std::runtime_error("Mesh1D: cell index out of range");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mesh
|
||||
28
include/modules/neural_networks/activation_functions/ReLU.h
Normal file
28
include/modules/neural_networks/activation_functions/ReLU.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/matrix.h"
|
||||
#include "./utils/random.h"
|
||||
|
||||
|
||||
namespace neural_networks{
|
||||
|
||||
template <typename T>
|
||||
struct activation_ReLU{
|
||||
|
||||
utils::Matrix<T> outputs;
|
||||
|
||||
void forward(utils::Matrix<T> inputs){
|
||||
outputs = numerics::max(inputs, T{0});
|
||||
//outputs.print();
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace neural_networks
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/matrix.h"
|
||||
|
||||
#include "./numerics/max.h"
|
||||
#include "./numerics/matsubtract.h"
|
||||
#include "./numerics/exponential.h"
|
||||
#include "./numerics/matdiv.h"
|
||||
|
||||
|
||||
namespace neural_networks{
|
||||
|
||||
template <typename T>
|
||||
struct activation_softmax{
|
||||
|
||||
utils::Matrix<T> exp_values;
|
||||
utils::Matrix<T> probabilities;
|
||||
utils::Matrix<T> outputs;
|
||||
|
||||
void forward(const utils::Matrix<T> inputs){
|
||||
|
||||
|
||||
exp_values = numerics::exponential(numerics::matsubtract(inputs, numerics::max(inputs, "rows"), "col"));
|
||||
probabilities = numerics::matdiv(exp_values, numerics::matsum(exp_values, "col"), "col");
|
||||
|
||||
outputs = probabilities;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace neural_networks
|
||||
42
include/modules/neural_networks/datasets/spiral.h
Normal file
42
include/modules/neural_networks/datasets/spiral.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
#include "./utils/matrix.h"
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/random.h"
|
||||
|
||||
//#include <math.h>
|
||||
|
||||
|
||||
namespace neural_networks{
|
||||
|
||||
template <typename TX, typename Ty>
|
||||
void create_spital_data(const uint64_t samples, const uint64_t classes, utils::Matrix<TX>& X, utils::Vector<Ty>& y) {
|
||||
|
||||
const uint64_t rows = samples*classes;
|
||||
TX r, t;
|
||||
uint64_t row_idx;
|
||||
|
||||
|
||||
if ((rows != X.rows()) || (X.cols() != 2)){
|
||||
X.resize(samples*classes, 2);
|
||||
}
|
||||
if (rows != y.size()){
|
||||
y.resize(rows);
|
||||
}
|
||||
|
||||
for (uint64_t i = 0; i < classes; ++i){
|
||||
for (uint64_t j = 0; j < samples; ++j){
|
||||
r = static_cast<TX>(j)/static_cast<TX>(samples);
|
||||
t = static_cast<TX>(i)*4.0 + (4.0+r);
|
||||
row_idx = (i*samples) + j;
|
||||
|
||||
X(row_idx, 0) = r*std::cos(t*2.5) + utils::random(TX{-0.15}, TX{0.15});
|
||||
X(row_idx, 1) = r*std::sin(t*2.5) + utils::random(TX{-0.15}, TX{0.15});
|
||||
y[row_idx] = static_cast<Ty>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namesoace NN
|
||||
42
include/modules/neural_networks/layers/dense_layer.h
Normal file
42
include/modules/neural_networks/layers/dense_layer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/matrix.h"
|
||||
#include "./utils/random.h"
|
||||
|
||||
|
||||
namespace neural_networks{
|
||||
|
||||
template <typename T>
|
||||
struct dense_layer{
|
||||
utils::Matrix<T> weights;
|
||||
utils::Vector<T> biases;
|
||||
utils::Matrix<T> outputs;
|
||||
|
||||
// Default Constructor
|
||||
dense_layer() = default;
|
||||
|
||||
// Constructor
|
||||
dense_layer(const uint64_t n_inputs, const uint64_t n_neurons){
|
||||
|
||||
weights.random(n_inputs, n_neurons, -1, 1);
|
||||
biases.resize(n_neurons, T{0});
|
||||
//weights.print();
|
||||
//outputs.resize()
|
||||
|
||||
}
|
||||
|
||||
|
||||
void forward(utils::Matrix<T> inputs){
|
||||
outputs = numerics::matadd(numerics::matmul_auto(inputs, (weights)), biases, "row");
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace neural_networks
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/matrix.h"
|
||||
|
||||
|
||||
namespace neural_networks{
|
||||
|
||||
template <typename Td, typename Ti>
|
||||
struct Loss{
|
||||
|
||||
utils::Matrix<Td> sample_losses;
|
||||
Td data_losses;
|
||||
|
||||
virtual utils::Vector<Td> forward(const utils::Matrix<Td>& output, const utils::Matrix<Ti>& y) = 0;
|
||||
|
||||
Td calculate(const utils::Matrix<Td>& output, const utils::Matrix<Ti>& y){
|
||||
// Calculate sample losses
|
||||
sample_losses = forward(output, y);
|
||||
|
||||
// Calculate mean loss
|
||||
data_losses = numerics::mean(sample_losses);
|
||||
return data_losses;
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace neural_networks
|
||||
34
include/modules/neural_networks/loss/loss.h
Normal file
34
include/modules/neural_networks/loss/loss.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/matrix.h"
|
||||
|
||||
|
||||
namespace neural_networks{
|
||||
|
||||
template <typename Td, typename Ti>
|
||||
struct Loss{
|
||||
|
||||
utils::Matrix<Td> sample_losses;
|
||||
Td data_losses;
|
||||
|
||||
virtual utils::Vector<Td> forward(const utils::Matrix<Td>& output, const utils::Matrix<Ti>& y) = 0;
|
||||
|
||||
Td calculate(const utils::Matrix<Td>& output, const utils::Matrix<Ti>& y){
|
||||
// Calculate sample losses
|
||||
sample_losses = forward(output, y);
|
||||
|
||||
// Calculate mean loss
|
||||
data_losses = numerics::mean(sample_losses);
|
||||
return data_losses;
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace neural_networks
|
||||
12
include/modules/neural_networks/neural_networks.h
Normal file
12
include/modules/neural_networks/neural_networks.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// #include "./modules/neural_networks/neural_networks.h"
|
||||
#pragma once
|
||||
|
||||
#include "datasets/spiral.h"
|
||||
|
||||
#include "layers/dense_layer.h"
|
||||
|
||||
|
||||
#include "activation_functions/ReLU.h"
|
||||
#include "activation_functions/Softmax.h"
|
||||
|
||||
#include "loss/loss.h"
|
||||
Reference in New Issue
Block a user