tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
eigs_z.cc
1 // -*- mode: c++; fill-column: 80; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 /*
3  Copyright (c) 2010 Juan Jose Garcia Ripoll
4 
5  Tensor is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published
7  by the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Library General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 //----------------------------------------------------------------------
21 // ARPACK DRIVER FOR NONSYMMETRIC EIGENVALUE PROBLEMS
22 //
23 
24 #include <tensor/linalg.h>
25 #include <tensor/arpack_z.h>
26 #include "gemv.cc"
27 
28 namespace linalg {
29 
30  using namespace tensor;
31 
32  CTensor
33  eigs(const CTensor &A, int eig_type, size_t neig, CTensor *eigenvectors,
34  const CTensor::elt_t *initial_guess)
35  {
36  EigType t = (EigType)eig_type;
37  size_t n = A.columns();
38 
39  if ((A.rank() != 2) || (A.rows() != n)) {
40  std::cerr << "In eigs(): Can only compute eigenvalues of square matrices.";
41  abort();
42  }
43 
44  if (neig > n || neig == 0) {
45  std::cerr << "In eigs(): Can only compute up to " << n << " eigenvalues\n"
46  << "in a matrix that has " << n << " times " << n << " elements.";
47  abort();
48  }
49 
50  if (n <= 4) {
51  /* For small sizes, the ARPACK solver produces wrong results!
52  * In any case, for these sizes it is more efficient to do the solving
53  * using the full routine.
54  */
55  CTensor vectors;
56  CTensor values = eig(A, NULL, eigenvectors? &vectors : 0);
57  Indices ndx = CArpack::sort_values(values, t);
58  Indices ndx_out(neig);
59  std::copy(ndx.begin(), ndx.begin() + neig, ndx_out.begin());
60  if (eigenvectors) {
61  *eigenvectors = vectors(range(), range(ndx_out));
62  }
63  return CTensor(values(range(ndx_out)));
64  }
65 
66  CTensor output;
67  {
68  CArpack data(n, t, neig);
69 
70  if (initial_guess)
71  data.set_start_vector(initial_guess);
72 
73  while (data.update() < CArpack::Finished) {
74  blas::gemv('N', n, n, number_one<cdouble>(), A.begin(), n, data.get_x_vector(), 1,
75  number_zero<cdouble>(), data.get_y_vector(), 1);
76  }
77  if (data.get_status() != CArpack::Finished) {
78  std::cerr << data.error_message() << '\n';
79  abort();
80  }
81  output = data.get_data(eigenvectors);
82  }
83  return output;
84  }
85 
86 } //namespace linalg
int rank() const
Number of Tensor indices.
Definition: tensor.h:119
const CTensor eig(const RTensor &A, CTensor *R=0, CTensor *L=0)
Eigenvalue decomposition of a real matrix.
Definition: eig_d.cc:45
index columns() const
Query the size of 2nd index.
Definition: tensor.h:137
index rows() const
Query then size of 1st index.
Definition: tensor.h:139
CTensor eigs(const CTensor &A, int eig_type, size_t neig, CTensor *vectors=NULL, const tensor::cdouble *initial_guess=NULL)
Find out a few eigenvalues and eigenvectors of a complex nonsymmetric matrix.
iterator begin()
Iterator at the beginning.
Definition: tensor.h:256
Complex Tensor with elements of type "cdouble".
Definition: tensor.h:435
Vector of 'index' type, where 'index' fits the indices of a tensor.
Definition: indices.h:35
EigType
Type of eigenvalues that eigs and Arpack compute.
Definition: linalg.h:69