[libcamera-devel,v1,05/10] ipa: raspberrypi: alsc: Use a better type name for sparse arrays
diff mbox series

Message ID 20230322130612.5208-6-naush@raspberrypi.com
State Superseded
Headers show
Series
  • Raspberry Pi: Generalised algorithms
Related show

Commit Message

Naushir Patuck March 22, 2023, 1:06 p.m. UTC
From: David Plowman <david.plowman@raspberrypi.com>

The algorithm uses the data type std::vector<std::array<double, 4>> to
represent the large sparse matrices that are XY (X, Y being the ALSC
grid size) high but with only 4 non-zero elements on each row.

Replace this slightly long type name by SparseArray<double>.

No functional changes.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
---
 src/ipa/raspberrypi/controller/rpi/alsc.cpp | 24 ++++++++++-----------
 src/ipa/raspberrypi/controller/rpi/alsc.h   | 10 ++++++++-
 2 files changed, 21 insertions(+), 13 deletions(-)

Comments

Jacopo Mondi March 24, 2023, 8:55 a.m. UTC | #1
Hi David

On Wed, Mar 22, 2023 at 01:06:07PM +0000, Naushir Patuck via libcamera-devel wrote:
> From: David Plowman <david.plowman@raspberrypi.com>
>
> The algorithm uses the data type std::vector<std::array<double, 4>> to
> represent the large sparse matrices that are XY (X, Y being the ALSC
> grid size) high but with only 4 non-zero elements on each row.
>
> Replace this slightly long type name by SparseArray<double>.

Nicer to read indeed
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

Thanks
  j

