ViennaCL - The Vienna Computing Library  1.5.1
viennacl/linalg/detail/spai/small_matrix.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_DETAIL_SPAI_SMALL_MATRIX_HPP
00002 #define VIENNACL_LINALG_DETAIL_SPAI_SMALL_MATRIX_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008    Portions of this software are copyright by UChicago Argonne, LLC.
00009 
00010                             -----------------
00011                   ViennaCL - The Vienna Computing Library
00012                             -----------------
00013 
00014    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00015 
00016    (A list of authors and contributors can be found in the PDF manual)
00017 
00018    License:         MIT (X11), see file LICENSE in the base directory
00019 ============================================================================= */
00020 
00027 #include <utility>
00028 #include <iostream>
00029 #include <fstream>
00030 #include <string>
00031 #include <algorithm>
00032 #include <vector>
00033 #include <math.h>
00034 #include <map>
00035 #include "boost/numeric/ublas/vector.hpp"
00036 #include "boost/numeric/ublas/matrix.hpp"
00037 #include "boost/numeric/ublas/matrix_proxy.hpp"
00038 #include "boost/numeric/ublas/vector_proxy.hpp"
00039 #include "boost/numeric/ublas/storage.hpp"
00040 #include "boost/numeric/ublas/io.hpp"
00041 #include "boost/numeric/ublas/lu.hpp"
00042 #include "boost/numeric/ublas/triangular.hpp"
00043 #include "boost/numeric/ublas/matrix_expression.hpp"
00044 #include "boost/numeric/ublas/detail/matrix_assign.hpp"
00045 
00046 
00047 
00048 namespace viennacl
00049 {
00050     namespace linalg
00051     {
00052       namespace detail
00053       {
00054         namespace spai
00055         {
00056 
00057           //
00058           // Constructs an orthonormal sparse matrix M (with M^T M = Id). Is composed of elementary 2x2 rotation matrices with suitable renumbering.
00059           //
00060           template <typename MatrixType>
00061           void make_rotation_matrix(MatrixType & mat, vcl_size_t new_size, vcl_size_t off_diagonal_distance = 4)
00062           {
00063             mat.resize(new_size, new_size, false);
00064             mat.clear();
00065 
00066             double val = 1.0 / std::sqrt(2.0);
00067 
00068             for (vcl_size_t i=0; i<new_size; ++i)
00069               mat(i,i) = val;
00070 
00071             for (vcl_size_t i=off_diagonal_distance; i<new_size; ++i)
00072             {
00073               mat(i-off_diagonal_distance, i) = val; mat(i, i-off_diagonal_distance) = -val;
00074             }
00075 
00076           }
00077 
00078 
00079           //calcualtes matrix determinant
00080           template <typename MatrixType>
00081           double determinant(boost::numeric::ublas::matrix_expression<MatrixType> const& mat_r)
00082           {
00083               double det = 1.0;
00084 
00085               MatrixType mLu(mat_r() );
00086               boost::numeric::ublas::permutation_matrix<vcl_size_t> pivots(mat_r().size1() );
00087 
00088               int is_singular = static_cast<int>(lu_factorize(mLu, pivots));
00089 
00090               if (!is_singular)
00091               {
00092                   for (vcl_size_t i=0; i < pivots.size(); ++i)
00093                   {
00094                       if (pivots(i) != i)
00095                           det *= -1.0;
00096 
00097                       det *= mLu(i,i);
00098                   }
00099               }
00100               else
00101                   det = 0.0;
00102 
00103               return det;
00104           }
00105 
00106         }
00107       }
00108     }
00109 }
00110 #endif