title: viennacl with complex numbers
body: <p>I'm using <a href="http://viennacl.sourceforge.net/" rel="nofollow">viennacl</a> to solve a linear system of equations (AX = B) with the graphic card. Also, the code uses <a href="http://arma.sourceforge.net" rel="nofollow">armadillo</a>.</p>
  
  <p>My system of equations have complex numbers. So the question is: Can I solve a system of equations (with complex numbers) using viennacl?</p>
  
  <p>Above is an example of a working code with real numbers.</p>
  
  <pre><code>// System headers
  #include &lt;iostream&gt;
  
  // Armadillo headers (disable BLAS and LAPACK to avoid linking issues)
  #define ARMA_DONT_USE_BLAS
  #define ARMA_DONT_USE_LAPACK
  #include &lt;armadillo&gt;
  #include &lt;complex&gt;
  
  #define VIENNACL_WITH_ARMADILLO 1
  
  // ViennaCL headers
  #include "viennacl/linalg/cg.hpp"
  #include "viennacl/linalg/bicgstab.hpp"
  #include "viennacl/linalg/gmres.hpp"
  #include "viennacl/io/matrix_market.hpp"
  #include "vector-io.hpp"
  
  //using namespace arma;
  using namespace viennacl::linalg;
  using namespace std;
  
  typedef arma::mat armat;
  typedef arma::vec arvec;
  
  typedef complex&lt;double&gt; dcmplx;
  
  int main(void)
  {
  
      int N = 500;
      armat A(N,N);
      A.randu();
      arvec B(N);
      B.randu();
      arvec X(N);
      arvec residual(N);
  
      viennacl::matrix&lt;double&gt; vcl_A(N, N);
      viennacl::vector&lt;double&gt; vcl_B(N);
      viennacl::vector&lt;double&gt; vcl_X(N);
      viennacl::vector&lt;double&gt; vcl_result(N);
  
      viennacl::copy(A, vcl_A);
      viennacl::copy(B, vcl_B);
      viennacl::copy(X, vcl_X);
  
      std::cout &lt;&lt; "----- Running GMRES -----" &lt;&lt; std::endl;
      vcl_X = viennacl::linalg::solve(vcl_A, vcl_B,               viennacl::linalg::gmres_tag());
  
      viennacl::copy(vcl_A, A);
      viennacl::copy(vcl_B, B);
      viennacl::copy(vcl_X, X);
  
      residual = A * X - B;
      cout &lt;&lt; "Relative residual: " &lt;&lt; norm(residual) / norm(B) &lt;&lt; endl;
  }
  </code></pre>
  
  <p>Complex version of the code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  // Armadillo headers (disable BLAS and LAPACK to avoid linking issues)
  #define ARMA_DONT_USE_BLAS
  #define ARMA_DONT_USE_LAPACK
  #include &lt;armadillo&gt;
  #include &lt;complex&gt;
  
  #define VIENNACL_WITH_ARMADILLO 1
  
  // ViennaCL headers
  #include "viennacl/linalg/cg.hpp"
  #include "viennacl/linalg/bicgstab.hpp"
  #include "viennacl/linalg/gmres.hpp"
  #include "viennacl/io/matrix_market.hpp"
  #include "vector-io.hpp"
  
  
  //using namespace arma;
  using namespace viennacl::linalg;
  using namespace std;
  
  typedef arma::cx_mat armat;
  typedef arma::cx_vec arvec;
  
  typedef complex&lt;double&gt; dcmplx;
  
  int main(void)
  {
  
  int N = 500;
  armat A(N,N);
  A.randu();
  arvec B(N);
  B.randu();
  arvec X(N);
  arvec residual(N);
  
  viennacl::matrix&lt;dcmplx&gt; vcl_A(N, N);
  viennacl::vector&lt;dcmplx&gt; vcl_B(N);
  viennacl::vector&lt;dcmplx&gt; vcl_X(N);
  viennacl::vector&lt;dcmplx&gt; vcl_result(N);
  
  viennacl::copy(A, vcl_A);
  viennacl::copy(B, vcl_B);
  viennacl::copy(X, vcl_X);
  
  std::cout &lt;&lt; "----- Running GMRES -----" &lt;&lt; std::endl;
  vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::gmres_tag());
  
  viennacl::copy(vcl_A, A);
  viennacl::copy(vcl_B, B);
  viennacl::copy(vcl_X, X);
  
  residual = A * X - B;
  cout &lt;&lt; "Relative residual: " &lt;&lt; norm(residual) / norm(B) &lt;&lt; endl;
  
  
  
  std::cout &lt;&lt; "----- Running BiCGStab -----" &lt;&lt; std::endl;
  vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::bicgstab_tag());
  
  viennacl::copy(vcl_A, A);
  viennacl::copy(vcl_B, B);
  viennacl::copy(vcl_X, X);
  
  residual = A * X - B;
  cout &lt;&lt; "Relative residual: " &lt;&lt; norm(residual) / norm(B) &lt;&lt; endl;
  
  std::cout &lt;&lt; "----- Running CG -----" &lt;&lt; std::endl;
  vcl_X = viennacl::linalg::solve(vcl_A, vcl_B, viennacl::linalg::cg_tag());
  
  viennacl::copy(vcl_A, A);
  viennacl::copy(vcl_B, B);
  viennacl::copy(vcl_X, X);
  
  residual = A * X - B;
  cout &lt;&lt; "Relative residual: " &lt;&lt; norm(residual) / norm(B) &lt;&lt; endl;
  
  }
  </code></pre>