@@ -41,20 +41,23 @@ using namespace SCIRun::Core;
4141
4242namespace
4343{
44+ template <class ColumnMatrixType >
4445 class SolveLinearSystemAlgorithmEigenCGImpl
4546 {
4647 public:
47- SolveLinearSystemAlgorithmEigenCGImpl (const DenseColumnMatrix& rhs, double tolerance, int maxIterations) :
48- rhs_ (rhs), tolerance_(tolerance), maxIterations_(maxIterations) {}
48+ SolveLinearSystemAlgorithmEigenCGImpl (const ColumnMatrixType& rhs, double tolerance, int maxIterations) :
49+ tolerance_ (tolerance), maxIterations_(maxIterations), rhs_(rhs) {}
50+
51+ using SolutionType = ColumnMatrixType;
4952
5053 template <class MatrixType >
51- DenseColumnMatrix ::EigenBase solveWithEigen (const MatrixType& lhs)
54+ typename ColumnMatrixType ::EigenBase solveWithEigen (const MatrixType& lhs)
5255 {
5356 Eigen::ConjugateGradient<typename MatrixType::EigenBase> cg;
5457 cg.compute (lhs);
5558
5659 if (cg.info () != Eigen::Success)
57- BOOST_THROW_EXCEPTION (AlgorithmInputException ()
60+ BOOST_THROW_EXCEPTION (AlgorithmInputException ()
5861 << LinearAlgebraErrorMessage (" Conjugate gradient initialization was unsuccessful" )
5962 << EigenComputationInfo (cg.info ()));
6063
@@ -69,42 +72,57 @@ namespace
6972 double tolerance_;
7073 int maxIterations_;
7174 private:
72- const DenseColumnMatrix & rhs_;
75+ const ColumnMatrixType & rhs_;
7376 };
7477}
7578
7679SolveLinearSystemAlgorithm::Outputs SolveLinearSystemAlgorithm::run (const Inputs& input, const Parameters& params) const
7780{
78- auto A = input.get <0 >();
81+ return runImpl<Inputs, Outputs>(input, params);
82+ }
83+
84+ SolveLinearSystemAlgorithm::ComplexOutputs SolveLinearSystemAlgorithm::run (const ComplexInputs& input, const Parameters& params) const
85+ {
86+ return runImpl<ComplexInputs, ComplexOutputs>(input, params);
87+ }
88+
89+ template <typename In, typename Out>
90+ Out SolveLinearSystemAlgorithm::runImpl (const In& input, const Parameters& params) const
91+ {
92+ auto A = std::get<0 >(input);
7993 ENSURE_ALGORITHM_INPUT_NOT_NULL (A, " Null input matrix" );
8094
81- auto b = input. get <1 >();
95+ auto b = std:: get<1 >(input );
8296 ENSURE_ALGORITHM_INPUT_NOT_NULL (b, " Null rhs vector" );
83-
84- double tolerance = params. get <0 >();
97+
98+ double tolerance = std:: get<0 >(params );
8599 ENSURE_POSITIVE_DOUBLE (tolerance, " Tolerance out of range!" );
86100
87- int maxIterations = params. get <1 >();
101+ int maxIterations = std:: get<1 >(params );
88102 ENSURE_POSITIVE_INT (maxIterations, " Max iterations out of range!" );
89103
90- SolveLinearSystemAlgorithmEigenCGImpl impl (*b, tolerance, maxIterations);
91- DenseColumnMatrix x;
104+ using SolutionType = DenseMatrixGeneric<typename std::tuple_element<0 , In>::type::element_type::value_type>;
105+ using SolverType = SolveLinearSystemAlgorithmEigenCGImpl<SolutionType>;
106+ SolverType impl (*b, tolerance, maxIterations);
107+ typename SolverType::SolutionType x;
92108 if (matrixIs::dense (A))
93109 {
94- x = impl.solveWithEigen (*castMatrix::toDense (A));
110+ auto dense = castMatrix::toDense (A);
111+ x = impl.solveWithEigen (*dense);
95112 }
96113 else if (matrixIs::sparse (A))
97114 {
98- x = impl.solveWithEigen (*castMatrix::toSparse (A));
115+ auto sparse = castMatrix::toSparse (A);
116+ x = impl.solveWithEigen (*sparse);
99117 }
100118 else
101119 BOOST_THROW_EXCEPTION (AlgorithmProcessingException () << ErrorMessage (" solveWithEigen can only handle dense and sparse matrices." ));
102-
120+
103121 if (x.size () != 0 )
104122 {
105123 // / @todo: move ctor
106- DenseColumnMatrixHandle solution (boost::make_shared<DenseColumnMatrix >(x));
107- return SolveLinearSystemAlgorithm::Outputs (solution, impl.tolerance_ , impl.maxIterations_ );
124+ auto solution (boost::make_shared<SolutionType >(x));
125+ return Out (solution, impl.tolerance_ , impl.maxIterations_ );
108126 }
109127 else
110128 BOOST_THROW_EXCEPTION (AlgorithmProcessingException () << ErrorMessage (" solveWithEigen produced an empty solution." ));
@@ -113,4 +131,4 @@ SolveLinearSystemAlgorithm::Outputs SolveLinearSystemAlgorithm::run(const Inputs
113131AlgorithmOutput SolveLinearSystemAlgorithm::run (const AlgorithmInput& input) const
114132{
115133 throw 2 ;
116- }
134+ }
0 commit comments