Hi,

The function gsl_linalg_complex_householder_hv(tau, v, w) [apply the
Householder transform defined by (tau, v) to the vector w] does not
check for the mildly pathological case where length of the involved
vectors is 1. In this case, a subvector()-call in the code cannot be
executed as it exceeds the index limits and the code breaks.

I encountered this problem when implementing the QR decomposition for
complex-valued matrices.


In the real-valued case, a vector of length 1 results in tau=0 when
calculating the HH transform using gsl_linalg_householder_transform()
and the corresponding function gsl_linalg_househoulder_hv() explicitly
checks for tau=0 and exits in this case.

In the complex-valued case, the HH transform of a vector of length 1
does *not* necessarily imply tau=0 which is why the case N=1 has to be
handled separately in gsl_linalg_complex_householder_hv().


I have attached a patch for linalg/householdercomplex.c which handles
the N=1 case.

To be patched against GSL 2.4; I have cloned the github repository a few
days ago. As that's my first patch, please let me know if I need to
provide anything else or if a different format would be better.

Christian
--- householdercomplex.c	2017-11-27 14:35:24.665197607 +0000
+++ householdercomplex.new.c	2017-11-27 14:35:40.105198153 +0000
@@ -1,6 +1,7 @@
 /* linalg/householdercomplex.c
  * 
  * Copyright (C) 2001, 2007 Brian Gough
+ * Copyright (C) 2017 Christian Krueger (bugfix in gsl_linalg_complex_householder_hv)
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -228,6 +229,19 @@
   if (GSL_REAL(tau) == 0.0 && GSL_IMAG(tau) == 0.0)
       return GSL_SUCCESS;
 
+  /* treat the N=1 case separately */
+  if (N == 1)
+    {
+      gsl_complex w0 = gsl_vector_complex_get(w, 0);
+      gsl_complex tz = gsl_complex_mul(tau, w0);
+      gsl_complex ntz = gsl_complex_negative(tz);
+      gsl_complex w0ntz = gsl_complex_add(w0, ntz);
+
+      gsl_vector_complex_set(w, 0, w0ntz);
+
+      return GSL_SUCCESS;
+    }
+
   {
     /* compute z = v'w */
 

Reply via email to