From 4873db6fb7b546f6ba04454b6ca96ee1d1a67e53 Mon Sep 17 00:00:00 2001 From: Scott Seto Date: Sun, 31 Mar 2024 19:57:41 -0400 Subject: [PATCH] Add VNN Operations. --- README.md | 24 + .../RMAD/VectorAttentionOperation.cs | 1 - ...kg => ParallelReverseAutoDiff.1.2.0.nupkg} | Bin 327928 -> 343865 bytes src/ParallelReverseAutoDiff.nuspec | 4 +- src/RMAD/ElementwiseSquareOperation.cs | 85 +++ src/RMAD/ElementwiseVectorAddOperation.cs | 122 ++++ ...ntwiseVectorCartesianSummationOperation.cs | 222 +++++++ ...twiseVectorConstituentMultiplyOperation.cs | 343 ++++++++++ ...ElementwiseVectorDecompositionOperation.cs | 614 ++++++++++++++++++ ...entwiseVectorMiniDecompositionOperation.cs | 394 +++++++++++ src/RMAD/PairwiseSineSoftmaxOperation.cs | 117 ++++ src/RMAD/VectorAttentionBinaryOperation.cs | 110 ++++ src/RMAD/VectorAttentionOperation.cs | 99 +++ src/RMAD/VectorizeOperation.cs | 139 ++++ src/docs/README.md | 26 + 15 files changed, 2297 insertions(+), 3 deletions(-) rename src/{ParallelReverseAutoDiff.1.1.65.nupkg => ParallelReverseAutoDiff.1.2.0.nupkg} (59%) create mode 100644 src/RMAD/ElementwiseSquareOperation.cs create mode 100644 src/RMAD/ElementwiseVectorAddOperation.cs create mode 100644 src/RMAD/ElementwiseVectorCartesianSummationOperation.cs create mode 100644 src/RMAD/ElementwiseVectorConstituentMultiplyOperation.cs create mode 100644 src/RMAD/ElementwiseVectorDecompositionOperation.cs create mode 100644 src/RMAD/ElementwiseVectorMiniDecompositionOperation.cs create mode 100644 src/RMAD/PairwiseSineSoftmaxOperation.cs create mode 100644 src/RMAD/VectorAttentionBinaryOperation.cs create mode 100644 src/RMAD/VectorAttentionOperation.cs create mode 100644 src/RMAD/VectorizeOperation.cs diff --git a/README.md b/README.md index 6930af07..e9c9db3f 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,30 @@ DeepScaleAndShiftOperation FlattenOperation +### Vector Neural Network (VNN) Operations +These types of operations typically operate on instances of the Matrix class where the left half are magnitudes and the right half are angles in radians. +Learn more about Vector Neural Networks [here](https://www.amazon.com/Vector-Neural-Networks-Geometric-Tensors-ebook/dp/B0CXBV3DY5/ref=sr_1_1). + +ElementwiseSquareOperation + +ElementwiseVectorAddOperation + +ElementwiseVectorCartesianSummationOperation + +ElementwiseVectorConstituentMultiplyOperation + +ElementwiseVectorDecompositionOperation + +ElementwiseVectorMiniDecompositionOperation + +PairwiseSineSoftmaxOperation + +VectorAttentionBinaryOperation + +VectorAttentionOperation + +VectorizeOperation + ### Neural Network Parameters Each neural network base class has a set of parameters that can be used to configure the neural network. They are as follows: diff --git a/examples/gravnet/ParallelReverseAutoDiff.GravNetExample/VectorNetwork/RMAD/VectorAttentionOperation.cs b/examples/gravnet/ParallelReverseAutoDiff.GravNetExample/VectorNetwork/RMAD/VectorAttentionOperation.cs index a3c2301b..a1da82e8 100644 --- a/examples/gravnet/ParallelReverseAutoDiff.GravNetExample/VectorNetwork/RMAD/VectorAttentionOperation.cs +++ b/examples/gravnet/ParallelReverseAutoDiff.GravNetExample/VectorNetwork/RMAD/VectorAttentionOperation.cs @@ -95,6 +95,5 @@ public override BackwardResult Backward(Matrix dOutput) .AddInputGradient(dProbabilities) .Build(); } - } } diff --git a/src/ParallelReverseAutoDiff.1.1.65.nupkg b/src/ParallelReverseAutoDiff.1.2.0.nupkg similarity index 59% rename from src/ParallelReverseAutoDiff.1.1.65.nupkg rename to src/ParallelReverseAutoDiff.1.2.0.nupkg index e1dba2e8ac88fa6a09c9a0fa13d48969255e73fd..e3439894b9fa826fab1bb3d5c7ee657db6839a3c 100644 GIT binary patch delta 142037 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ⅆxRUmxQ}de*>|Nfn}03c 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

