From abde0fa6ee3b813e05a9fcf7bff8c6cedfc5e996 Mon Sep 17 00:00:00 2001
From: Daniel Waggoner <dwaggoner@frbatlanta.org>
Date: Wed, 7 Mar 2012 18:28:31 -0500
Subject: [PATCH] added UpdateTransposeProductMM() to dw_matrix (cherry picked
 from commit 20e23a5850f7af46af95e8cd4df8ef92f0a32f9f)

---
 matrix/dw_matrix.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/matrix/dw_matrix.c b/matrix/dw_matrix.c
index fb978ba..128fd7e 100644
--- a/matrix/dw_matrix.c
+++ b/matrix/dw_matrix.c
@@ -1558,6 +1558,54 @@ TMatrix UpdateProductMM(PRECISION a, TMatrix X, PRECISION b, TMatrix Y, TMatrix
     bProductMM_Update(pElementM(X),pElementM(Y),pElementM(Z),a,b,RowM(X),ColM(X),ColM(Y),MajorForm(X),MajorForm(Y),MajorForm(Z));
   return X;
 }
+
+/*
+   Assumes
+     a : scalar
+     X : m x n matrix
+     b : scalar
+     Y : m x k matrix
+     Z : k x n matrix
+
+   Results
+     X = a*X + b*Y'*Z
+
+   Returns
+     Returns X upon success and null on failure.  Call GetError() to
+     determine the cause of failure.
+
+   Notes
+     X, Y, and Z do not have to be distinct matrices.
+*/
+TMatrix UpdateTransposeProductMM(PRECISION a, TMatrix X, PRECISION b, TMatrix Y, TMatrix Z)
+{
+  PRECISION *ptr;
+  if (!X || !Y || ! Z)
+    {
+      dw_Error(NULL_ERR);
+      return (TMatrix)NULL;
+    }
+  if ((RowM(X) != RowM(Y)) || (ColM(X) != ColM(Z)) || (ColM(Y) != RowM(Z)))
+    {
+      dw_Error(SIZE_ERR);
+      return (TMatrix)NULL;
+    }
+  if ((X == Y) || (X == Z))
+    {
+      if (!(ptr=(PRECISION*)dw_malloc(RowM(X)*ColM(X)*sizeof(PRECISION))))
+	{
+	  dw_Error(MEM_ERR); 
+	  return (TMatrix)NULL; 
+	}
+      memcpy(ptr,pElementM(X),RowM(X)*ColM(X)*sizeof(PRECISION));
+      bProductMM_Update(pElementM(X),(X == Y) ? ptr : pElementM(Y),(X == Z) ? ptr : pElementM(Z),a,b,RowM(X),
+			    ColM(X),ColM(Y),MajorForm(X),1^MajorForm(Y),MajorForm(Z));
+      dw_free(ptr);
+    }
+  else
+    bProductMM_Update(pElementM(X),pElementM(Y),pElementM(Z),a,b,RowM(X),ColM(X),ColM(Y),MajorForm(X),1^MajorForm(Y),MajorForm(Z));
+  return X;
+}
 /*******************************************************************************/
 /*******************************************************************************/
 /*******************************************************************************/
-- 
GitLab