メインページ   クラス階層   構成   ファイル一覧   構成メンバ   ファイルメンバ  

dbleSVD.cc

解説を見る。
00001 /*
00002 
00003 Copyright (C) 1996, 1997 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 2, or (at your option) any
00010 later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021 */
00022 
00023 #if defined (__GNUG__) && defined (USE_PRAGMA_INTERFACE_IMPLEMENTATION)
00024 #pragma implementation
00025 #endif
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030 
00031 #include <iostream>
00032 
00033 #include "dbleSVD.h"
00034 #include "f77-fcn.h"
00035 
00036 extern "C"
00037 {
00038   F77_RET_T
00039   F77_FUNC (dgesvd, DGESVD) (F77_CONST_CHAR_ARG_DECL,
00040                              F77_CONST_CHAR_ARG_DECL,
00041                              const int&, const int&, double*,
00042                              const int&, double*, double*,
00043                              const int&, double*, const int&,
00044                              double*, const int&, int&
00045                              F77_CHAR_ARG_LEN_DECL
00046                              F77_CHAR_ARG_LEN_DECL);
00047 }
00048 
00049 Matrix
00050 SVD::left_singular_matrix (void) const
00051 {
00052   if (type_computed == SVD::sigma_only)
00053     {
00054       (*current_liboctave_error_handler)
00055         ("ComplexSVD: U not computed because type == SVD::sigma_only");
00056       return Matrix ();
00057     }
00058   else
00059     return left_sm;
00060 }
00061 
00062 Matrix
00063 SVD::right_singular_matrix (void) const
00064 {
00065   if (type_computed == SVD::sigma_only)
00066     {
00067       (*current_liboctave_error_handler)
00068         ("ComplexSVD: V not computed because type == SVD::sigma_only");
00069       return Matrix ();
00070     }
00071   else
00072     return right_sm;
00073 }
00074 
00075 int
00076 SVD::init (const Matrix& a, SVD::type svd_type)
00077 {
00078   int info;
00079 
00080   int m = a.rows ();
00081   int n = a.cols ();
00082 
00083   Matrix atmp = a;
00084   double *tmp_data = atmp.fortran_vec ();
00085 
00086   int min_mn = m < n ? m : n;
00087 
00088   char jobu = 'A';
00089   char jobv = 'A';
00090 
00091   int ncol_u = m;
00092   int nrow_vt = n;
00093   int nrow_s = m;
00094   int ncol_s = n;
00095 
00096   switch (svd_type)
00097     {
00098     case SVD::economy:
00099       jobu = jobv = 'S';
00100       ncol_u = nrow_vt = nrow_s = ncol_s = min_mn;
00101       break;
00102 
00103     case SVD::sigma_only:
00104 
00105       // Note:  for this case, both jobu and jobv should be 'N', but
00106       // there seems to be a bug in dgesvd from Lapack V2.0.  To
00107       // demonstrate the bug, set both jobu and jobv to 'N' and find
00108       // the singular values of [eye(3), eye(3)].  The result is
00109       // [-sqrt(2), -sqrt(2), -sqrt(2)].
00110       //
00111       // For Lapack 3.0, this problem seems to be fixed.
00112 
00113       jobu = 'N';
00114       jobv = 'N';
00115       ncol_u = nrow_vt = 1;
00116       break;
00117 
00118     default:
00119       break;
00120     }
00121 
00122   type_computed = svd_type;
00123 
00124   if (! (jobu == 'N' || jobu == 'O'))
00125     left_sm.resize (m, ncol_u);
00126 
00127   double *u = left_sm.fortran_vec ();
00128 
00129   sigma.resize (nrow_s, ncol_s);
00130   double *s_vec  = sigma.fortran_vec ();
00131 
00132   if (! (jobv == 'N' || jobv == 'O'))
00133     right_sm.resize (nrow_vt, n);
00134 
00135   double *vt = right_sm.fortran_vec ();
00136 
00137   // Ask DGESVD what the dimension of WORK should be.
00138 
00139   int lwork = -1;
00140 
00141   Array<double> work (1);
00142 
00143   F77_XFCN (dgesvd, DGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
00144                              F77_CONST_CHAR_ARG2 (&jobv, 1),
00145                              m, n, tmp_data, m, s_vec, u, m, vt,
00146                              nrow_vt, work.fortran_vec (), lwork, info
00147                              F77_CHAR_ARG_LEN (1)
00148                              F77_CHAR_ARG_LEN (1)));
00149 
00150   if (f77_exception_encountered)
00151     (*current_liboctave_error_handler) ("unrecoverable error in dgesvd");
00152   else
00153     {
00154       lwork = static_cast<int> (work(0));
00155       work.resize (lwork);
00156 
00157       F77_XFCN (dgesvd, DGESVD, (F77_CONST_CHAR_ARG2 (&jobu, 1),
00158                                  F77_CONST_CHAR_ARG2 (&jobv, 1),
00159                                  m, n, tmp_data, m, s_vec, u, m, vt,
00160                                  nrow_vt, work.fortran_vec (), lwork, info
00161                                  F77_CHAR_ARG_LEN (1)
00162                                  F77_CHAR_ARG_LEN (1)));
00163 
00164       if (f77_exception_encountered)
00165         (*current_liboctave_error_handler) ("unrecoverable error in dgesvd");
00166       else
00167         {
00168           if (! (jobv == 'N' || jobv == 'O'))
00169             right_sm = right_sm.transpose ();
00170         }
00171     }
00172 
00173   return info;
00174 }
00175 
00176 std::ostream&
00177 operator << (std::ostream& os, const SVD& a)
00178 {
00179   os << a.left_singular_matrix () << "\n";
00180   os << a.singular_values () << "\n";
00181   os << a.right_singular_matrix () << "\n";
00182 
00183   return os;
00184 }
00185 
00186 /*
00187 ;;; Local Variables: ***
00188 ;;; mode: C++ ***
00189 ;;; End: ***
00190 */

Wed Dec 29 11:51:12 2004に生成されました。 doxygen1.2.18
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送