using Elsheimy.Components.Linears;
private Random _radomObj;
public int SynapseMatrixColumns { get; }
public int SynapseMatrixLines { get; }
public double[,] SynapsesMatrix { get; private set; }
public NeuralNetWork(int synapseMatrixColumns, int synapseMatrixLines)
SynapseMatrixColumns = synapseMatrixColumns;
SynapseMatrixLines = synapseMatrixLines;
_radomObj = new Random(1);
_GenerateSynapsesMatrix();
private void _GenerateSynapsesMatrix()
SynapsesMatrix = new double[SynapseMatrixLines, SynapseMatrixColumns];
for (var i = 0; i < SynapseMatrixLines; i++)
for (var j = 0; j < SynapseMatrixColumns; j++)
SynapsesMatrix[i, j] = (2 * _radomObj.NextDouble()) - 1;
private double[,] _CalculateSigmoid(double[,] matrix)
int rowLength = matrix.GetLength(0);
int colLength = matrix.GetLength(1);
for (int i = 0; i < rowLength; i++)
for (int j = 0; j < colLength; j++)
var value = matrix[i, j];
matrix[i, j] = 1 / (1 + Math.Exp(value * -1));
private double[,] _CalculateSigmoidDerivative(double[,] matrix)
int rowLength = matrix.GetLength(0);
int colLength = matrix.GetLength(1);
for (int i = 0; i < rowLength; i++)
for (int j = 0; j < colLength; j++)
var value = matrix[i, j];
matrix[i, j] = value * (1 - value);
public static double[,] MatrixProduct(double[,] matrix1, double[,] matrix2) {
var matrix1Rows = matrix1.GetLength(0);
var matrix1Cols = matrix1.GetLength(1);
var matrix2Rows = matrix2.GetLength(0);
var matrix2Cols = matrix2.GetLength(1);
if (matrix1Cols != matrix2Rows)
throw new InvalidOperationException
("Product is undefined. n columns of first matrix must equal to n rows of second matrix");
double[,] product = new double[matrix1Rows, matrix2Cols];
for (int matrix1_row = 0; matrix1_row < matrix1Rows; matrix1_row++) {
for (int matrix2_col = 0; matrix2_col < matrix2Cols; matrix2_col++) {
for (int matrix1_col = 0; matrix1_col < matrix1Cols; matrix1_col++) {
product[matrix1_row, matrix2_col] +=
matrix1[matrix1_row, matrix1_col] *
matrix2[matrix1_col, matrix2_col];
public double[,] Think(double[,] inputMatrix)
var productOfTheInputsAndWeights = MatrixDotProduct(inputMatrix, SynapsesMatrix);
return _CalculateSigmoid(productOfTheInputsAndWeights);
public void Train(double[,] trainInputMatrix,double[,] trainOutputMatrix,int interactions)
for (var i = 0; i < interactions; i++)
var output = Think(trainInputMatrix);
var error = MatrixSubstract(trainOutputMatrix, output);
var curSigmoidDerivative = _CalculateSigmoidDerivative(output);
var error_SigmoidDerivative = MatrixProduct(error, curSigmoidDerivative);
var adjustment = MatrixDotProduct(MatrixTranspose(trainInputMatrix), error_SigmoidDerivative);
SynapsesMatrix = MatrixSum(SynapsesMatrix, adjustment);
static void PrintMatrix(double[,] matrix)
int rowLength = matrix.GetLength(0);
int colLength = matrix.GetLength(1);
for (int i = 0; i < rowLength; i++)
for (int j = 0; j < colLength; j++)
Console.Write(string.Format("{0} ", matrix[i, j]));
Console.Write(Environment.NewLine);
static void Main(string[] args)
var curNeuralNetwork = new NeuralNetWork(1, 3);
Console.WriteLine("Synaptic weights before training:");
PrintMatrix(curNeuralNetwork.SynapsesMatrix);
var trainingInputs = new double[,] { { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 0, 1, 1 } };
var trainingOutputs = NeuralNetWork.MatrixTranspose(new double[,] { { 0, 1, 1, 0 } });
curNeuralNetwork.Train(trainingInputs, trainingOutputs, 10000);
Console.WriteLine("\nSynaptic weights after training:");
PrintMatrix(curNeuralNetwork.SynapsesMatrix);
var output = curNeuralNetwork.Think(new double[,] { { 1, 0, 0 } });
Console.WriteLine("\nConsidering new problem [1, 0, 0] => :");