GX5oyJZxQX{-u5NjdcC*gGT2h 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

?HlorMW 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 b^uJ3JC0V#P7yXlXh)~vV4r>*Hd+YrliWhzc delta 126050 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%0D?X= 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 diff --git a/src/ParallelReverseAutoDiff.nuspec b/src/ParallelReverseAutoDiff.nuspec index 1be4d04f..08448961 100644 --- a/src/ParallelReverseAutoDiff.nuspec +++ b/src/ParallelReverseAutoDiff.nuspec @@ -2,7 +2,7 @@ ParallelReverseAutoDiff - 1.1.65 + 1.2.0 ameritusweb ameritusweb LGPL-2.1-only @@ -11,7 +11,7 @@ false A library for parallelized reverse mode automatic differentiation in C# for custom neural network development. - Fix GPU Matrix Multiply. + Add VNN Operations. ameritusweb, 2024 autodiff automatic-differentiation parallel reverse-mode differentiation C# neural network diff --git a/src/RMAD/ElementwiseSquareOperation.cs b/src/RMAD/ElementwiseSquareOperation.cs new file mode 100644 index 00000000..21587629 --- /dev/null +++ b/src/RMAD/ElementwiseSquareOperation.cs @@ -0,0 +1,85 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + + ///

+ /// Performs the forward and backward operations for the element-wise square function. + /// + public class ElementwiseSquareOperation : Operation + { + private Matrix input; + + /// + /// A common factory method for instantiating this operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new ElementwiseSquareOperation(); + } + + /// + public override void Store(Guid id) + { + this.IntermediateMatrices.AddOrUpdate(id, this.input, (x, y) => this.input); + } + + /// + public override void Restore(Guid id) + { + this.input = this.IntermediateMatrices[id]; + } + + /// + /// Performs the forward operation for the element-wise square function. + /// + /// The input to the element-wise square operation. + /// The output of the element-wise square operation. + public Matrix Forward(Matrix input) + { + this.input = input; + int rows = input.Length; + int cols = input[0].Length; + this.Output = new Matrix(rows, cols); + + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < cols; j++) + { + double x = input[i][j]; + this.Output[i][j] = x * x; + } + } + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dLdOutput) + { + int rows = dLdOutput.Length; + int cols = dLdOutput[0].Length; + Matrix dLdInput = new Matrix(rows, cols); + + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < cols; j++) + { + double x = this.input[i][j]; + double gradient = 2 * x; + dLdInput[i][j] = dLdOutput[i][j] * gradient; + } + } + + return new BackwardResultBuilder() + .AddInputGradient(dLdInput) + .Build(); + } + } +} diff --git a/src/RMAD/ElementwiseVectorAddOperation.cs b/src/RMAD/ElementwiseVectorAddOperation.cs new file mode 100644 index 00000000..d5adbd75 --- /dev/null +++ b/src/RMAD/ElementwiseVectorAddOperation.cs @@ -0,0 +1,122 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Threading.Tasks; + + /// + /// Element-wise add operation. + /// + public class ElementwiseVectorAddOperation : Operation + { + private Matrix input1; + private Matrix input2; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new ElementwiseVectorAddOperation(); + } + + /// + /// Performs the forward operation for the element-wise vector summation function. + /// + /// The first input to the element-wise vector summation operation. + /// The second input to the element-wise vector summation operation. + /// The output of the element-wise vector summation operation. + public Matrix Forward(Matrix input1, Matrix input2) + { + this.input1 = input1; + this.input2 = input2; + + this.Output = new Matrix(this.input1.Rows, this.input1.Cols); + Parallel.For(0, input1.Rows, i => + { + for (int j = 0; j < input1.Cols / 2; j++) + { + // Accessing the magnitudes and angles from the concatenated matrices + double magnitude = input1[i, j]; + double angle = input1[i, j + (input1.Cols / 2)]; + + double wMagnitude = input2[i, j]; + double wAngle = input2[i, j + (input2.Cols / 2)]; + + // Compute vector components + double x1 = magnitude * Math.Cos(angle); + double y1 = magnitude * Math.Sin(angle); + double x2 = wMagnitude * Math.Cos(wAngle); + double y2 = wMagnitude * Math.Sin(wAngle); + + double sumx = x1 + x2; + double sumy = y1 + y2; + + // Compute resultant vector magnitude and angle + double resultMagnitude = Math.Sqrt((sumx * sumx) + (sumy * sumy)); + double resultAngle = Math.Atan2(sumy, sumx); + + this.Output[i, j] = resultMagnitude; + this.Output[i, j + (this.input1.Cols / 2)] = resultAngle; + } + }); + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + Matrix dInput1 = new Matrix(this.input1.Rows, this.input1.Cols); + Matrix dInput2 = new Matrix(this.input2.Rows, this.input2.Cols); + + Parallel.For(0, this.input1.Rows, i => + { + for (int j = 0; j < this.input1.Cols / 2; j++) + { + var magnitude = this.input1[i, j]; + var angle = this.input1[i, j + (this.input1.Cols / 2)]; + var wMagnitude = this.input2[i, j]; + var wAngle = this.input2[i, j + (this.input2.Cols / 2)]; + + var x1 = magnitude * Math.Cos(angle); + var y1 = magnitude * Math.Sin(angle); + var x2 = wMagnitude * Math.Cos(wAngle); + var y2 = wMagnitude * Math.Sin(wAngle); + + var combinedX = x1 + x2; + var combinedY = y1 + y2; + + // Compute gradients for magnitude and angle + double dResultMagnitude_dX = combinedX / this.Output[i, j]; + double dResultMagnitude_dY = combinedY / this.Output[i, j]; + + double dResultAngle_dX = -combinedY / ((combinedX * combinedX) + (combinedY * combinedY)); + double dResultAngle_dY = combinedX / ((combinedX * combinedX) + (combinedY * combinedY)); + + // Chain rule to compute gradients for input vectors + dInput1[i, j] = (dOutput[i, j] * dResultMagnitude_dX * Math.Cos(angle)) + + (dOutput[i, j + (this.input1.Cols / 2)] * dResultAngle_dX * -Math.Sin(angle)); + dInput1[i, j + (this.input1.Cols / 2)] = (dOutput[i, j] * dResultMagnitude_dY * Math.Sin(angle)) + + (dOutput[i, j + (this.input1.Cols / 2)] * dResultAngle_dY * Math.Cos(angle)); + + dInput2[i, j] = (dOutput[i, j] * dResultMagnitude_dX * Math.Cos(wAngle)) + + (dOutput[i, j + (this.input2.Cols / 2)] * dResultAngle_dX * -Math.Sin(wAngle)); + dInput2[i, j + (this.input2.Cols / 2)] = (dOutput[i, j] * dResultMagnitude_dY * Math.Sin(wAngle)) + + (dOutput[i, j + (this.input2.Cols / 2)] * dResultAngle_dY * Math.Cos(wAngle)); + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dInput1) + .AddInputGradient(dInput2) + .Build(); + } + } +} diff --git a/src/RMAD/ElementwiseVectorCartesianSummationOperation.cs b/src/RMAD/ElementwiseVectorCartesianSummationOperation.cs new file mode 100644 index 00000000..e15dd749 --- /dev/null +++ b/src/RMAD/ElementwiseVectorCartesianSummationOperation.cs @@ -0,0 +1,222 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Linq; + using System.Threading.Tasks; + + /// + /// Element-wise cartesian summation operation. + /// + public class ElementwiseVectorCartesianSummationOperation : Operation + { + private Matrix input1; + private Matrix input2; + private Matrix weights; + private double[] summationX; + private double[] summationY; + private CalculatedValues[,] calculatedValues; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new ElementwiseVectorCartesianSummationOperation(); + } + + /// + /// Performs the forward operation for the element-wise vector summation function. + /// + /// The first input to the element-wise vector summation operation. + /// The second input to the element-wise vector summation operation. + /// The weights. + /// The output of the element-wise vector summation operation. + public Matrix Forward(Matrix input1, Matrix input2, Matrix weights) + { + this.input1 = input1; + this.input2 = input2; + this.weights = weights; + + this.Output = new Matrix(1, 2); + + this.calculatedValues = new CalculatedValues[this.input1.Rows, this.input1.Cols / 2]; + + double[] summationX = new double[input1.Rows]; + double[] summationY = new double[input1.Rows]; + double[,] resultVectors = new double[input1.Rows * (input1.Cols / 2), 2]; + Parallel.For(0, input1.Rows, i => + { + double sumX = 0.0d; + double sumY = 0.0d; + (double, double)[] resultMagnitudes = new (double, double)[input1.Cols / 2]; + for (int j = 0; j < (input1.Cols / 2); j++) + { + // Accessing the magnitudes and angles from the concatenated matrices + double magnitude = input1[i, j]; + double angle = input1[i, j + (input1.Cols / 2)]; + + double wMagnitude = input2[i, j]; + double wAngle = input2[i, j + (input2.Cols / 2)]; + + // Compute vector components + double x1 = magnitude * Math.Cos(angle); + double y1 = magnitude * Math.Sin(angle); + double x2 = wMagnitude * Math.Cos(wAngle); + double y2 = wMagnitude * Math.Sin(wAngle); + + double sumx = x1 + x2; + double sumy = y1 + y2; + + double dsumx_dAngle = -magnitude * Math.Sin(angle); + double dsumx_dWAngle = -wMagnitude * Math.Sin(wAngle); + double dsumy_dAngle = magnitude * Math.Cos(angle); + double dsumy_dWAngle = wMagnitude * Math.Cos(wAngle); + double dsumx_dMagnitude = Math.Cos(angle); + double dsumx_dWMagnitude = Math.Cos(wAngle); + double dsumy_dMagnitude = Math.Sin(angle); + double dsumy_dWMagnitude = Math.Sin(wAngle); + + // Compute resultant vector magnitude and angle + double resultMagnitude = Math.Sqrt((sumx * sumx) + (sumy * sumy)) * weights[i, j]; + double resultAngle = Math.Atan2(sumy, sumx); + + double dResultMagnitude_dsumx = (sumx * weights[i, j]) / Math.Sqrt((sumx * sumx) + (sumy * sumy)); + double dResultMagnitude_dsumy = (sumy * weights[i, j]) / Math.Sqrt((sumx * sumx) + (sumy * sumy)); + double dResultAngle_dsumx = -sumy / ((sumx * sumx) + (sumy * sumy)); + double dResultAngle_dsumy = sumx / ((sumx * sumx) + (sumy * sumy)); + + double dResultMagnitude_dAngle = (dResultMagnitude_dsumx * dsumx_dAngle) + (dResultMagnitude_dsumy * dsumy_dAngle); + double dResultMagnitude_dWAngle = (dResultMagnitude_dsumx * dsumx_dWAngle) + (dResultMagnitude_dsumy * dsumy_dWAngle); + double dResultAngle_dAngle = (dResultAngle_dsumx * dsumx_dAngle) + (dResultAngle_dsumy * dsumy_dAngle); + double dResultAngle_dWAngle = (dResultAngle_dsumx * dsumx_dWAngle) + (dResultAngle_dsumy * dsumy_dWAngle); + + double dResultMagnitude_dMagnitude = (dResultMagnitude_dsumx * dsumx_dMagnitude) + (dResultMagnitude_dsumy * dsumy_dMagnitude); + double dResultMagnitude_dWMagnitude = (dResultMagnitude_dsumx * dsumx_dWMagnitude) + (dResultMagnitude_dsumy * dsumy_dWMagnitude); + double dResultAngle_dMagnitude = (dResultAngle_dsumx * dsumx_dMagnitude) + (dResultAngle_dsumy * dsumy_dMagnitude); + double dResultAngle_dWMagnitude = (dResultAngle_dsumx * dsumx_dWMagnitude) + (dResultAngle_dsumy * dsumy_dWMagnitude); + + resultVectors[(i * (input1.Cols / 2)) + j, 0] = resultMagnitude; + resultVectors[(i * (input1.Cols / 2)) + j, 1] = resultAngle; + + double localSumX = resultMagnitude * Math.Cos(resultAngle); + double localSumY = resultMagnitude * Math.Sin(resultAngle); + + double localSumXFull = Math.Sqrt((sumx * sumx) + (sumy * sumy)) * weights[i, j] * Math.Cos(resultAngle); + double localSumYFull = Math.Sqrt((sumx * sumx) + (sumy * sumy)) * weights[i, j] * Math.Sin(resultAngle); + + double dLocalSumX_dWeight = Math.Sqrt((sumx * sumx) + (sumy * sumy)) * Math.Cos(resultAngle); + double dLocalSumY_dWeight = Math.Sqrt((sumx * sumx) + (sumy * sumy)) * Math.Sin(resultAngle); + + this.calculatedValues[i, j].DLocalSumX_DWeight = dLocalSumX_dWeight; + this.calculatedValues[i, j].DLocalSumY_DWeight = dLocalSumY_dWeight; + + double dLocalSumX_dResultMagnitude = Math.Cos(resultAngle); + double dLocalSumX_dResultAngle = -resultMagnitude * Math.Sin(resultAngle); + + double dLocalSumX_dAngle = (dLocalSumX_dResultMagnitude * dResultMagnitude_dAngle) + (dLocalSumX_dResultAngle * dResultAngle_dAngle); + double dLocalSumX_dWAngle = (dLocalSumX_dResultMagnitude * dResultMagnitude_dWAngle) + (dLocalSumX_dResultAngle * dResultAngle_dWAngle); + double dLocalSumX_dMagnitude = (dLocalSumX_dResultMagnitude * dResultMagnitude_dMagnitude) + (dLocalSumX_dResultAngle * dResultAngle_dMagnitude); + double dLocalSumX_dWMagnitude = (dLocalSumX_dResultMagnitude * dResultMagnitude_dWMagnitude) + (dLocalSumX_dResultAngle * dResultAngle_dWMagnitude); + + this.calculatedValues[i, j].DLocalSumX_DAngle = dLocalSumX_dAngle; + this.calculatedValues[i, j].DLocalSumX_DWAngle = dLocalSumX_dWAngle; + this.calculatedValues[i, j].DLocalSumX_DMagnitude = dLocalSumX_dMagnitude; + this.calculatedValues[i, j].DLocalSumX_DWMagnitude = dLocalSumX_dWMagnitude; + + double dLocalSumY_dResultMagnitude = Math.Sin(resultAngle); + double dLocalSumY_dResultAngle = resultMagnitude * Math.Cos(resultAngle); + + double dLocalSumY_dAngle = (dLocalSumY_dResultMagnitude * dResultMagnitude_dAngle) + (dLocalSumY_dResultAngle * dResultAngle_dAngle); + double dLocalSumY_dWAngle = (dLocalSumY_dResultMagnitude * dResultMagnitude_dWAngle) + (dLocalSumY_dResultAngle * dResultAngle_dWAngle); + double dLocalSumY_dMagnitude = (dLocalSumY_dResultMagnitude * dResultMagnitude_dMagnitude) + (dLocalSumY_dResultAngle * dResultAngle_dMagnitude); + double dLocalSumY_dWMagnitude = (dLocalSumY_dResultMagnitude * dResultMagnitude_dWMagnitude) + (dLocalSumY_dResultAngle * dResultAngle_dWMagnitude); + + this.calculatedValues[i, j].DLocalSumY_DAngle = dLocalSumY_dAngle; + this.calculatedValues[i, j].DLocalSumY_DWAngle = dLocalSumY_dWAngle; + this.calculatedValues[i, j].DLocalSumY_DMagnitude = dLocalSumY_dMagnitude; + this.calculatedValues[i, j].DLocalSumY_DWMagnitude = dLocalSumY_dWMagnitude; + + sumX += localSumX; + sumY += localSumY; + } + + summationX[i] = sumX; + summationY[i] = sumY; + }); + + this.summationX = summationX; + this.summationY = summationY; + + this.Output[0, 0] = this.summationX.Sum(); + this.Output[0, 1] = this.summationY.Sum(); + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + Matrix dInput1 = new Matrix(this.input1.Rows, this.input1.Cols); + Matrix dInput2 = new Matrix(this.input2.Rows, this.input2.Cols); + Matrix dWeights = new Matrix(this.weights.Rows, this.weights.Cols); + + double dSummationXOutput = dOutput[0, 0]; // Gradient of the loss function with respect to the output X + double dSummationYOutput = dOutput[0, 1]; // Gradient of the loss function with respect to the output Y + + // Updating gradients with respect to resultMagnitude and resultAngle + Parallel.For(0, this.input1.Rows, i => + { + for (int j = 0; j < this.input1.Cols / 2; j++) + { + var values = this.calculatedValues[i, j]; + + // Update dWeights with direct contributions from summationX and summationY + dWeights[i, j] = (dSummationXOutput * values.DLocalSumX_DWeight) + (dSummationYOutput * values.DLocalSumY_DWeight); + + // Apply chain rule to propagate back to dInput1 and dInput2 + dInput1[i, j] = (dSummationXOutput * values.DLocalSumX_DMagnitude) + (dSummationYOutput * values.DLocalSumY_DMagnitude); + dInput1[i, j + (this.input1.Cols / 2)] = (dSummationXOutput * values.DLocalSumX_DAngle) + (dSummationYOutput * values.DLocalSumY_DAngle); + + dInput2[i, j] = (dSummationXOutput * values.DLocalSumX_DWMagnitude) + (dSummationYOutput * values.DLocalSumY_DWMagnitude); + dInput2[i, j + (this.input2.Cols / 2)] = (dSummationXOutput * values.DLocalSumX_DWAngle) + (dSummationYOutput * values.DLocalSumY_DWAngle); + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dInput1) + .AddInputGradient(dInput2) + .AddInputGradient(dWeights) + .Build(); + } + + private struct CalculatedValues + { + public double DLocalSumX_DAngle { get; internal set; } + + public double DLocalSumX_DWAngle { get; internal set; } + + public double DLocalSumX_DMagnitude { get; internal set; } + + public double DLocalSumX_DWMagnitude { get; internal set; } + + public double DLocalSumY_DAngle { get; internal set; } + + public double DLocalSumY_DWAngle { get; internal set; } + + public double DLocalSumY_DMagnitude { get; internal set; } + + public double DLocalSumY_DWMagnitude { get; internal set; } + + public double DLocalSumX_DWeight { get; internal set; } + + public double DLocalSumY_DWeight { get; internal set; } + } + } +} diff --git a/src/RMAD/ElementwiseVectorConstituentMultiplyOperation.cs b/src/RMAD/ElementwiseVectorConstituentMultiplyOperation.cs new file mode 100644 index 00000000..6b30a09b --- /dev/null +++ b/src/RMAD/ElementwiseVectorConstituentMultiplyOperation.cs @@ -0,0 +1,343 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Threading.Tasks; + + /// + /// Element-wise vector constituent multiplication operation. + /// + public class ElementwiseVectorConstituentMultiplyOperation : Operation + { + private Matrix input1; + private Matrix input2; + private Matrix weights; + private Matrix sumX; + private Matrix sumY; + private CalculatedValues calculatedValues; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new ElementwiseVectorConstituentMultiplyOperation(); + } + + /// + /// Performs the forward operation for the vector constituent multiply function. + /// + /// The first input to the vector constituent multiply operation. + /// The second input to the vector constituent multiply operation. + /// The weights to the vector constituent multiply operation. + /// The output of the vector constituent multiply operation. + public Matrix Forward(Matrix input1, Matrix input2, Matrix weights) + { + this.input1 = input1; + this.input2 = input2; + this.weights = weights; + + this.Output = new Matrix(input1.Rows, input2.Cols); + this.sumX = new Matrix(input1.Rows, input2.Cols / 2); + this.sumY = new Matrix(input1.Rows, input2.Cols / 2); + + double[,] dInputMag_dOutputMag = new double[input1.Rows, input2.Rows / 2]; + double[,] dInputMag_dOutputAngle = new double[input1.Rows, input2.Rows / 2]; + double[,] dInputAngle_dOutputMag = new double[input1.Rows, input2.Rows / 2]; + double[,] dInputAngle_dOutputAngle = new double[input1.Rows, input2.Rows / 2]; + double[,] dInput2Mag_dOutputMag = new double[input2.Rows / 2, input2.Cols / 2]; + double[,] dInput2Mag_dOutputAngle = new double[input2.Rows / 2, input2.Cols / 2]; + double[,] dInput2Angle_dOutputMag = new double[input2.Rows / 2, input2.Cols / 2]; + double[,] dInput2Angle_dOutputAngle = new double[input2.Rows / 2, input2.Cols / 2]; + double[,] dWeight_dOutputMag = new double[input2.Rows / 2, input2.Cols / 2]; + double[,] dWeight_dOutputAngle = new double[input2.Rows / 2, input2.Cols / 2]; + + Parallel.For(0, input1.Rows, i => + { + for (int j = 0; j < input2.Cols / 2; j++) + { + double sumX = 0.0d; + double sumY = 0.0d; + + double[] dDeltaX_dX1 = new double[input2.Rows / 2]; + double[] dDeltaY_dY1 = new double[input2.Rows / 2]; + double[] dDeltaX_dX2 = new double[input2.Rows / 2]; + double[] dDeltaY_dY2 = new double[input2.Rows / 2]; + double[] dSumX_dDeltaX = new double[input2.Rows / 2]; + double[] dSumX_dDeltaY = new double[input2.Rows / 2]; + double[] dSumY_dDeltaX = new double[input2.Rows / 2]; + double[] dSumY_dDeltaY = new double[input2.Rows / 2]; + double[] dDeltaX_dWeight = new double[input2.Rows / 2]; + double[] dDeltaY_dWeight = new double[input2.Rows / 2]; + double[] dX1_dMagnitude = new double[input2.Rows / 2]; + double[] dY1_dMagnitude = new double[input2.Rows / 2]; + double[] dX1_dAngle = new double[input2.Rows / 2]; + double[] dY1_dAngle = new double[input2.Rows / 2]; + double[] dX2_dWMagnitude = new double[input2.Rows / 2]; + double[] dY2_dWMagnitude = new double[input2.Rows / 2]; + double[] dX2_dWAngle = new double[input2.Rows / 2]; + double[] dY2_dWAngle = new double[input2.Rows / 2]; + double[] dSumX_dResultMagnitude = new double[input2.Rows / 2]; + double[] dSumY_dResultMagnitude = new double[input2.Rows / 2]; + double[] dResultMagnitude_dWeight = new double[input2.Rows / 2]; + + for (int k = 0; k < input2.Rows / 2; k++) + { + // Accessing the magnitudes and angles from the concatenated matrices + double magnitude = input1[i, k]; + double angle = input1[i, k + (input1.Cols / 2)]; + + double wMagnitude = input2[k, j]; + double wAngle = input2[k, j + (input2.Cols / 2)]; + + // Compute vector components + double x1 = magnitude * Math.Cos(angle); + double y1 = magnitude * Math.Sin(angle); + double x2 = wMagnitude * Math.Cos(wAngle); + double y2 = wMagnitude * Math.Sin(wAngle); + + // Select vector direction based on weight + double deltax = weights[k, j] > 0 ? x2 - x1 : x1 - x2; + double deltay = weights[k, j] > 0 ? y2 - y1 : y1 - y2; + + double deltaXYSquared = (deltax * deltax) + (deltay * deltay); + + // Compute resultant vector magnitude and angle + double resultMagnitude = Math.Sqrt(deltaXYSquared) * weights[k, j]; + double resultAngle = Math.Atan2(deltay, deltax); + + double dResultMagnitude_dDeltaX = (deltax * weights[k, j]) / Math.Sqrt(deltaXYSquared); + double dResultMagnitude_dDeltaY = (deltay * weights[k, j]) / Math.Sqrt(deltaXYSquared); + double dResultAngle_dDeltaX = -deltay / deltaXYSquared; + double dResultAngle_dDeltaY = deltax / deltaXYSquared; + + double localSumX = resultMagnitude * Math.Cos(resultAngle); + double localSumY = resultMagnitude * Math.Sin(resultAngle); + + double dLocalSumX_dResultMagnitude = Math.Cos(resultAngle); + double dLocalSumY_dResultMagnitude = Math.Sin(resultAngle); + + double dLocalSumX_dResultAngle = -resultMagnitude * Math.Sin(resultAngle); + double dLocalSumY_dResultAngle = resultMagnitude * Math.Cos(resultAngle); + + double dLocalSumX_dDeltaX = (dLocalSumX_dResultMagnitude * dResultMagnitude_dDeltaX) + + (dLocalSumX_dResultAngle * dResultAngle_dDeltaX); + double dLocalSumX_dDeltaY = (dLocalSumX_dResultMagnitude * dResultMagnitude_dDeltaY) + + (dLocalSumX_dResultAngle * dResultAngle_dDeltaY); + double dLocalSumY_dDeltaX = (dLocalSumY_dResultMagnitude * dResultMagnitude_dDeltaX) + + (dLocalSumY_dResultAngle * dResultAngle_dDeltaX); + double dLocalSumY_dDeltaY = (dLocalSumY_dResultMagnitude * dResultMagnitude_dDeltaY) + + (dLocalSumY_dResultAngle * dResultAngle_dDeltaY); + + sumX += localSumX; + sumY += localSumY; + + dSumX_dDeltaX[k] = dLocalSumX_dDeltaX; + dSumX_dDeltaY[k] = dLocalSumX_dDeltaY; + dSumY_dDeltaX[k] = dLocalSumY_dDeltaX; + dSumY_dDeltaY[k] = dLocalSumY_dDeltaY; + + // Derivatives of delta components with respect to inputs + dDeltaX_dX1[k] = this.weights[k, j] > 0 ? -1 : 1; // Depending on weight sign + dDeltaY_dY1[k] = this.weights[k, j] > 0 ? -1 : 1; // Depending on weight sign + dDeltaX_dX2[k] = this.weights[k, j] > 0 ? 1 : -1; // Depending on weight sign + dDeltaY_dY2[k] = this.weights[k, j] > 0 ? 1 : -1; // Depending on weight sign + + dX1_dMagnitude[k] = Math.Cos(angle); + dY1_dMagnitude[k] = Math.Sin(angle); + + dX1_dAngle[k] = -magnitude * Math.Sin(angle); + dY1_dAngle[k] = magnitude * Math.Cos(angle); + + dX2_dWMagnitude[k] = Math.Cos(wAngle); + dY2_dWMagnitude[k] = Math.Sin(wAngle); + + dX2_dWAngle[k] = -wMagnitude * Math.Sin(wAngle); + dY2_dWAngle[k] = wMagnitude * Math.Cos(wAngle); + + // Derivatives of delta components with respect to weight + dDeltaX_dWeight[k] = (weights[k, j] > 0) ? (x2 - x1) : (x1 - x2); + dDeltaY_dWeight[k] = (weights[k, j] > 0) ? (y2 - y1) : (y1 - y2); + + dResultMagnitude_dWeight[k] = Math.Sqrt(deltaXYSquared); + dSumX_dResultMagnitude[k] = Math.Cos(resultAngle); + dSumY_dResultMagnitude[k] = Math.Sin(resultAngle); + } + + this.sumX[i, j] = sumX; + this.sumY[i, j] = sumY; + + // Analytically determined gradients for combined magnitude + double magSumXY = (this.sumX[i, j] * this.sumX[i, j]) + (this.sumY[i, j] * this.sumY[i, j]); + double dCombinedMagnitude_dSumX = this.sumX[i, j] / Math.Sqrt(magSumXY); + double dCombinedMagnitude_dSumY = this.sumY[i, j] / Math.Sqrt(magSumXY); + + double dCombinedAngle_dSumX = -this.sumY[i, j] / magSumXY; + double dCombinedAngle_dSumY = this.sumX[i, j] / magSumXY; + + for (int k = 0; k < input2.Rows / 2; k++) + { + dInputMag_dOutputMag[i, k] += + (dCombinedMagnitude_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dMagnitude[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dMagnitude[k]) + + (dCombinedMagnitude_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dMagnitude[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dMagnitude[k]); + + dInput2Mag_dOutputMag[k, j] += + (dCombinedMagnitude_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX1[k] * dX2_dWMagnitude[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY1[k] * dY2_dWMagnitude[k]) + + (dCombinedMagnitude_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY1[k] * dY2_dWMagnitude[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX1[k] * dX2_dWMagnitude[k]); + + dInputMag_dOutputAngle[i, k] += + (dCombinedAngle_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dMagnitude[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dMagnitude[k]) + + (dCombinedAngle_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dMagnitude[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dMagnitude[k]); + + dInput2Mag_dOutputAngle[k, j] += + (dCombinedAngle_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX2[k] * dX2_dWMagnitude[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY2[k] * dY2_dWMagnitude[k]) + + (dCombinedAngle_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY2[k] * dY2_dWMagnitude[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX2[k] * dX2_dWMagnitude[k]); + + dInputAngle_dOutputMag[i, k] += + (dCombinedMagnitude_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dAngle[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dAngle[k]) + + (dCombinedMagnitude_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dAngle[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dAngle[k]); + + dInput2Angle_dOutputMag[k, j] += + (dCombinedMagnitude_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX2[k] * dX2_dWAngle[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY2[k] * dY2_dWAngle[k]) + + (dCombinedMagnitude_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY2[k] * dY2_dWAngle[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX2[k] * dX2_dWAngle[k]); + + dInputAngle_dOutputAngle[i, k] += + (dCombinedAngle_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dAngle[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dAngle[k]) + + (dCombinedAngle_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY1[k] * dY1_dAngle[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX1[k] * dX1_dAngle[k]); + + dInput2Angle_dOutputAngle[k, j] += + (dCombinedAngle_dSumX * dSumX_dDeltaX[k] * dDeltaX_dX2[k] * dX2_dWAngle[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaY[k] * dDeltaY_dY2[k] * dY2_dWAngle[k]) + + (dCombinedAngle_dSumX * dSumX_dDeltaY[k] * dDeltaY_dY2[k] * dY2_dWAngle[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaX[k] * dDeltaX_dX2[k] * dX2_dWAngle[k]); + + dWeight_dOutputMag[k, j] += + (dCombinedMagnitude_dSumX * dSumX_dDeltaX[k] * dDeltaX_dWeight[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaY[k] * dDeltaY_dWeight[k]) + + (dCombinedMagnitude_dSumX * dSumX_dDeltaY[k] * dDeltaY_dWeight[k]) + + (dCombinedMagnitude_dSumY * dSumY_dDeltaX[k] * dDeltaX_dWeight[k]) + + (dCombinedMagnitude_dSumX * dSumX_dResultMagnitude[k] * dResultMagnitude_dWeight[k]) + + (dCombinedMagnitude_dSumY * dSumY_dResultMagnitude[k] * dResultMagnitude_dWeight[k]); + + dWeight_dOutputAngle[k, j] += + (dCombinedAngle_dSumX * dSumX_dDeltaX[k] * dDeltaX_dWeight[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaY[k] * dDeltaY_dWeight[k]) + + (dCombinedAngle_dSumX * dSumX_dDeltaY[k] * dDeltaY_dWeight[k]) + + (dCombinedAngle_dSumY * dSumY_dDeltaX[k] * dDeltaX_dWeight[k]) + + (dCombinedAngle_dSumX * dSumX_dResultMagnitude[k] * dResultMagnitude_dWeight[k]) + + (dCombinedAngle_dSumY * dSumY_dResultMagnitude[k] * dResultMagnitude_dWeight[k]); + } + + this.Output[i, j] = Math.Sqrt((sumX * sumX) + (sumY * sumY)); // Magnitude + this.Output[i, j + (input2.Cols / 2)] = Math.Atan2(sumY, sumX); // Angle in radians + } + }); + + this.calculatedValues = new CalculatedValues + { + DInputMag_dOutputMag = dInputMag_dOutputMag, + DInputMag_dOutputAngle = dInputMag_dOutputAngle, + DInputAngle_dOutputMag = dInputAngle_dOutputMag, + DInputAngle_dOutputAngle = dInputAngle_dOutputAngle, + DInput2Mag_dOutputMag = dInput2Mag_dOutputMag, + DInput2Mag_dOutputAngle = dInput2Mag_dOutputAngle, + DInput2Angle_dOutputMag = dInput2Angle_dOutputMag, + DInput2Angle_dOutputAngle = dInput2Angle_dOutputAngle, + DWeight_dOutputMag = dWeight_dOutputMag, + DWeight_dOutputAngle = dWeight_dOutputAngle, + }; + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + // Initialize gradient matrices + Matrix dInput1 = new Matrix(this.input1.Rows, this.input1.Cols); + Matrix dInput2 = new Matrix(this.input2.Rows, this.input2.Cols); + Matrix dWeights = new Matrix(this.weights.Rows, this.weights.Cols); + + // Loop through each element in input1 + Parallel.For(0, this.input1.Rows, i => + { + for (int k = 0; k < this.input2.Rows / 2; k++) + { + for (int j = 0; j < this.input2.Cols / 2; j++) + { + dInput1[i, k] += dOutput[i, j] * this.calculatedValues.DInputMag_dOutputMag[i, k]; + dInput1[i, k] += dOutput[i, j + (this.input2.Cols / 2)] * this.calculatedValues.DInputMag_dOutputAngle[i, k]; + dInput1[i, k + (this.input1.Cols / 2)] += dOutput[i, j] * this.calculatedValues.DInputAngle_dOutputMag[i, k]; + dInput1[i, k + (this.input1.Cols / 2)] += dOutput[i, j + (this.input2.Cols / 2)] * this.calculatedValues.DInputAngle_dOutputAngle[i, k]; + } + } + }); + + Parallel.For(0, this.input2.Rows / 2, k => + { + for (int j = 0; j < this.input2.Cols / 2; j++) + { + for (int i = 0; i < this.input1.Rows; ++i) + { + dInput2[k, j] += dOutput[i, j] * this.calculatedValues.DInput2Mag_dOutputMag[k, j]; + dInput2[k, j] += dOutput[i, j + (this.input2.Cols / 2)] * this.calculatedValues.DInput2Mag_dOutputAngle[k, j]; + dInput2[k, j + (this.input2.Cols / 2)] += dOutput[i, j] * this.calculatedValues.DInput2Angle_dOutputMag[k, j]; + dInput2[k, j + (this.input2.Cols / 2)] += dOutput[i, j + (this.input2.Cols / 2)] * this.calculatedValues.DInput2Angle_dOutputAngle[k, j]; + + dWeights[k, j] += dOutput[i, j] * this.calculatedValues.DWeight_dOutputMag[k, j]; + dWeights[k, j] += dOutput[i, j + (this.input2.Cols / 2)] * this.calculatedValues.DWeight_dOutputAngle[k, j]; + } + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dInput1) + .AddInputGradient(dInput2) + .AddInputGradient(dWeights) + .Build(); + } + + private struct CalculatedValues + { + public double[,] DInputMag_dOutputMag { get; internal set; } + + public double[,] DInputMag_dOutputAngle { get; internal set; } + + public double[,] DInputAngle_dOutputMag { get; internal set; } + + public double[,] DInputAngle_dOutputAngle { get; internal set; } + + public double[,] DInput2Mag_dOutputMag { get; internal set; } + + public double[,] DInput2Mag_dOutputAngle { get; internal set; } + + public double[,] DInput2Angle_dOutputMag { get; internal set; } + + public double[,] DInput2Angle_dOutputAngle { get; internal set; } + + public double[,] DWeight_dOutputMag { get; internal set; } + + public double[,] DWeight_dOutputAngle { get; internal set; } + } + } +} diff --git a/src/RMAD/ElementwiseVectorDecompositionOperation.cs b/src/RMAD/ElementwiseVectorDecompositionOperation.cs new file mode 100644 index 00000000..330ff491 --- /dev/null +++ b/src/RMAD/ElementwiseVectorDecompositionOperation.cs @@ -0,0 +1,614 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Threading.Tasks; + + /// + /// Element-wise vector projection operation. + /// + public class ElementwiseVectorDecompositionOperation : Operation + { + private Matrix input1; + private Matrix input2; + private Matrix weights; + private CalculatedValues[,] calculatedValues; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new ElementwiseVectorDecompositionOperation(); + } + + /// + /// Performs the forward operation for the element-wise vector projection function. + /// + /// The first input to the element-wise vector projection operation. + /// The second input to the element-wise vector projection operation. + /// The weights input to the element-wise vector projection operation. + /// The output of the element-wise vector projection operation. + public Matrix Forward(Matrix input1, Matrix input2, Matrix weights) + { + this.input1 = input1; + this.input2 = input2; + this.weights = weights; + + this.Output = new Matrix(this.input1.Rows, this.input1.Cols * 10); + + this.calculatedValues = new CalculatedValues[this.input1.Rows, this.input1.Cols / 2]; + + Parallel.For(0, input1.Rows, i => + { + for (int j = 0; j < input1.Cols / 2; j++) + { + // Accessing the magnitudes and angles from the concatenated matrices + double magnitude = input1[i, j]; + double angle = input1[i, j + (input1.Cols / 2)]; + + double wMagnitudePivot = input2[i, j * 5]; + double wAnglePivot = input2[i, (j * 5) + (input2.Cols / 2)]; + + double wMagnitude1 = input2[i, (j * 5) + 1]; + double wAngle1 = input2[i, (j * 5) + 1 + (input2.Cols / 2)]; + + double wMagnitude2 = input2[i, (j * 5) + 2]; + double wAngle2 = input2[i, (j * 5) + 2 + (input2.Cols / 2)]; + + double wMagnitude3 = input2[i, (j * 5) + 3]; + double wAngle3 = input2[i, (j * 5) + 3 + (input2.Cols / 2)]; + + double wMagnitude4 = input2[i, (j * 5) + 4]; + double wAngle4 = input2[i, (j * 5) + 4 + (input2.Cols / 2)]; + + // Compute vector components + double x = magnitude * Math.Cos(angle); + double y = magnitude * Math.Sin(angle); + double xPivot = wMagnitudePivot * Math.Cos(wAnglePivot); + double yPivot = wMagnitudePivot * Math.Sin(wAnglePivot); + + double dx_dMagnitude = Math.Cos(angle); + double dx_dAngle = -magnitude * Math.Sin(angle); + double dy_dMagnitude = Math.Sin(angle); + double dy_dAngle = magnitude * Math.Cos(angle); + double dXPivot_dWMagnitudePivot = Math.Cos(wAnglePivot); + double dXPivot_dWAnglePivot = -wMagnitudePivot * Math.Sin(wAnglePivot); + double dYPivot_dWMagnitudePivot = Math.Sin(wAnglePivot); + double dYPivot_dWAnglePivot = wMagnitudePivot * Math.Cos(wAnglePivot); + + this.calculatedValues[i, j] = new CalculatedValues() + { + CV_dx_dMagnitude = dx_dMagnitude, + CV_dx_dAngle = dx_dAngle, + CV_dy_dMagnitude = dy_dMagnitude, + CV_dy_dAngle = dy_dAngle, + CV_dXPivot_dWMagnitudePivot = dXPivot_dWMagnitudePivot, + CV_dXPivot_dWAnglePivot = dXPivot_dWAnglePivot, + CV_dYPivot_dWMagnitudePivot = dYPivot_dWMagnitudePivot, + CV_dYPivot_dWAnglePivot = dYPivot_dWAnglePivot, + }; + + double x1 = wMagnitude1 * Math.Cos(wAngle1); + double y1 = wMagnitude1 * Math.Sin(wAngle1); + + double dX1_wMagnitude1 = Math.Cos(wAngle1); + double dX1_wAngle1 = -wMagnitude1 * Math.Sin(wAngle1); + double dY1_wMagnitude1 = Math.Sin(wAngle1); + double dY1_wAngle1 = wMagnitude1 * Math.Cos(wAngle1); + + this.calculatedValues[i, j].CV_dX1_wMagnitude1 = dX1_wMagnitude1; + this.calculatedValues[i, j].CV_dX1_wAngle1 = dX1_wAngle1; + this.calculatedValues[i, j].CV_dY1_wMagnitude1 = dY1_wMagnitude1; + this.calculatedValues[i, j].CV_dY1_wAngle1 = dY1_wAngle1; + + double x2 = wMagnitude2 * Math.Cos(wAngle2); + double y2 = wMagnitude2 * Math.Sin(wAngle2); + + double dX2_wMagnitude2 = Math.Cos(wAngle2); + double dX2_wAngle2 = -wMagnitude2 * Math.Sin(wAngle2); + double dY2_wMagnitude2 = Math.Sin(wAngle2); + double dY2_wAngle2 = wMagnitude2 * Math.Cos(wAngle2); + + this.calculatedValues[i, j].CV_dX2_wMagnitude2 = dX2_wMagnitude2; + this.calculatedValues[i, j].CV_dX2_wAngle2 = dX2_wAngle2; + this.calculatedValues[i, j].CV_dY2_wMagnitude2 = dY2_wMagnitude2; + this.calculatedValues[i, j].CV_dY2_wAngle2 = dY2_wAngle2; + + double x3 = wMagnitude3 * Math.Cos(wAngle3); + double y3 = wMagnitude3 * Math.Sin(wAngle3); + + double dX3_wMagnitude3 = Math.Cos(wAngle3); + double dX3_wAngle3 = -wMagnitude3 * Math.Sin(wAngle3); + double dY3_wMagnitude3 = Math.Sin(wAngle3); + double dY3_wAngle3 = wMagnitude3 * Math.Cos(wAngle3); + + this.calculatedValues[i, j].CV_dX3_wMagnitude3 = dX3_wMagnitude3; + this.calculatedValues[i, j].CV_dX3_wAngle3 = dX3_wAngle3; + this.calculatedValues[i, j].CV_dY3_wMagnitude3 = dY3_wMagnitude3; + this.calculatedValues[i, j].CV_dY3_wAngle3 = dY3_wAngle3; + + double x4 = wMagnitude4 * Math.Cos(wAngle4); + double y4 = wMagnitude4 * Math.Sin(wAngle4); + + double dX4_wMagnitude4 = Math.Cos(wAngle4); + double dX4_wAngle4 = -wMagnitude4 * Math.Sin(wAngle4); + double dY4_wMagnitude4 = Math.Sin(wAngle4); + double dY4_wAngle4 = wMagnitude4 * Math.Cos(wAngle4); + + this.calculatedValues[i, j].CV_dX4_wMagnitude4 = dX4_wMagnitude4; + this.calculatedValues[i, j].CV_dX4_wAngle4 = dX4_wAngle4; + this.calculatedValues[i, j].CV_dY4_wMagnitude4 = dY4_wMagnitude4; + this.calculatedValues[i, j].CV_dY4_wAngle4 = dY4_wAngle4; + + double sumx = (x + xPivot) / (this.weights[i, j] + 1E-9); + double sumy = (y + yPivot) / (this.weights[i, j] + 1E-9); + + double dsumx_dX = 1d / (this.weights[i, j] + 1E-9); + double dsumx_dXPivot = 1d / (this.weights[i, j] + 1E-9); + double dsumx_dWeight = -(x + xPivot) / ((this.weights[i, j] + 1E-9) * (this.weights[i, j] + 1E-9)); + double dsumy_dY = 1d / (this.weights[i, j] + 1E-9); + double dsumy_dYPivot = 1d / (this.weights[i, j] + 1E-9); + double dsumy_dWeight = -(y + yPivot) / ((this.weights[i, j] + 1E-9) * (this.weights[i, j] + 1E-9)); + + this.calculatedValues[i, j].CV_dsumx_dX = dsumx_dX; + this.calculatedValues[i, j].CV_dsumx_dXPivot = dsumx_dXPivot; + this.calculatedValues[i, j].CV_dsumx_dWeight = dsumx_dWeight; + this.calculatedValues[i, j].CV_dsumy_dY = dsumy_dY; + this.calculatedValues[i, j].CV_dsumy_dYPivot = dsumy_dYPivot; + this.calculatedValues[i, j].CV_dsumy_dWeight = dsumy_dWeight; + + double diffx1 = sumx - x1; + double diffy1 = sumy - y1; + + double dDiffX1_dSumX = 1d; + double dDiffX1_dX1 = -1d; + double dDiffY1_dSumY = 1d; + double dDiffY1_dY1 = -1d; + + this.calculatedValues[i, j].CV_dDiffX1_dSumX = dDiffX1_dSumX; + this.calculatedValues[i, j].CV_dDiffX1_dX1 = dDiffX1_dX1; + this.calculatedValues[i, j].CV_dDiffY1_dSumY = dDiffY1_dSumY; + this.calculatedValues[i, j].CV_dDiffY1_dY1 = dDiffY1_dY1; + + double diffx2 = -sumx - x2; + double diffy2 = -sumy - y2; + + double dDiffX2_dSumX = -1d; + double dDiffX2_dX2 = -1d; + double dDiffY2_dSumY = -1d; + double dDiffY2_dY2 = -1d; + + this.calculatedValues[i, j].CV_dDiffX2_dSumX = dDiffX2_dSumX; + this.calculatedValues[i, j].CV_dDiffX2_dX2 = dDiffX2_dX2; + this.calculatedValues[i, j].CV_dDiffY2_dSumY = dDiffY2_dSumY; + this.calculatedValues[i, j].CV_dDiffY2_dY2 = dDiffY2_dY2; + + double diffx3 = sumx - x3; + double diffy3 = sumy - y3; + + double dDiffX3_dSumX = 1d; + double dDiffX3_dX3 = -1d; + double dDiffY3_dSumY = 1d; + double dDiffY3_dY3 = -1d; + + this.calculatedValues[i, j].CV_dDiffX3_dSumX = dDiffX3_dSumX; + this.calculatedValues[i, j].CV_dDiffX3_dX3 = dDiffX3_dX3; + this.calculatedValues[i, j].CV_dDiffY3_dSumY = dDiffY3_dSumY; + this.calculatedValues[i, j].CV_dDiffY3_dY3 = dDiffY3_dY3; + + double diffx4 = -sumx - x4; + double diffy4 = -sumy - y4; + + double dDiffX4_dSumX = -1d; + double dDiffX4_dX4 = -1d; + double dDiffY4_dSumY = -1d; + double dDiffY4_dY4 = -1d; + + this.calculatedValues[i, j].CV_dDiffX4_dSumX = dDiffX4_dSumX; + this.calculatedValues[i, j].CV_dDiffX4_dX4 = dDiffX4_dX4; + this.calculatedValues[i, j].CV_dDiffY4_dSumY = dDiffY4_dSumY; + this.calculatedValues[i, j].CV_dDiffY4_dY4 = dDiffY4_dY4; + + // Compute resultant vector magnitude and angle + double resultMagnitude1 = Math.Sqrt((diffx1 * diffx1) + (diffy1 * diffy1)); + double resultAngle1 = Math.Atan2(diffy1, diffx1); + + double dResultMagnitude1_dDiffX1 = diffx1 / resultMagnitude1; + double dResultMagnitude1_dDiffY1 = diffy1 / resultMagnitude1; + double dResultAngle1_dDiffX1 = -diffy1 / ((diffx1 * diffx1) + (diffy1 * diffy1)); + double dResultAngle1_dDiffY1 = diffx1 / ((diffx1 * diffx1) + (diffy1 * diffy1)); + + this.calculatedValues[i, j].CV_dResultMagnitude1_dDiffX1 = dResultMagnitude1_dDiffX1; + this.calculatedValues[i, j].CV_dResultMagnitude1_dDiffY1 = dResultMagnitude1_dDiffY1; + this.calculatedValues[i, j].CV_dResultAngle1_dDiffX1 = dResultAngle1_dDiffX1; + this.calculatedValues[i, j].CV_dResultAngle1_dDiffY1 = dResultAngle1_dDiffY1; + + double resultMagnitude2 = Math.Sqrt((diffx2 * diffx2) + (diffy2 * diffy2)); + double resultAngle2 = Math.Atan2(diffy2, diffx2); + + double dResultMagnitude2_dDiffX2 = diffx2 / resultMagnitude2; + double dResultMagnitude2_dDiffY2 = diffy2 / resultMagnitude2; + double dResultAngle2_dDiffX2 = -diffy2 / ((diffx2 * diffx2) + (diffy2 * diffy2)); + double dResultAngle2_dDiffY2 = diffx2 / ((diffx2 * diffx2) + (diffy2 * diffy2)); + + this.calculatedValues[i, j].CV_dResultMagnitude2_dDiffX2 = dResultMagnitude2_dDiffX2; + this.calculatedValues[i, j].CV_dResultMagnitude2_dDiffY2 = dResultMagnitude2_dDiffY2; + this.calculatedValues[i, j].CV_dResultAngle2_dDiffX2 = dResultAngle2_dDiffX2; + this.calculatedValues[i, j].CV_dResultAngle2_dDiffY2 = dResultAngle2_dDiffY2; + + double resultMagnitude3 = Math.Sqrt((diffx3 * diffx3) + (diffy3 * diffy3)); + double resultAngle3 = Math.Atan2(diffy3, diffx3); + + double dResultMagnitude3_dDiffX3 = diffx3 / resultMagnitude3; + double dResultMagnitude3_dDiffY3 = diffy3 / resultMagnitude3; + double dResultAngle3_dDiffX3 = -diffy3 / ((diffx3 * diffx3) + (diffy3 * diffy3)); + double dResultAngle3_dDiffY3 = diffx3 / ((diffx3 * diffx3) + (diffy3 * diffy3)); + + this.calculatedValues[i, j].CV_dResultMagnitude3_dDiffX3 = dResultMagnitude3_dDiffX3; + this.calculatedValues[i, j].CV_dResultMagnitude3_dDiffY3 = dResultMagnitude3_dDiffY3; + this.calculatedValues[i, j].CV_dResultAngle3_dDiffX3 = dResultAngle3_dDiffX3; + this.calculatedValues[i, j].CV_dResultAngle3_dDiffY3 = dResultAngle3_dDiffY3; + + double resultMagnitude4 = Math.Sqrt((diffx4 * diffx4) + (diffy4 * diffy4)); + double resultAngle4 = Math.Atan2(diffy4, diffx4); + + double dResultMagnitude4_dDiffX4 = diffx4 / resultMagnitude4; + double dResultMagnitude4_dDiffY4 = diffy4 / resultMagnitude4; + double dResultAngle4_dDiffX4 = -diffy4 / ((diffx4 * diffx4) + (diffy4 * diffy4)); + double dResultAngle4_dDiffY4 = diffx4 / ((diffx4 * diffx4) + (diffy4 * diffy4)); + + this.calculatedValues[i, j].CV_dResultMagnitude4_dDiffX4 = dResultMagnitude4_dDiffX4; + this.calculatedValues[i, j].CV_dResultMagnitude4_dDiffY4 = dResultMagnitude4_dDiffY4; + this.calculatedValues[i, j].CV_dResultAngle4_dDiffX4 = dResultAngle4_dDiffX4; + this.calculatedValues[i, j].CV_dResultAngle4_dDiffY4 = dResultAngle4_dDiffY4; + + this.Output[i, j * 10] = magnitude; + this.Output[i, (j * 10) + (this.input1.Cols * 10 / 2)] = angle; + + this.Output[i, (j * 10) + 1] = wMagnitudePivot; + this.Output[i, (j * 10) + 1 + (this.input1.Cols * 10 / 2)] = wAnglePivot; + + this.Output[i, (j * 10) + 2] = wMagnitude1; + this.Output[i, (j * 10) + 2 + (this.input1.Cols * 10 / 2)] = wAngle1; + + this.Output[i, (j * 10) + 3] = wMagnitude2; + this.Output[i, (j * 10) + 3 + (this.input1.Cols * 10 / 2)] = wAngle2; + + this.Output[i, (j * 10) + 4] = wMagnitude3; + this.Output[i, (j * 10) + 4 + (this.input1.Cols * 10 / 2)] = wAngle3; + + this.Output[i, (j * 10) + 5] = wMagnitude4; + this.Output[i, (j * 10) + 5 + (this.input1.Cols * 10 / 2)] = wAngle4; + + this.Output[i, (j * 10) + 6] = resultMagnitude1; + this.Output[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] = resultAngle1; + + this.Output[i, (j * 10) + 7] = resultMagnitude2; + this.Output[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] = resultAngle2; + + this.Output[i, (j * 10) + 8] = resultMagnitude3; + this.Output[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] = resultAngle3; + + this.Output[i, (j * 10) + 9] = resultMagnitude4; + this.Output[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] = resultAngle4; + } + }); + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + Matrix dInput1 = new Matrix(this.input1.Rows, this.input1.Cols); + Matrix dInput2 = new Matrix(this.input2.Rows, this.input2.Cols); + Matrix dWeights = new Matrix(this.weights.Rows, this.weights.Cols); + + Parallel.For(0, this.input1.Rows, i => + { + for (int j = 0; j < this.input1.Cols / 2; j++) + { + var grad = this.calculatedValues[i, j]; + + dInput1[i, j] += dOutput[i, j * 10]; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + (this.input1.Cols * 10 / 2)]; + + dInput1[i, j] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 6] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + + dInput1[i, j] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 7] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + + dInput1[i, j] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 8] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + + dInput1[i, j] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 9] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + + dInput2[i, j * 5] += dOutput[i, (j * 10) + 1]; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 1 + (this.input1.Cols * 10 / 2)]; + + dInput2[i, (j * 5) + 1] += dOutput[i, (j * 10) + 2]; + dInput2[i, (j * 5) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 2 + (this.input1.Cols * 10 / 2)]; + + dInput2[i, (j * 5) + 2] += dOutput[i, (j * 10) + 3]; + dInput2[i, (j * 5) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 3 + (this.input1.Cols * 10 / 2)]; + + dInput2[i, (j * 5) + 3] += dOutput[i, (j * 10) + 4]; + dInput2[i, (j * 5) + 3 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 4 + (this.input1.Cols * 10 / 2)]; + + dInput2[i, (j * 5) + 4] += dOutput[i, (j * 10) + 5]; + dInput2[i, (j * 5) + 4 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 5 + (this.input1.Cols * 10 / 2)]; + + dInput2[i, j * 5] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + + dInput2[i, j * 5] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + + dInput2[i, j * 5] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + + dInput2[i, j * 5] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 5] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + dInput2[i, (j * 5) + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + + dInput2[i, (j * 5) + 1] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wMagnitude1; + dInput2[i, (j * 5) + 1] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wMagnitude1; + dInput2[i, (j * 5) + 1] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wMagnitude1; + dInput2[i, (j * 5) + 1] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wMagnitude1; + + dInput2[i, (j * 5) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wAngle1; + dInput2[i, (j * 5) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wAngle1; + dInput2[i, (j * 5) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wAngle1; + dInput2[i, (j * 5) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wAngle1; + + dInput2[i, (j * 5) + 2] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wMagnitude2; + dInput2[i, (j * 5) + 2] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wMagnitude2; + dInput2[i, (j * 5) + 2] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wMagnitude2; + dInput2[i, (j * 5) + 2] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wMagnitude2; + + dInput2[i, (j * 5) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wAngle2; + dInput2[i, (j * 5) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wAngle2; + dInput2[i, (j * 5) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wAngle2; + dInput2[i, (j * 5) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wAngle2; + + dInput2[i, (j * 5) + 3] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dX3 * grad.CV_dX3_wMagnitude3; + dInput2[i, (j * 5) + 3] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dY3 * grad.CV_dY3_wMagnitude3; + dInput2[i, (j * 5) + 3] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dX3 * grad.CV_dX3_wMagnitude3; + dInput2[i, (j * 5) + 3] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dY3 * grad.CV_dY3_wMagnitude3; + + dInput2[i, (j * 5) + 3 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dX3 * grad.CV_dX3_wAngle3; + dInput2[i, (j * 5) + 3 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dX3 * grad.CV_dX3_wAngle3; + dInput2[i, (j * 5) + 3 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dY3 * grad.CV_dY3_wAngle3; + dInput2[i, (j * 5) + 3 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dY3 * grad.CV_dY3_wAngle3; + + dInput2[i, (j * 5) + 4] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dX4 * grad.CV_dX4_wMagnitude4; + dInput2[i, (j * 5) + 4] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dY4 * grad.CV_dY4_wMagnitude4; + dInput2[i, (j * 5) + 4] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dX4 * grad.CV_dX4_wMagnitude4; + dInput2[i, (j * 5) + 4] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dY4 * grad.CV_dY4_wMagnitude4; + + dInput2[i, (j * 5) + 4 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dX4 * grad.CV_dX4_wAngle4; + dInput2[i, (j * 5) + 4 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dX4 * grad.CV_dX4_wAngle4; + dInput2[i, (j * 5) + 4 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dY4 * grad.CV_dY4_wAngle4; + dInput2[i, (j * 5) + 4 + (this.input2.Cols / 2)] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dY4 * grad.CV_dY4_wAngle4; + + dWeights[i, j] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 6] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 6 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dWeight; + + dWeights[i, j] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 7] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 7 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dWeight; + + dWeights[i, j] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 8] * grad.CV_dResultMagnitude3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffX3 * grad.CV_dDiffX3_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 8 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle3_dDiffY3 * grad.CV_dDiffY3_dSumY * grad.CV_dsumy_dWeight; + + dWeights[i, j] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 9] * grad.CV_dResultMagnitude4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffX4 * grad.CV_dDiffX4_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 10) + 9 + (this.input1.Cols * 10 / 2)] * grad.CV_dResultAngle4_dDiffY4 * grad.CV_dDiffY4_dSumY * grad.CV_dsumy_dWeight; + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dInput1) + .AddInputGradient(dInput2) + .AddInputGradient(dWeights) + .Build(); + } + + private struct CalculatedValues + { + public double CV_dx_dMagnitude { get; internal set; } + + public double CV_dx_dAngle { get; internal set; } + + public double CV_dy_dMagnitude { get; internal set; } + + public double CV_dy_dAngle { get; internal set; } + + public double CV_dXPivot_dWMagnitudePivot { get; internal set; } + + public double CV_dXPivot_dWAnglePivot { get; internal set; } + + public double CV_dYPivot_dWMagnitudePivot { get; internal set; } + + public double CV_dYPivot_dWAnglePivot { get; internal set; } + + public double CV_dX1_wMagnitude1 { get; internal set; } + + public double CV_dX1_wAngle1 { get; internal set; } + + public double CV_dY1_wMagnitude1 { get; internal set; } + + public double CV_dY1_wAngle1 { get; internal set; } + + public double CV_dX2_wMagnitude2 { get; internal set; } + + public double CV_dX2_wAngle2 { get; internal set; } + + public double CV_dY2_wMagnitude2 { get; internal set; } + + public double CV_dY2_wAngle2 { get; internal set; } + + public double CV_dX3_wMagnitude3 { get; internal set; } + + public double CV_dX3_wAngle3 { get; internal set; } + + public double CV_dY3_wMagnitude3 { get; internal set; } + + public double CV_dY3_wAngle3 { get; internal set; } + + public double CV_dX4_wMagnitude4 { get; internal set; } + + public double CV_dX4_wAngle4 { get; internal set; } + + public double CV_dY4_wMagnitude4 { get; internal set; } + + public double CV_dY4_wAngle4 { get; internal set; } + + public double CV_dsumx_dX { get; internal set; } + + public double CV_dsumx_dXPivot { get; internal set; } + + public double CV_dsumx_dWeight { get; internal set; } + + public double CV_dsumy_dY { get; internal set; } + + public double CV_dsumy_dYPivot { get; internal set; } + + public double CV_dsumy_dWeight { get; internal set; } + + public double CV_dDiffX1_dSumX { get; internal set; } + + public double CV_dDiffX1_dX1 { get; internal set; } + + public double CV_dDiffY1_dSumY { get; internal set; } + + public double CV_dDiffY1_dY1 { get; internal set; } + + public double CV_dDiffX2_dSumX { get; internal set; } + + public double CV_dDiffX2_dX2 { get; internal set; } + + public double CV_dDiffY2_dSumY { get; internal set; } + + public double CV_dDiffY2_dY2 { get; internal set; } + + public double CV_dDiffX3_dSumX { get; internal set; } + + public double CV_dDiffX3_dX3 { get; internal set; } + + public double CV_dDiffY3_dSumY { get; internal set; } + + public double CV_dDiffY3_dY3 { get; internal set; } + + public double CV_dDiffX4_dSumX { get; internal set; } + + public double CV_dDiffX4_dX4 { get; internal set; } + + public double CV_dDiffY4_dSumY { get; internal set; } + + public double CV_dDiffY4_dY4 { get; internal set; } + + public double CV_dResultMagnitude1_dDiffX1 { get; internal set; } + + public double CV_dResultMagnitude1_dDiffY1 { get; internal set; } + + public double CV_dResultAngle1_dDiffX1 { get; internal set; } + + public double CV_dResultAngle1_dDiffY1 { get; internal set; } + + public double CV_dResultMagnitude2_dDiffX2 { get; internal set; } + + public double CV_dResultMagnitude2_dDiffY2 { get; internal set; } + + public double CV_dResultAngle2_dDiffX2 { get; internal set; } + + public double CV_dResultAngle2_dDiffY2 { get; internal set; } + + public double CV_dResultMagnitude3_dDiffX3 { get; internal set; } + + public double CV_dResultMagnitude3_dDiffY3 { get; internal set; } + + public double CV_dResultAngle3_dDiffX3 { get; internal set; } + + public double CV_dResultAngle3_dDiffY3 { get; internal set; } + + public double CV_dResultMagnitude4_dDiffX4 { get; internal set; } + + public double CV_dResultMagnitude4_dDiffY4 { get; internal set; } + + public double CV_dResultAngle4_dDiffX4 { get; internal set; } + + public double CV_dResultAngle4_dDiffY4 { get; internal set; } + } + } +} diff --git a/src/RMAD/ElementwiseVectorMiniDecompositionOperation.cs b/src/RMAD/ElementwiseVectorMiniDecompositionOperation.cs new file mode 100644 index 00000000..24cd402a --- /dev/null +++ b/src/RMAD/ElementwiseVectorMiniDecompositionOperation.cs @@ -0,0 +1,394 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Threading.Tasks; + + /// + /// Element-wise vector mini decomposition operation. + /// + public class ElementwiseVectorMiniDecompositionOperation : Operation + { + private Matrix input1; + private Matrix input2; + private Matrix weights; + private CalculatedValues[,] calculatedValues; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new ElementwiseVectorMiniDecompositionOperation(); + } + + /// + /// Performs the forward operation for the element-wise vector mini decomposition function. + /// + /// The first input to the element-wise vector mini decomposition operation. + /// The second input to the element-wise vector mini decomposition operation. + /// The weights input to the element-wise vector mini decomposition operation. + /// The output of the element-wise vector mini decomposition operation. + public Matrix Forward(Matrix input1, Matrix input2, Matrix weights) + { + this.input1 = input1; + this.input2 = input2; + this.weights = weights; + + this.Output = new Matrix(this.input1.Rows, this.input1.Cols * 6); + + this.calculatedValues = new CalculatedValues[this.input1.Rows, this.input1.Cols / 2]; + + Parallel.For(0, input1.Rows, i => + { + for (int j = 0; j < input1.Cols / 2; j++) + { + // Accessing the magnitudes and angles from the concatenated matrices + double magnitude = input1[i, j]; + double angle = input1[i, j + (input1.Cols / 2)]; + + double wMagnitudePivot = input2[i, j * 3]; + double wAnglePivot = input2[i, (j * 3) + (input2.Cols / 2)]; + + double wMagnitude1 = input2[i, (j * 3) + 1]; + double wAngle1 = input2[i, (j * 3) + 1 + (input2.Cols / 2)]; + + double wMagnitude2 = input2[i, (j * 3) + 2]; + double wAngle2 = input2[i, (j * 3) + 2 + (input2.Cols / 2)]; + + // Compute vector components + double x = magnitude * Math.Cos(angle); + double y = magnitude * Math.Sin(angle); + double xPivot = wMagnitudePivot * Math.Cos(wAnglePivot); + double yPivot = wMagnitudePivot * Math.Sin(wAnglePivot); + + double dx_dMagnitude = Math.Cos(angle); + double dx_dAngle = -magnitude * Math.Sin(angle); + double dy_dMagnitude = Math.Sin(angle); + double dy_dAngle = magnitude * Math.Cos(angle); + double dXPivot_dWMagnitudePivot = Math.Cos(wAnglePivot); + double dXPivot_dWAnglePivot = -wMagnitudePivot * Math.Sin(wAnglePivot); + double dYPivot_dWMagnitudePivot = Math.Sin(wAnglePivot); + double dYPivot_dWAnglePivot = wMagnitudePivot * Math.Cos(wAnglePivot); + + this.calculatedValues[i, j] = new CalculatedValues() + { + CV_dx_dMagnitude = dx_dMagnitude, + CV_dx_dAngle = dx_dAngle, + CV_dy_dMagnitude = dy_dMagnitude, + CV_dy_dAngle = dy_dAngle, + CV_dXPivot_dWMagnitudePivot = dXPivot_dWMagnitudePivot, + CV_dXPivot_dWAnglePivot = dXPivot_dWAnglePivot, + CV_dYPivot_dWMagnitudePivot = dYPivot_dWMagnitudePivot, + CV_dYPivot_dWAnglePivot = dYPivot_dWAnglePivot, + }; + + double x1 = wMagnitude1 * Math.Cos(wAngle1); + double y1 = wMagnitude1 * Math.Sin(wAngle1); + + double dX1_wMagnitude1 = Math.Cos(wAngle1); + double dX1_wAngle1 = -wMagnitude1 * Math.Sin(wAngle1); + double dY1_wMagnitude1 = Math.Sin(wAngle1); + double dY1_wAngle1 = wMagnitude1 * Math.Cos(wAngle1); + + this.calculatedValues[i, j].CV_dX1_wMagnitude1 = dX1_wMagnitude1; + this.calculatedValues[i, j].CV_dX1_wAngle1 = dX1_wAngle1; + this.calculatedValues[i, j].CV_dY1_wMagnitude1 = dY1_wMagnitude1; + this.calculatedValues[i, j].CV_dY1_wAngle1 = dY1_wAngle1; + + double x2 = wMagnitude2 * Math.Cos(wAngle2); + double y2 = wMagnitude2 * Math.Sin(wAngle2); + + double dX2_wMagnitude2 = Math.Cos(wAngle2); + double dX2_wAngle2 = -wMagnitude2 * Math.Sin(wAngle2); + double dY2_wMagnitude2 = Math.Sin(wAngle2); + double dY2_wAngle2 = wMagnitude2 * Math.Cos(wAngle2); + + this.calculatedValues[i, j].CV_dX2_wMagnitude2 = dX2_wMagnitude2; + this.calculatedValues[i, j].CV_dX2_wAngle2 = dX2_wAngle2; + this.calculatedValues[i, j].CV_dY2_wMagnitude2 = dY2_wMagnitude2; + this.calculatedValues[i, j].CV_dY2_wAngle2 = dY2_wAngle2; + + double sumx = (x + xPivot) / (this.weights[i, j] + 1E-9); + double sumy = (y + yPivot) / (this.weights[i, j] + 1E-9); + + double dsumx_dX = 1d / (this.weights[i, j] + 1E-9); + double dsumx_dXPivot = 1d / (this.weights[i, j] + 1E-9); + double dsumx_dWeight = -(x + xPivot) / ((this.weights[i, j] + 1E-9) * (this.weights[i, j] + 1E-9)); + double dsumy_dY = 1d / (this.weights[i, j] + 1E-9); + double dsumy_dYPivot = 1d / (this.weights[i, j] + 1E-9); + double dsumy_dWeight = -(y + yPivot) / ((this.weights[i, j] + 1E-9) * (this.weights[i, j] + 1E-9)); + + this.calculatedValues[i, j].CV_dsumx_dX = dsumx_dX; + this.calculatedValues[i, j].CV_dsumx_dXPivot = dsumx_dXPivot; + this.calculatedValues[i, j].CV_dsumx_dWeight = dsumx_dWeight; + this.calculatedValues[i, j].CV_dsumy_dY = dsumy_dY; + this.calculatedValues[i, j].CV_dsumy_dYPivot = dsumy_dYPivot; + this.calculatedValues[i, j].CV_dsumy_dWeight = dsumy_dWeight; + + double diffx1 = sumx - x1; + double diffy1 = sumy - y1; + + double dDiffX1_dSumX = 1d; + double dDiffX1_dX1 = -1d; + double dDiffY1_dSumY = 1d; + double dDiffY1_dY1 = -1d; + + this.calculatedValues[i, j].CV_dDiffX1_dSumX = dDiffX1_dSumX; + this.calculatedValues[i, j].CV_dDiffX1_dX1 = dDiffX1_dX1; + this.calculatedValues[i, j].CV_dDiffY1_dSumY = dDiffY1_dSumY; + this.calculatedValues[i, j].CV_dDiffY1_dY1 = dDiffY1_dY1; + + double diffx2 = -sumx - x2; + double diffy2 = -sumy - y2; + + double dDiffX2_dSumX = -1d; + double dDiffX2_dX2 = -1d; + double dDiffY2_dSumY = -1d; + double dDiffY2_dY2 = -1d; + + this.calculatedValues[i, j].CV_dDiffX2_dSumX = dDiffX2_dSumX; + this.calculatedValues[i, j].CV_dDiffX2_dX2 = dDiffX2_dX2; + this.calculatedValues[i, j].CV_dDiffY2_dSumY = dDiffY2_dSumY; + this.calculatedValues[i, j].CV_dDiffY2_dY2 = dDiffY2_dY2; + + // Compute resultant vector magnitude and angle + double resultMagnitude1 = Math.Sqrt((diffx1 * diffx1) + (diffy1 * diffy1)); + double resultAngle1 = Math.Atan2(diffy1, diffx1); + + double dResultMagnitude1_dDiffX1 = diffx1 / resultMagnitude1; + double dResultMagnitude1_dDiffY1 = diffy1 / resultMagnitude1; + double dResultAngle1_dDiffX1 = -diffy1 / ((diffx1 * diffx1) + (diffy1 * diffy1)); + double dResultAngle1_dDiffY1 = diffx1 / ((diffx1 * diffx1) + (diffy1 * diffy1)); + + this.calculatedValues[i, j].CV_dResultMagnitude1_dDiffX1 = dResultMagnitude1_dDiffX1; + this.calculatedValues[i, j].CV_dResultMagnitude1_dDiffY1 = dResultMagnitude1_dDiffY1; + this.calculatedValues[i, j].CV_dResultAngle1_dDiffX1 = dResultAngle1_dDiffX1; + this.calculatedValues[i, j].CV_dResultAngle1_dDiffY1 = dResultAngle1_dDiffY1; + + double resultMagnitude2 = Math.Sqrt((diffx2 * diffx2) + (diffy2 * diffy2)); + double resultAngle2 = Math.Atan2(diffy2, diffx2); + + double dResultMagnitude2_dDiffX2 = diffx2 / resultMagnitude2; + double dResultMagnitude2_dDiffY2 = diffy2 / resultMagnitude2; + double dResultAngle2_dDiffX2 = -diffy2 / ((diffx2 * diffx2) + (diffy2 * diffy2)); + double dResultAngle2_dDiffY2 = diffx2 / ((diffx2 * diffx2) + (diffy2 * diffy2)); + + this.calculatedValues[i, j].CV_dResultMagnitude2_dDiffX2 = dResultMagnitude2_dDiffX2; + this.calculatedValues[i, j].CV_dResultMagnitude2_dDiffY2 = dResultMagnitude2_dDiffY2; + this.calculatedValues[i, j].CV_dResultAngle2_dDiffX2 = dResultAngle2_dDiffX2; + this.calculatedValues[i, j].CV_dResultAngle2_dDiffY2 = dResultAngle2_dDiffY2; + + this.Output[i, j * 6] = magnitude; + this.Output[i, (j * 6) + (this.input1.Cols * 6 / 2)] = angle; + + this.Output[i, (j * 6) + 1] = wMagnitudePivot; + this.Output[i, (j * 6) + 1 + (this.input1.Cols * 6 / 2)] = wAnglePivot; + + this.Output[i, (j * 6) + 2] = wMagnitude1; + this.Output[i, (j * 6) + 2 + (this.input1.Cols * 6 / 2)] = wAngle1; + + this.Output[i, (j * 6) + 3] = wMagnitude2; + this.Output[i, (j * 6) + 3 + (this.input1.Cols * 6 / 2)] = wAngle2; + + this.Output[i, (j * 6) + 4] = resultMagnitude1; + this.Output[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] = resultAngle1; + + this.Output[i, (j * 6) + 5] = resultMagnitude2; + this.Output[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] = resultAngle2; + } + }); + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + Matrix dInput1 = new Matrix(this.input1.Rows, this.input1.Cols); + Matrix dInput2 = new Matrix(this.input2.Rows, this.input2.Cols); + Matrix dWeights = new Matrix(this.weights.Rows, this.weights.Cols); + + Parallel.For(0, this.input1.Rows, i => + { + for (int j = 0; j < this.input1.Cols / 2; j++) + { + var grad = this.calculatedValues[i, j]; + + dInput1[i, j] += dOutput[i, j * 6]; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + (this.input1.Cols * 6 / 2)]; + + dInput1[i, j] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 4] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + + dInput1[i, j] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dMagnitude; + dInput1[i, j] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dMagnitude; + + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 5] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dX * grad.CV_dx_dAngle; + dInput1[i, j + (this.input1.Cols / 2)] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dY * grad.CV_dy_dAngle; + + dInput2[i, j * 3] += dOutput[i, (j * 6) + 1]; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 1 + (this.input1.Cols * 6 / 2)]; + + dInput2[i, (j * 3) + 1] += dOutput[i, (j * 6) + 2]; + dInput2[i, (j * 3) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 2 + (this.input1.Cols * 6 / 2)]; + + dInput2[i, (j * 3) + 2] += dOutput[i, (j * 6) + 3]; + dInput2[i, (j * 3) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 3 + (this.input1.Cols * 6 / 2)]; + + dInput2[i, j * 3] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 3] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + dInput2[i, j * 3] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 3] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + + dInput2[i, j * 3] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 3] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + dInput2[i, j * 3] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWMagnitudePivot; + dInput2[i, j * 3] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWMagnitudePivot; + + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dXPivot * grad.CV_dXPivot_dWAnglePivot; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + dInput2[i, (j * 3) + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dYPivot * grad.CV_dYPivot_dWAnglePivot; + + dInput2[i, (j * 3) + 1] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wMagnitude1; + dInput2[i, (j * 3) + 1] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wMagnitude1; + dInput2[i, (j * 3) + 1] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wMagnitude1; + dInput2[i, (j * 3) + 1] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wMagnitude1; + + dInput2[i, (j * 3) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wAngle1; + dInput2[i, (j * 3) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dX1 * grad.CV_dX1_wAngle1; + dInput2[i, (j * 3) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wAngle1; + dInput2[i, (j * 3) + 1 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dY1 * grad.CV_dY1_wAngle1; + + dInput2[i, (j * 3) + 2] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wMagnitude2; + dInput2[i, (j * 3) + 2] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wMagnitude2; + dInput2[i, (j * 3) + 2] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wMagnitude2; + dInput2[i, (j * 3) + 2] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wMagnitude2; + + dInput2[i, (j * 3) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wAngle2; + dInput2[i, (j * 3) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dX2 * grad.CV_dX2_wAngle2; + dInput2[i, (j * 3) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wAngle2; + dInput2[i, (j * 3) + 2 + (this.input2.Cols / 2)] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dY2 * grad.CV_dY2_wAngle2; + + dWeights[i, j] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 6) + 4] * grad.CV_dResultMagnitude1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dWeight; + dWeights[i, j] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffX1 * grad.CV_dDiffX1_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 6) + 4 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle1_dDiffY1 * grad.CV_dDiffY1_dSumY * grad.CV_dsumy_dWeight; + + dWeights[i, j] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 6) + 5] * grad.CV_dResultMagnitude2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dWeight; + dWeights[i, j] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffX2 * grad.CV_dDiffX2_dSumX * grad.CV_dsumx_dWeight; + dWeights[i, j] += dOutput[i, (j * 6) + 5 + (this.input1.Cols * 6 / 2)] * grad.CV_dResultAngle2_dDiffY2 * grad.CV_dDiffY2_dSumY * grad.CV_dsumy_dWeight; + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dInput1) + .AddInputGradient(dInput2) + .AddInputGradient(dWeights) + .Build(); + } + + private struct CalculatedValues + { + public double CV_dx_dMagnitude { get; internal set; } + + public double CV_dx_dAngle { get; internal set; } + + public double CV_dy_dMagnitude { get; internal set; } + + public double CV_dy_dAngle { get; internal set; } + + public double CV_dXPivot_dWMagnitudePivot { get; internal set; } + + public double CV_dXPivot_dWAnglePivot { get; internal set; } + + public double CV_dYPivot_dWMagnitudePivot { get; internal set; } + + public double CV_dYPivot_dWAnglePivot { get; internal set; } + + public double CV_dX1_wMagnitude1 { get; internal set; } + + public double CV_dX1_wAngle1 { get; internal set; } + + public double CV_dY1_wMagnitude1 { get; internal set; } + + public double CV_dY1_wAngle1 { get; internal set; } + + public double CV_dX2_wMagnitude2 { get; internal set; } + + public double CV_dX2_wAngle2 { get; internal set; } + + public double CV_dY2_wMagnitude2 { get; internal set; } + + public double CV_dY2_wAngle2 { get; internal set; } + + public double CV_dsumx_dX { get; internal set; } + + public double CV_dsumx_dXPivot { get; internal set; } + + public double CV_dsumx_dWeight { get; internal set; } + + public double CV_dsumy_dY { get; internal set; } + + public double CV_dsumy_dYPivot { get; internal set; } + + public double CV_dsumy_dWeight { get; internal set; } + + public double CV_dDiffX1_dSumX { get; internal set; } + + public double CV_dDiffX1_dX1 { get; internal set; } + + public double CV_dDiffY1_dSumY { get; internal set; } + + public double CV_dDiffY1_dY1 { get; internal set; } + + public double CV_dDiffX2_dSumX { get; internal set; } + + public double CV_dDiffX2_dX2 { get; internal set; } + + public double CV_dDiffY2_dSumY { get; internal set; } + + public double CV_dDiffY2_dY2 { get; internal set; } + + public double CV_dResultMagnitude1_dDiffX1 { get; internal set; } + + public double CV_dResultMagnitude1_dDiffY1 { get; internal set; } + + public double CV_dResultAngle1_dDiffX1 { get; internal set; } + + public double CV_dResultAngle1_dDiffY1 { get; internal set; } + + public double CV_dResultMagnitude2_dDiffX2 { get; internal set; } + + public double CV_dResultMagnitude2_dDiffY2 { get; internal set; } + + public double CV_dResultAngle2_dDiffX2 { get; internal set; } + + public double CV_dResultAngle2_dDiffY2 { get; internal set; } + } + } +} diff --git a/src/RMAD/PairwiseSineSoftmaxOperation.cs b/src/RMAD/PairwiseSineSoftmaxOperation.cs new file mode 100644 index 00000000..c18bbabf --- /dev/null +++ b/src/RMAD/PairwiseSineSoftmaxOperation.cs @@ -0,0 +1,117 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + + /// + /// Sine Softmax operation. + /// + public class PairwiseSineSoftmaxOperation : Operation + { + private Matrix input; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new PairwiseSineSoftmaxOperation(); + } + + /// + public override void Store(Guid id) + { + this.IntermediateMatrixArrays.AddOrUpdate(id, new[] { this.input, this.Output }, (x, y) => new[] { this.input, this.Output }); + } + + /// + public override void Restore(Guid id) + { + var restored = this.IntermediateMatrixArrays[id]; + this.input = restored[0]; + this.Output = restored[1]; + } + + /// + /// Performs the forward operation for the softmax function. + /// + /// The input to the softmax operation. + /// The output of the softmax operation. + public Matrix Forward(Matrix input) + { + this.input = input; + this.Output = this.PairedSineSoftmax(input); + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dLdOutput) + { + int numRows = this.Output.Length; + int numCols = this.Output[0].Length; + int m = numCols / 2; + + Matrix dLdInput = new Matrix(numRows, numCols); + for (int i = 0; i < numRows; i++) + { + for (int j = 0; j < m; j++) + { + double a = this.input[i, j]; + double b = this.input[i, j + m]; + double expSinA = Math.Exp(Math.Sin(a)); + double expSinB = Math.Exp(Math.Sin(b)); + + double f1 = expSinA; + double fPrime1 = Math.Cos(a) * expSinA; + double g1 = expSinA + expSinB; + double gPrime1 = Math.Cos(a) * expSinA; + double dSinSoftmaxj1 = ((fPrime1 * g1) - (f1 * gPrime1)) / Math.Pow(g1, 2d); + + double f2 = expSinB; + double fPrime2 = Math.Cos(b) * expSinB; + double g2 = expSinA + expSinB; + double gPrime2 = Math.Cos(b) * expSinB; + double dSinSoftmaxj2 = ((fPrime2 * g2) - (f2 * gPrime2)) / Math.Pow(g2, 2d); + + dLdInput[i][j] = dLdOutput[i][j] * dSinSoftmaxj1; + dLdInput[i][j + m] = dLdOutput[i][j + m] * dSinSoftmaxj2; + } + } + + return new BackwardResultBuilder() + .AddInputGradient(dLdInput) + .Build(); + } + + private Matrix PairedSineSoftmax(Matrix input) + { + int numRows = input.Rows; + int numCols = input.Cols; + int m = numCols / 2; + + Matrix output = new Matrix(numRows, numCols); + + for (int i = 0; i < numRows; i++) + { + for (int j = 0; j < m; j++) + { + double a = input[i, j]; + double b = input[i, j + m]; + double sumExp = Math.Exp(Math.Sin(a)) + Math.Exp(Math.Sin(b)); + double numerator1 = Math.Exp(Math.Sin(a)); + output[i, j] = numerator1 / sumExp; + double numerator2 = Math.Exp(Math.Sin(b)); + output[i, j + m] = numerator2 / sumExp; + } + } + + return output; + } + } +} diff --git a/src/RMAD/VectorAttentionBinaryOperation.cs b/src/RMAD/VectorAttentionBinaryOperation.cs new file mode 100644 index 00000000..5061ee15 --- /dev/null +++ b/src/RMAD/VectorAttentionBinaryOperation.cs @@ -0,0 +1,110 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Threading.Tasks; + + /// + /// Vector attention operation. + /// + public class VectorAttentionBinaryOperation : Operation + { + private Matrix vectors; + private Matrix probabilities; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new VectorAttentionBinaryOperation(); + } + + /// + /// Performs the forward operation for the vector attention function. + /// + /// The first input to the vector attention operation. + /// The second input to the vector attention operation. + /// The output of the vector attention operation. + public Matrix Forward(Matrix vectors, Matrix probabilities) + { + this.vectors = vectors; + this.probabilities = probabilities; + + this.Output = new Matrix(vectors.Rows, vectors.Cols); + + int m = vectors.Cols / 2; + + Parallel.For(0, vectors.Rows, i => + { + for (int j = 0; j < m; j++) + { + // Calculate the scaling factor for the magnitude + double prob = probabilities[i, j]; + double magnitudeScale = 1.5 - prob; // Ranges from 1 (at prob = 0.5) to 2 (at prob = 0) to 0.5 (at prob = 1) + double magnitude = vectors[i, j] * magnitudeScale; + + // Adjust the angle based on the probability + double angle = vectors[i, j + m]; + double angleAdjustment = Math.PI * (1 - prob); // Ranges from 0 (at prob = 1) to π (at prob = 0) + angle = (angle + angleAdjustment) % (2 * Math.PI); + + this.Output[i, j] = magnitude; + this.Output[i, j + m] = angle; + } + }); + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + Matrix dVectors = new Matrix(this.vectors.Rows, this.vectors.Cols); + Matrix dProbabilities = new Matrix(this.probabilities.Rows, this.probabilities.Cols); + + int m = this.vectors.Cols / 2; + Parallel.For(0, this.vectors.Rows, i => + { + for (int j = 0; j < m; j++) + { + double prop1 = this.probabilities[i, j]; + + // Gradient for magnitude + dVectors[i, j] = dOutput[i, j] * (1.5d - prop1); // Direct gradient flow for magnitude + + // Gradient for angle + double dAngle = dOutput[i, j + m]; + dVectors[i, j + m] = dAngle; // Direct gradient flow for angle + + double dAngle_dProb1 = -Math.PI; + double dAngle_dProb2 = Math.PI; + + // Gradient for Prob1 (affects magnitude and angle) + dProbabilities[i, j] = dAngle * dAngle_dProb1; // From derivative dAngle/dProb1 = -π + + // Gradient for Prob2 (affects only angle) + dProbabilities[i, j + m] = dAngle * dAngle_dProb2; // From derivative dAngle/dProb2 = π + + double dMagnitude = dOutput[i, j]; + double originalMagnitude = this.vectors[i, j]; + + // Compute gradients for probabilities related to magnitude + dProbabilities[i, j] += -dMagnitude * originalMagnitude; // dMagnitude/dProb1 + dProbabilities[i, j + m] += dMagnitude * originalMagnitude; // dMagnitude/dProb2 + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dVectors) + .AddInputGradient(dProbabilities) + .Build(); + } + } +} diff --git a/src/RMAD/VectorAttentionOperation.cs b/src/RMAD/VectorAttentionOperation.cs new file mode 100644 index 00000000..b671e942 --- /dev/null +++ b/src/RMAD/VectorAttentionOperation.cs @@ -0,0 +1,99 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Threading.Tasks; + + /// + /// Vector attention operation. + /// + public class VectorAttentionOperation : Operation + { + private Matrix vectors; + private Matrix probabilities; + + /// + /// A common method for instantiating an operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new VectorAttentionOperation(); + } + + /// + /// Performs the forward operation for the vector attention function. + /// + /// The first input to the vector attention operation. + /// The second input to the vector attention operation. + /// The output of the vector attention operation. + public Matrix Forward(Matrix vectors, Matrix probabilities) + { + this.vectors = vectors; + this.probabilities = probabilities; + + this.Output = new Matrix(vectors.Rows, vectors.Cols); + + int m = vectors.Cols / 2; + + Parallel.For(0, vectors.Rows, i => + { + for (int j = 0; j < m; j++) + { + // Calculate the scaling factor for the magnitude + double prob = probabilities[i, j]; + double magnitudeScale = 1.5 - prob; // Ranges from 1 (at prob = 0.5) to 2 (at prob = 0) to 0.5 (at prob = 1) + double magnitude = vectors[i, j] * magnitudeScale; + + // Adjust the angle based on the probability + double angle = vectors[i, j + m]; + double angleAdjustment = 1.5d * Math.PI * (1 - prob); // Ranges from 0 (at prob = 1) to 2π (at prob = 0) + angle = (angle + angleAdjustment) % (2 * Math.PI); + + this.Output[i, j] = magnitude; + this.Output[i, j + m] = angle; + } + }); + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dOutput) + { + Matrix dVectors = new Matrix(this.vectors.Rows, this.vectors.Cols); + Matrix dProbabilities = new Matrix(this.probabilities.Rows, this.probabilities.Cols); + + int m = this.vectors.Cols / 2; + Parallel.For(0, this.vectors.Rows, i => + { + for (int j = 0; j < m; j++) + { + double prob = this.probabilities[i, j]; + double dMagnitude_dProb = -dOutput[i, j] * this.vectors[i, j]; // Derivative of magnitude w.r.t probability + double dMagnitude_dProb2 = dOutput[i, j] * this.vectors[i, j]; // Derivative of magnitude w.r.t probability 2 + double dAngle_dProb = -1.5d * Math.PI * dOutput[i, j + m]; // Derivative of angle w.r.t probability + double dAngle_dProb2 = 1.5d * Math.PI * dOutput[i, j + m]; // Derivative of angle w.r.t probability 2 + + // Update gradients for vectors + dVectors[i, j] = dOutput[i, j] * (1.5 - prob); // Corrected gradient flow for magnitude + dVectors[i, j + m] = dOutput[i, j + m]; // Direct gradient flow for angle is correct + + // Aggregate gradients for probabilities + dProbabilities[i, j] = dMagnitude_dProb + dAngle_dProb; // Correct aggregation of gradients + dProbabilities[i, j + m] = dMagnitude_dProb2 + dAngle_dProb2; // Correct aggregation of gradients 2 + } + }); + + return new BackwardResultBuilder() + .AddInputGradient(dVectors) + .AddInputGradient(dProbabilities) + .Build(); + } + } +} diff --git a/src/RMAD/VectorizeOperation.cs b/src/RMAD/VectorizeOperation.cs new file mode 100644 index 00000000..2c73210c --- /dev/null +++ b/src/RMAD/VectorizeOperation.cs @@ -0,0 +1,139 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023 ameritusweb All rights reserved. +// +//------------------------------------------------------------------------------ +namespace ParallelReverseAutoDiff.RMAD +{ + using System; + using System.Collections.Generic; + + /// + /// Performs the forward and backward operations for the vectorize function. + /// + public class VectorizeOperation : Operation + { + private Matrix input; + private Matrix angles; + + /// + /// A common factory method for instantiating this operation. + /// + /// The neural network. + /// The instantiated operation. + public static IOperation Instantiate(NeuralNetwork net) + { + return new VectorizeOperation(); + } + + /// + public override void Store(Guid id) + { + this.IntermediateMatrices.AddOrUpdate(id, this.input, (x, y) => this.input); + } + + /// + public override void Restore(Guid id) + { + this.input = this.IntermediateMatrices[id]; + } + + /// + /// Performs the forward operation for the vectorize function. + /// + /// The input to the vectorize operation. + /// The angles to the vectorize operation. + /// The output of the vectorize operation. + public Matrix Forward(Matrix input, Matrix angles) + { + this.input = input; + this.angles = angles; + + int rows = input.Length; + int cols = input[0].Length; + + if (cols != angles[0].Length) + { + throw new ArgumentException("Input and angles matrices must have the same number of columns."); + } + + int m = cols * 2; + this.Output = new Matrix(rows, m); + + var angleMappings = new Dictionary<(double, double, double), double>(); + + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < cols; j++) + { + // Left half: magnitudes from input + this.Output[i][j] = input[i][j]; + + // Right half: angles with context + double prev = j > 0 ? input[i][j - 1] : double.MinValue; + double next = j < cols - 1 ? input[i][j + 1] : double.MaxValue; + var context = (prev, input[i][j], next); + + if (!angleMappings.ContainsKey(context)) + { + angleMappings[context] = angles[i][j]; // Store new angle for the context + } + + this.Output[i][cols + j] = angleMappings[context]; // Use the angle for the output matrix + } + } + + return this.Output; + } + + /// + public override BackwardResult Backward(Matrix dLdOutput) + { + int rows = dLdOutput.Length; + int cols = this.input[0].Length; + Matrix dLdInput = new Matrix(rows, cols); // Gradient with respect to input magnitudes + Matrix dLdAngles = new Matrix(rows, cols); // Gradient with respect to input angles + + var angleUsage = new Dictionary>(); // Tracks angle usage + + // Track the usage of each angle in the forward pass + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < cols; j++) + { + double angle = this.angles[i][j]; + if (!angleUsage.ContainsKey(angle)) + { + angleUsage[angle] = new List<(int, int)>(); + } + + angleUsage[angle].Add((i, j)); + } + } + + // Calculate the gradient for each angle based on its usage + foreach (var angle in angleUsage.Keys) + { + foreach (var (row, col) in angleUsage[angle]) + { + // Accumulate gradients from all outputs affected by this angle + dLdAngles[row][col] += dLdOutput[row][cols + col]; + } + } + + // Gradient for magnitudes is straightforward + for (int i = 0; i < rows; i++) + { + for (int j = 0; j < cols; j++) + { + dLdInput[i][j] = dLdOutput[i][j]; + } + } + + return new BackwardResultBuilder() + .AddInputGradient(dLdInput) + .AddInputGradient(dLdAngles) + .Build(); + } + } +} diff --git a/src/docs/README.md b/src/docs/README.md index 2ea869a1..e9c9db3f 100644 --- a/src/docs/README.md +++ b/src/docs/README.md @@ -127,6 +127,8 @@ MatrixConcatenateOperation MatrixDiagonalFilterOperation +MatrixHorizontalConcatenateOperation + MatrixMultiplyOperation MatrixMultiplyAndSumOperation @@ -197,6 +199,30 @@ DeepScaleAndShiftOperation FlattenOperation +### Vector Neural Network (VNN) Operations +These types of operations typically operate on instances of the Matrix class where the left half are magnitudes and the right half are angles in radians. +Learn more about Vector Neural Networks [here](https://www.amazon.com/Vector-Neural-Networks-Geometric-Tensors-ebook/dp/B0CXBV3DY5/ref=sr_1_1). + +ElementwiseSquareOperation + +ElementwiseVectorAddOperation + +ElementwiseVectorCartesianSummationOperation + +ElementwiseVectorConstituentMultiplyOperation + +ElementwiseVectorDecompositionOperation + +ElementwiseVectorMiniDecompositionOperation + +PairwiseSineSoftmaxOperation + +VectorAttentionBinaryOperation + +VectorAttentionOperation + +VectorizeOperation + ### Neural Network Parameters Each neural network base class has a set of parameters that can be used to configure the neural network. They are as follows: