fn_solve.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // 
00007 // This file is part of the Armadillo C++ library.
00008 // It is provided without any warranty of fitness
00009 // for any purpose. You can redistribute this file
00010 // and/or modify it under the terms of the GNU
00011 // Lesser General Public License (LGPL) as published
00012 // by the Free Software Foundation, either version 3
00013 // of the License or (at your option) any later version.
00014 // (see http://www.opensource.org/licenses for more info)
00015 
00016 
00017 //! \addtogroup fn_solve
00018 //! @{
00019 
00020 
00021 
00022 //! Solve a system of linear equations, i.e., A*X = B, where X is unknown.
00023 //! For a square matrix A, this function is conceptually the same as X = inv(A)*B,
00024 //! but is done more efficiently.
00025 //! The number of rows in A and B must be the same.
00026 //! B can be either a column vector or a matrix.
00027 //! This function will also try to provide approximate solutions
00028 //! to under-determined as well as over-determined systems (non-square A matrices).
00029 
00030 template<typename eT, typename T1, typename T2>
00031 inline
00032 bool
00033 solve(Mat<eT>& X, const Base<eT,T1>& A_in, const Base<eT,T2>& B_in)
00034   {
00035   arma_extra_debug_sigprint();
00036   
00037   const unwrap<T1> tmp1(A_in.get_ref());
00038   const unwrap<T2> tmp2(B_in.get_ref());
00039   
00040   const Mat<eT>& A = tmp1.M;
00041   const Mat<eT>& B = tmp2.M;
00042   
00043   arma_debug_check( (A.n_rows != B.n_rows), "solve(): number of rows in A and B must be the same" );
00044   
00045   bool status;
00046   
00047   if(A.n_rows == A.n_cols)
00048     {
00049     status = auxlib::solve(X, A, B);
00050     }
00051   else
00052   if(A.n_rows > A.n_cols)
00053     {
00054     arma_extra_debug_print("solve(): detected over-determined system");
00055     status = auxlib::solve_od(X, A, B);
00056     }
00057   else
00058     {
00059     arma_extra_debug_print("solve(): detected under-determined system");
00060     status = auxlib::solve_ud(X, A, B);
00061     }
00062   
00063   if(status == false)
00064     {
00065     X.reset();
00066     }
00067   
00068   return status;
00069   }
00070 
00071 
00072 
00073 template<typename eT, typename T1, typename T2>
00074 inline
00075 Mat<eT>
00076 solve(const Base<eT,T1>& A_in, const Base<eT,T2>& B_in)
00077   {
00078   arma_extra_debug_sigprint();
00079   
00080   Mat<eT> X;
00081   const bool status = solve(X, A_in, B_in);
00082   
00083   if(status == false)
00084     {
00085     arma_print("solve(): solution not found");
00086     
00087     X.reset();
00088     }
00089   
00090   return X;
00091   }
00092 
00093 
00094 
00095 //! @}