>
> No functional changes.
>
> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
> ---
>  src/ipa/raspberrypi/controller/rpi/alsc.cpp | 24 ++++++++++-----------
>  src/ipa/raspberrypi/controller/rpi/alsc.h   | 10 ++++++++-
>  2 files changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> index 524c48093590..3a2e8fe00ca6 100644
> --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
> @@ -607,7 +607,7 @@ static double computeWeight(double Ci, double Cj, double sigma)
>
>  /* Compute all weights. */
>  static void computeW(const Array2D<double> &C, double sigma,
> -		     std::vector<std::array<double, 4>> &W)
> +		     SparseArray<double> &W)
>  {
>  	size_t XY = C.size();
>  	size_t X = C.dimensions().width;
> @@ -623,8 +623,8 @@ static void computeW(const Array2D<double> &C, double sigma,
>
>  /* Compute M, the large but sparse matrix such that M * lambdas = 0. */
>  static void constructM(const Array2D<double> &C,
> -		       const std::vector<std::array<double, 4>> &W,
> -		       std::vector<std::array<double, 4>> &M)
> +		       const SparseArray<double> &W,
> +		       SparseArray<double> &M)
>  {
>  	size_t XY = C.size();
>  	size_t X = C.dimensions().width;
> @@ -651,37 +651,37 @@ static void constructM(const Array2D<double> &C,
>   * left/right neighbours are zero down the left/right edges, so we don't need
>   * need to test the i value to exclude them.
>   */
> -static double computeLambdaBottom(int i, const std::vector<std::array<double, 4>> &M,
> +static double computeLambdaBottom(int i, const SparseArray<double> &M,
>  				  Array2D<double> &lambda)
>  {
>  	return M[i][1] * lambda[i + 1] + M[i][2] * lambda[i + lambda.dimensions().width] +
>  	       M[i][3] * lambda[i - 1];
>  }
> -static double computeLambdaBottomStart(int i, const std::vector<std::array<double, 4>> &M,
> +static double computeLambdaBottomStart(int i, const SparseArray<double> &M,
>  				       Array2D<double> &lambda)
>  {
>  	return M[i][1] * lambda[i + 1] + M[i][2] * lambda[i + lambda.dimensions().width];
>  }
> -static double computeLambdaInterior(int i, const std::vector<std::array<double, 4>> &M,
> +static double computeLambdaInterior(int i, const SparseArray<double> &M,
>  				    Array2D<double> &lambda)
>  {
>  	return M[i][0] * lambda[i - lambda.dimensions().width] + M[i][1] * lambda[i + 1] +
>  	       M[i][2] * lambda[i + lambda.dimensions().width] + M[i][3] * lambda[i - 1];
>  }
> -static double computeLambdaTop(int i, const std::vector<std::array<double, 4>> &M,
> +static double computeLambdaTop(int i, const SparseArray<double> &M,
>  			       Array2D<double> &lambda)
>  {
>  	return M[i][0] * lambda[i - lambda.dimensions().width] + M[i][1] * lambda[i + 1] +
>  	       M[i][3] * lambda[i - 1];
>  }
> -static double computeLambdaTopEnd(int i, const std::vector<std::array<double, 4>> &M,
> +static double computeLambdaTopEnd(int i, const SparseArray<double> &M,
>  				  Array2D<double> &lambda)
>  {
>  	return M[i][0] * lambda[i - lambda.dimensions().width] + M[i][3] * lambda[i - 1];
>  }
>
>  /* Gauss-Seidel iteration with over-relaxation. */
> -static double gaussSeidel2Sor(const std::vector<std::array<double, 4>> &M, double omega,
> +static double gaussSeidel2Sor(const SparseArray<double> &M, double omega,
>  			      Array2D<double> &lambda, double lambdaBound)
>  {
>  	int XY = lambda.size();
> @@ -753,8 +753,8 @@ static void reaverage(Array2D<double> &data)
>
>  static void runMatrixIterations(const Array2D<double> &C,
>  				Array2D<double> &lambda,
> -				const std::vector<std::array<double, 4>> &W,
> -				std::vector<std::array<double, 4>> &M, double omega,
> +				const SparseArray<double> &W,
> +				SparseArray<double> &M, double omega,
>  				unsigned int nIter, double threshold, double lambdaBound)
>  {
>  	constructM(C, W, M);
> @@ -813,7 +813,7 @@ void Alsc::doAlsc()
>  {
>  	Array2D<double> &cr = tmpC_[0], &cb = tmpC_[1], &calTableR = tmpC_[2],
>  			&calTableB = tmpC_[3], &calTableTmp = tmpC_[4];
> -	std::vector<std::array<double, 4>> &wr = tmpM_[0], &wb = tmpM_[1], &M = tmpM_[2];
> +	SparseArray<double> &wr = tmpM_[0], &wb = tmpM_[1], &M = tmpM_[2];
>
>  	/*
>  	 * Calculate our R/B ("Cr"/"Cb") colour statistics, and assess which are
> diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.h b/src/ipa/raspberrypi/controller/rpi/alsc.h
> index 1ab61299c4cd..0b6d9478073c 100644
> --- a/src/ipa/raspberrypi/controller/rpi/alsc.h
> +++ b/src/ipa/raspberrypi/controller/rpi/alsc.h
> @@ -68,6 +68,14 @@ private:
>  	std::vector<T> data_;
>  };
>
> +/*
> + * We'll use the term SparseArray for the large sparse matrices that are
> + * XY tall but have only 4 non-zero elements on each row.
> + */
> +
> +template<typename T>
> +using SparseArray = std::vector<std::array<T, 4>>;
> +
>  struct AlscCalibration {
>  	double ct;
>  	Array2D<double> table;
> @@ -160,7 +168,7 @@ private:
>
>  	/* Temporaries for the computations */
>  	std::array<Array2D<double>, 5> tmpC_;
> -	std::array<std::vector<std::array<double, 4>>, 3> tmpM_;
> +	std::array<SparseArray<double>, 3> tmpM_;
>  };
>
>  } /* namespace RPiController */
> --
> 2.34.1
>

Patch
diff mbox series

diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
index 524c48093590..3a2e8fe00ca6 100644
--- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp
+++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
@@ -607,7 +607,7 @@  static double computeWeight(double Ci, double Cj, double sigma)
 
 /* Compute all weights. */
 static void computeW(const Array2D<double> &C, double sigma,
-		     std::vector<std::array<double, 4>> &W)
+		     SparseArray<double> &W)
 {
 	size_t XY = C.size();
 	size_t X = C.dimensions().width;
@@ -623,8 +623,8 @@  static void computeW(const Array2D<double> &C, double sigma,
 
 /* Compute M, the large but sparse matrix such that M * lambdas = 0. */
 static void constructM(const Array2D<double> &C,
-		       const std::vector<std::array<double, 4>> &W,
-		       std::vector<std::array<double, 4>> &M)
+		       const SparseArray<double> &W,
+		       SparseArray<double> &M)
 {
 	size_t XY = C.size();
 	size_t X = C.dimensions().width;
@@ -651,37 +651,37 @@  static void constructM(const Array2D<double> &C,
  * left/right neighbours are zero down the left/right edges, so we don't need
  * need to test the i value to exclude them.
  */
-static double computeLambdaBottom(int i, const std::vector<std::array<double, 4>> &M,
+static double computeLambdaBottom(int i, const SparseArray<double> &M,
 				  Array2D<double> &lambda)
 {
 	return M[i][1] * lambda[i + 1] + M[i][2] * lambda[i + lambda.dimensions().width] +
 	       M[i][3] * lambda[i - 1];
 }
-static double computeLambdaBottomStart(int i, const std::vector<std::array<double, 4>> &M,
+static double computeLambdaBottomStart(int i, const SparseArray<double> &M,
 				       Array2D<double> &lambda)
 {
 	return M[i][1] * lambda[i + 1] + M[i][2] * lambda[i + lambda.dimensions().width];
 }
-static double computeLambdaInterior(int i, const std::vector<std::array<double, 4>> &M,
+static double computeLambdaInterior(int i, const SparseArray<double> &M,
 				    Array2D<double> &lambda)
 {
 	return M[i][0] * lambda[i - lambda.dimensions().width] + M[i][1] * lambda[i + 1] +
 	       M[i][2] * lambda[i + lambda.dimensions().width] + M[i][3] * lambda[i - 1];
 }
-static double computeLambdaTop(int i, const std::vector<std::array<double, 4>> &M,
+static double computeLambdaTop(int i, const SparseArray<double> &M,
 			       Array2D<double> &lambda)
 {
 	return M[i][0] * lambda[i - lambda.dimensions().width] + M[i][1] * lambda[i + 1] +
 	       M[i][3] * lambda[i - 1];
 }
-static double computeLambdaTopEnd(int i, const std::vector<std::array<double, 4>> &M,
+static double computeLambdaTopEnd(int i, const SparseArray<double> &M,
 				  Array2D<double> &lambda)
 {
 	return M[i][0] * lambda[i - lambda.dimensions().width] + M[i][3] * lambda[i - 1];
 }
 
 /* Gauss-Seidel iteration with over-relaxation. */
-static double gaussSeidel2Sor(const std::vector<std::array<double, 4>> &M, double omega,
+static double gaussSeidel2Sor(const SparseArray<double> &M, double omega,
 			      Array2D<double> &lambda, double lambdaBound)
 {
 	int XY = lambda.size();
@@ -753,8 +753,8 @@  static void reaverage(Array2D<double> &data)
 
 static void runMatrixIterations(const Array2D<double> &C,
 				Array2D<double> &lambda,
-				const std::vector<std::array<double, 4>> &W,
-				std::vector<std::array<double, 4>> &M, double omega,
+				const SparseArray<double> &W,
+				SparseArray<double> &M, double omega,
 				unsigned int nIter, double threshold, double lambdaBound)
 {
 	constructM(C, W, M);
@@ -813,7 +813,7 @@  void Alsc::doAlsc()
 {
 	Array2D<double> &cr = tmpC_[0], &cb = tmpC_[1], &calTableR = tmpC_[2],
 			&calTableB = tmpC_[3], &calTableTmp = tmpC_[4];
-	std::vector<std::array<double, 4>> &wr = tmpM_[0], &wb = tmpM_[1], &M = tmpM_[2];
+	SparseArray<double> &wr = tmpM_[0], &wb = tmpM_[1], &M = tmpM_[2];
 
 	/*
 	 * Calculate our R/B ("Cr"/"Cb") colour statistics, and assess which are
diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.h b/src/ipa/raspberrypi/controller/rpi/alsc.h
index 1ab61299c4cd..0b6d9478073c 100644
--- a/src/ipa/raspberrypi/controller/rpi/alsc.h
+++ b/src/ipa/raspberrypi/controller/rpi/alsc.h
@@ -68,6 +68,14 @@  private:
 	std::vector<T> data_;
 };
 
+/*
+ * We'll use the term SparseArray for the large sparse matrices that are
+ * XY tall but have only 4 non-zero elements on each row.
+ */
+
+template<typename T>
+using SparseArray = std::vector<std::array<T, 4>>;
+
 struct AlscCalibration {
 	double ct;
 	Array2D<double> table;
@@ -160,7 +168,7 @@  private:
 
 	/* Temporaries for the computations */
 	std::array<Array2D<double>, 5> tmpC_;
-	std::array<std::vector<std::array<double, 4>>, 3> tmpM_;
+	std::array<SparseArray<double>, 3> tmpM_;
 };
 
 } /* namespace RPiController */