tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
eigs_d.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 #include <tensor/linalg.h>
21 #include <tensor/arpack_d.h>
22 #include "gemv.cc"
23 
24 namespace linalg {
25 
26  using namespace tensor;
27 
28  RTensor
29  eigs(const RTensor &A, int eig_type, size_t neig, RTensor *eigenvectors,
30  const RTensor::elt_t *initial_guess)
31  {
32  EigType t = (EigType)eig_type;
33  size_t n = A.columns();
34 
35  if ((A.rank() != 2) || (A.rows() != n)) {
36  std::cerr << "In eigs(): Can only compute eigenvalues of square matrices.";
37  abort();
38  }
39 
40  if (neig > n || neig == 0) {
41  std::cerr << "In eigs(): Can only compute up to " << n << " eigenvalues\n"
42  << "in a matrix that has " << n << " times " << n << " elements.";
43  abort();
44  }
45 
46  if (n <= 4) {
47  /* For small sizes, the ARPACK solver produces wrong results!
48  * In any case, for these sizes it is more efficient to do the solving
49  * using the full routine.
50  */
51  CTensor vectors;
52  CTensor values = eig(A, NULL, eigenvectors? &vectors : 0);
53  Indices ndx = RArpack::sort_values(values, t);
54  Indices ndx_out(neig);
55  std::copy(ndx.begin(), ndx.begin() + neig, ndx_out.begin());
56  if (eigenvectors) {
57  *eigenvectors = tensor::real(vectors(range(), range(ndx_out)));
58  }
59  return tensor::real(values(range(ndx_out)));
60  }
61 
62  RTensor output;
63  {
64  RArpack data(n, t, neig);
65 
66  if (initial_guess)
67  data.set_start_vector(initial_guess);
68 
69  while (data.update() < RArpack::Finished) {
70  blas::gemv('N', n, n, 1.0, A.begin(), n, data.get_x_vector(), 1,
71  0.0, data.get_y_vector(), 1);
72  }
73  if (data.get_status() != RArpack::Finished) {
74  std::cerr << data.error_message() << '\n';
75  abort();
76  }
77  output = data.get_data(eigenvectors);
78  }
79  return output;
80  }
81 
82 } // 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
Real Tensor with elements of type "double".
Definition: tensor.h:349
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