Add non-sym eigen value computation.
diff --git a/TensorMath.lua b/TensorMath.lua
index 50d3158..74bc89c 100644
--- a/TensorMath.lua
+++ b/TensorMath.lua
@@ -986,6 +986,18 @@
                       {name='charoption', values={'N', 'V'}, default='N'},
                       {name='charoption', values={'U', 'L'}, default='U'}}
                   )
+      interface:wrap("reig",
+                     cname("geev"),
+                     {{name=Tensor, returned=true},
+                      {name=Tensor, returned=true},
+                      {name=Tensor},
+                      {name='charoption', values={'N', 'V'}, default='N'}},
+                     cname("geev"),
+                     {{name=Tensor, default=true, returned=true, invisible=true},
+                      {name=Tensor, default=true, returned=true, invisible=true},
+                      {name=Tensor},
+                      {name='charoption', values={'N', 'V'}, default='N'}}
+                  )
 
       interface:wrap("svd",
                      cname("gesvd"),
diff --git a/lib/TH/generic/THLapack.c b/lib/TH/generic/THLapack.c
index 1816edb..44ac046 100644
--- a/lib/TH/generic/THLapack.c
+++ b/lib/TH/generic/THLapack.c
@@ -48,6 +48,21 @@
 #endif
 }
 
+void THLapack_(geev)(char jobvl, char jobvr, int n, real *a, int lda, real *wr, real *wi, real* vl, int ldvl, real *vr, int ldvr, real *work, int lwork, int *info)
+{
+#ifdef USE_LAPACK
+#if defined(TH_REAL_IS_DOUBLE)
+  extern void dgeev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *wr, double *wi, double* vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info);
+  dgeev_(&jobvl, &jobvr, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr, work, &lwork, info);
+#else
+  extern void sgeev_(char *jobvl, char *jobvr, int *n, float *a, int *lda, float *wr, float *wi, float* vl, int *ldvl, float *vr, int *ldvr, float *work, int *lwork, int *info);
+  sgeev_(&jobvl, &jobvr, &n, a, &lda, wr, wi, vl, &ldvl, vr, &ldvr, work, &lwork, info);
+#endif
+#else
+  THError("geev : Lapack library not found in compile time\n");
+#endif
+}
+
 void THLapack_(gesvd)(char jobu, char jobvt, int m, int n, real *a, int lda, real *s, real *u, int ldu, real *vt, int ldvt, real *work, int lwork, int *info)
 {
 #ifdef USE_LAPACK
diff --git a/lib/TH/generic/THLapack.h b/lib/TH/generic/THLapack.h
index 44eb093..3c2b4e8 100644
--- a/lib/TH/generic/THLapack.h
+++ b/lib/TH/generic/THLapack.h
@@ -10,6 +10,8 @@
 void THLapack_(gels)(char trans, int m, int n, int nrhs, real *a, int lda, real *b, int ldb, real *work, int lwork, int *info);
 /* Eigenvals */
 void THLapack_(syev)(char jobz, char uplo, int n, real *a, int lda, real *w, real *work, int lwork, int *info);
+/* Non-sym eigenvals */
+void THLapack_(geev)(char jobvl, char jobvr, int n, real *a, int lda, real *wr, real *wi, real* vl, int ldvl, real *vr, int ldvr, real *work, int lwork, int *info);
 /* svd */
 void THLapack_(gesvd)(char jobu, char jobvt, int m, int n, real *a, int lda, real *s, real *u, int ldu, real *vt, int ldvt, real *work, int lwork, int *info);
 /* LU decomposition */
diff --git a/lib/TH/generic/THTensorLapack.c b/lib/TH/generic/THTensorLapack.c
index 1ba025a..c8e9751 100644
--- a/lib/TH/generic/THTensorLapack.c
+++ b/lib/TH/generic/THTensorLapack.c
@@ -190,6 +190,72 @@
   THTensor_(free)(work);
 }
 
+TH_API void THTensor_(geev)(THTensor *re_, THTensor *rv_, THTensor *a_, const char *jobvr)
+{
+  int n, lda, lwork, info, ldvr;
+  THTensor *work, *wi, *wr, *a;
+  real wkopt;
+  real *rv_data;
+  long i;
+
+  THArgCheck(a_->nDimension == 2, 3, "A should be 2 dimensional");
+  THArgCheck(a_->size[0] == a_->size[1], 3,"A should be square");
+
+  /* we want to definitely clone */
+  a = THTensor_(new)();
+  THTensor_(lapackClone)(a,a_,1);
+  
+  n = a->size[0];
+  lda = n;
+
+  wi = THTensor_(new)();
+  wr = THTensor_(new)();
+  THTensor_(resize2d)(re_,n,2);
+  THTensor_(resize1d)(wi,n);
+  THTensor_(resize1d)(wr,n);
+
+  rv_data = NULL;
+  ldvr = 1;
+  if (*jobvr == 'V')
+  {
+    THTensor_(resize2d)(rv_,n,n);
+    rv_data = THTensor_(data)(rv_);
+    ldvr = n;
+  }
+  // get optimal workspace size
+  THLapack_(geev)('N', jobvr[0], n, THTensor_(data)(a), lda, THTensor_(data)(wr), THTensor_(data)(wi), 
+      NULL, 1, rv_data, ldvr, &wkopt, -1, &info);
+
+  lwork = (int)wkopt;
+  work = THTensor_(newWithSize1d)(lwork);
+
+  THLapack_(geev)('N', jobvr[0], n, THTensor_(data)(a), lda, THTensor_(data)(wr), THTensor_(data)(wi), 
+      NULL, 1, rv_data, ldvr, THTensor_(data)(work), lwork, &info);
+
+  if (info > 0)
+  {
+    THError(" Lapack geev : Failed to converge. %d off-diagonal elements of an didn't converge to zero",info);
+  }
+  else if (info < 0)
+  {
+    THError("Lapack geev : Argument %d : illegal value", -info);
+  }
+
+  real *re_data = THTensor_(data)(re_);
+  real *wi_data = THTensor_(data)(wi);
+  real *wr_data = THTensor_(data)(wr);
+  for (i=0; i<n; i++)
+  {
+    re_data[2*i] = wr_data[i];
+    re_data[2*i+1] = wi_data[i];
+  }
+  THTensor_(transpose)(rv_,NULL,0,1);
+  THTensor_(free)(a);
+  THTensor_(free)(wi);
+  THTensor_(free)(wr);
+  THTensor_(free)(work);
+}
+
 TH_API void THTensor_(syev)(THTensor *re_, THTensor *rv_, THTensor *a, const char *jobz, const char *uplo)
 {
   int n, lda, lwork, info;
diff --git a/lib/TH/generic/THTensorLapack.h b/lib/TH/generic/THTensorLapack.h
index de7715e..1b17907 100644
--- a/lib/TH/generic/THTensorLapack.h
+++ b/lib/TH/generic/THTensorLapack.h
@@ -5,6 +5,7 @@
 TH_API void THTensor_(gesv)(THTensor *rb_, THTensor *ra_, THTensor *b_, THTensor *a_);
 TH_API void THTensor_(gels)(THTensor *rb_, THTensor *ra_, THTensor *b_, THTensor *a_);
 TH_API void THTensor_(syev)(THTensor *re_, THTensor *rv_, THTensor *a_, const char *jobz, const char *uplo);
+TH_API void THTensor_(geev)(THTensor *re_, THTensor *rv_, THTensor *a_, const char *jobvr);
 TH_API void THTensor_(gesvd)(THTensor *ru_, THTensor *rs_, THTensor *rv_, THTensor *a, const char *jobu);
 TH_API void THTensor_(gesvd2)(THTensor *ru_, THTensor *rs_, THTensor *rv_, THTensor *ra_, THTensor *a, const char *jobu);
 TH_API void THTensor_(getri)(THTensor *ra_, THTensor *a);