ViennaCL - The Vienna Computing Library  1.5.2
viennacl/linalg/direct_solve.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_DIRECT_SOLVE_HPP_
00002 #define VIENNACL_LINALG_DIRECT_SOLVE_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 
00025 #include "viennacl/forwards.h"
00026 #include "viennacl/meta/enable_if.hpp"
00027 #include "viennacl/vector.hpp"
00028 #include "viennacl/matrix.hpp"
00029 #include "viennacl/linalg/host_based/direct_solve.hpp"
00030 
00031 #ifdef VIENNACL_WITH_OPENCL
00032   #include "viennacl/linalg/opencl/direct_solve.hpp"
00033 #endif
00034 
00035 #ifdef VIENNACL_WITH_CUDA
00036   #include "viennacl/linalg/cuda/direct_solve.hpp"
00037 #endif
00038 
00039 namespace viennacl
00040 {
00041   namespace linalg
00042   {
00043 
00044     //
00045     // A \ B:
00046     //
00047 
00053     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00054     void inplace_solve(const matrix_base<NumericT, F1> & A, matrix_base<NumericT, F2> & B, SOLVERTAG)
00055     {
00056       assert( (viennacl::traits::size1(A) == viennacl::traits::size2(A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)"));
00057       assert( (viennacl::traits::size1(A) == viennacl::traits::size1(B)) && bool("Size check failed in inplace_solve(): size1(A) != size1(B)"));
00058 
00059       switch (viennacl::traits::handle(A).get_active_handle_id())
00060       {
00061         case viennacl::MAIN_MEMORY:
00062           viennacl::linalg::host_based::inplace_solve(A, B, SOLVERTAG());
00063           break;
00064 #ifdef VIENNACL_WITH_OPENCL
00065         case viennacl::OPENCL_MEMORY:
00066           viennacl::linalg::opencl::inplace_solve(A, B, SOLVERTAG());
00067           break;
00068 #endif
00069 #ifdef VIENNACL_WITH_CUDA
00070         case viennacl::CUDA_MEMORY:
00071           viennacl::linalg::cuda::inplace_solve(A, B, SOLVERTAG());
00072           break;
00073 #endif
00074         case viennacl::MEMORY_NOT_INITIALIZED:
00075           throw memory_exception("not initialised!");
00076         default:
00077           throw memory_exception("not implemented");
00078       }
00079     }
00080 
00086     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00087     void inplace_solve(const matrix_base<NumericT, F1> & A,
00088                        matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> proxy_B,
00089                        SOLVERTAG)
00090     {
00091       assert( (viennacl::traits::size1(A) == viennacl::traits::size2(A))       && bool("Size check failed in inplace_solve(): size1(A) != size2(A)"));
00092       assert( (viennacl::traits::size1(A) == viennacl::traits::size1(proxy_B)) && bool("Size check failed in inplace_solve(): size1(A) != size1(B^T)"));
00093 
00094       switch (viennacl::traits::handle(A).get_active_handle_id())
00095       {
00096         case viennacl::MAIN_MEMORY:
00097           viennacl::linalg::host_based::inplace_solve(A, proxy_B, SOLVERTAG());
00098           break;
00099 #ifdef VIENNACL_WITH_OPENCL
00100         case viennacl::OPENCL_MEMORY:
00101           viennacl::linalg::opencl::inplace_solve(A, proxy_B, SOLVERTAG());
00102           break;
00103 #endif
00104 #ifdef VIENNACL_WITH_CUDA
00105         case viennacl::CUDA_MEMORY:
00106           viennacl::linalg::cuda::inplace_solve(A, proxy_B, SOLVERTAG());
00107           break;
00108 #endif
00109         case viennacl::MEMORY_NOT_INITIALIZED:
00110           throw memory_exception("not initialised!");
00111         default:
00112           throw memory_exception("not implemented");
00113       }
00114     }
00115 
00116     //upper triangular solver for transposed lower triangular matrices
00122     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00123     void inplace_solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy_A,
00124                        matrix_base<NumericT, F2> & B,
00125                        SOLVERTAG)
00126     {
00127       assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size2(proxy_A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)"));
00128       assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size1(B))       && bool("Size check failed in inplace_solve(): size1(A^T) != size1(B)"));
00129 
00130       switch (viennacl::traits::handle(proxy_A.lhs()).get_active_handle_id())
00131       {
00132         case viennacl::MAIN_MEMORY:
00133           viennacl::linalg::host_based::inplace_solve(proxy_A, B, SOLVERTAG());
00134           break;
00135 #ifdef VIENNACL_WITH_OPENCL
00136         case viennacl::OPENCL_MEMORY:
00137           viennacl::linalg::opencl::inplace_solve(proxy_A, B, SOLVERTAG());
00138           break;
00139 #endif
00140 #ifdef VIENNACL_WITH_CUDA
00141         case viennacl::CUDA_MEMORY:
00142           viennacl::linalg::cuda::inplace_solve(proxy_A, B, SOLVERTAG());
00143           break;
00144 #endif
00145         case viennacl::MEMORY_NOT_INITIALIZED:
00146           throw memory_exception("not initialised!");
00147         default:
00148           throw memory_exception("not implemented");
00149       }
00150     }
00151 
00157     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00158     void inplace_solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy_A,
00159                              matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans>   proxy_B,
00160                        SOLVERTAG)
00161     {
00162       assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size2(proxy_A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)"));
00163       assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size1(proxy_B)) && bool("Size check failed in inplace_solve(): size1(A^T) != size1(B^T)"));
00164 
00165       switch (viennacl::traits::handle(proxy_A.lhs()).get_active_handle_id())
00166       {
00167         case viennacl::MAIN_MEMORY:
00168           viennacl::linalg::host_based::inplace_solve(proxy_A, proxy_B, SOLVERTAG());
00169           break;
00170 #ifdef VIENNACL_WITH_OPENCL
00171         case viennacl::OPENCL_MEMORY:
00172           viennacl::linalg::opencl::inplace_solve(proxy_A, proxy_B, SOLVERTAG());
00173           break;
00174 #endif
00175 #ifdef VIENNACL_WITH_CUDA
00176         case viennacl::CUDA_MEMORY:
00177           viennacl::linalg::cuda::inplace_solve(proxy_A, proxy_B, SOLVERTAG());
00178           break;
00179 #endif
00180         case viennacl::MEMORY_NOT_INITIALIZED:
00181           throw memory_exception("not initialised!");
00182         default:
00183           throw memory_exception("not implemented");
00184       }
00185     }
00186 
00187     //
00188     // A \ b
00189     //
00190 
00191     template <typename NumericT, typename F, typename SOLVERTAG>
00192     void inplace_solve(const matrix_base<NumericT, F> & mat,
00193                              vector_base<NumericT> & vec,
00194                        SOLVERTAG)
00195     {
00196       assert( (mat.size1() == vec.size()) && bool("Size check failed in inplace_solve(): size1(A) != size(b)"));
00197       assert( (mat.size2() == vec.size()) && bool("Size check failed in inplace_solve(): size2(A) != size(b)"));
00198 
00199       switch (viennacl::traits::handle(mat).get_active_handle_id())
00200       {
00201         case viennacl::MAIN_MEMORY:
00202           viennacl::linalg::host_based::inplace_solve(mat, vec, SOLVERTAG());
00203           break;
00204 #ifdef VIENNACL_WITH_OPENCL
00205         case viennacl::OPENCL_MEMORY:
00206           viennacl::linalg::opencl::inplace_solve(mat, vec, SOLVERTAG());
00207           break;
00208 #endif
00209 #ifdef VIENNACL_WITH_CUDA
00210         case viennacl::CUDA_MEMORY:
00211           viennacl::linalg::cuda::inplace_solve(mat, vec, SOLVERTAG());
00212           break;
00213 #endif
00214         case viennacl::MEMORY_NOT_INITIALIZED:
00215           throw memory_exception("not initialised!");
00216         default:
00217           throw memory_exception("not implemented");
00218       }
00219     }
00220 
00226     template <typename NumericT, typename F, typename SOLVERTAG>
00227     void inplace_solve(const matrix_expression< const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans> & proxy,
00228                        vector_base<NumericT> & vec,
00229                        SOLVERTAG)
00230     {
00231       assert( (proxy.lhs().size1() == vec.size()) && bool("Size check failed in inplace_solve(): size1(A) != size(b)"));
00232       assert( (proxy.lhs().size2() == vec.size()) && bool("Size check failed in inplace_solve(): size2(A) != size(b)"));
00233 
00234       switch (viennacl::traits::handle(proxy.lhs()).get_active_handle_id())
00235       {
00236         case viennacl::MAIN_MEMORY:
00237           viennacl::linalg::host_based::inplace_solve(proxy, vec, SOLVERTAG());
00238           break;
00239 #ifdef VIENNACL_WITH_OPENCL
00240         case viennacl::OPENCL_MEMORY:
00241           viennacl::linalg::opencl::inplace_solve(proxy, vec, SOLVERTAG());
00242           break;
00243 #endif
00244 #ifdef VIENNACL_WITH_CUDA
00245         case viennacl::CUDA_MEMORY:
00246           viennacl::linalg::cuda::inplace_solve(proxy, vec, SOLVERTAG());
00247           break;
00248 #endif
00249         case viennacl::MEMORY_NOT_INITIALIZED:
00250           throw memory_exception("not initialised!");
00251         default:
00252           throw memory_exception("not implemented");
00253       }
00254     }
00255 
00257 
00258 
00265     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00266     matrix<NumericT, F2> solve(const matrix_base<NumericT, F1> & A,
00267                                const matrix_base<NumericT, F2> & B,
00268                                SOLVERTAG tag)
00269     {
00270       // do an inplace solve on the result vector:
00271       matrix<NumericT, F2> result(B);
00272 
00273       inplace_solve(A, result, tag);
00274 
00275       return result;
00276     }
00277 
00278 
00280 
00287     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00288     matrix<NumericT, F2> solve(const matrix_base<NumericT, F1> & A,
00289                                const matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> & proxy,
00290                                SOLVERTAG tag)
00291     {
00292       // do an inplace solve on the result vector:
00293       matrix<NumericT, F2> result(proxy);
00294 
00295       inplace_solve(A, result, tag);
00296 
00297       return result;
00298     }
00299 
00306     template <typename NumericT, typename F1, typename SOLVERTAG>
00307     vector<NumericT> solve(const matrix_base<NumericT, F1> & mat,
00308                            const vector_base<NumericT> & vec,
00309                            SOLVERTAG const & tag)
00310     {
00311       // do an inplace solve on the result vector:
00312       vector<NumericT> result(vec);
00313 
00314       inplace_solve(mat, result, tag);
00315 
00316       return result;
00317     }
00318 
00319 
00321 
00327     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00328     matrix<NumericT, F2> solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy,
00329                                const matrix_base<NumericT, F2> & B,
00330                                SOLVERTAG tag)
00331     {
00332       // do an inplace solve on the result vector:
00333       matrix<NumericT, F2> result(B);
00334 
00335       inplace_solve(proxy, result, tag);
00336 
00337       return result;
00338     }
00339 
00340 
00347     template <typename NumericT, typename F1, typename F2, typename SOLVERTAG>
00348     matrix<NumericT, F2> solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy_A,
00349                                const matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> & proxy_B,
00350                                SOLVERTAG tag)
00351     {
00352       // do an inplace solve on the result vector:
00353       matrix<NumericT, F2> result(proxy_B);
00354 
00355       inplace_solve(proxy_A, result, tag);
00356 
00357       return result;
00358     }
00359 
00366     template <typename NumericT, typename F1, typename SOLVERTAG>
00367     vector<NumericT> solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy,
00368                            const vector_base<NumericT> & vec,
00369                            SOLVERTAG const & tag)
00370     {
00371       // do an inplace solve on the result vector:
00372       vector<NumericT> result(vec);
00373 
00374       inplace_solve(proxy, result, tag);
00375 
00376       return result;
00377     }
00378 
00379 
00380   }
00381 }
00382 
00383 #endif