STK++ 0.9.13
STK_lapack_MultiLeastSquare.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::Algebra
27 * created on: 1 avr. 2015
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
36#ifndef STK_LAPACK_MULTILEASTSQUARE_H
37#define STK_LAPACK_MULTILEASTSQUARE_H
38
39#include "STK_ILeastSquare.h"
40#include "STK_lapack_Util.h"
41
44
45#ifdef STKUSELAPACK
46
47extern "C"
48{
49
50}
51
52#endif // STKUSELAPACK
53
54
55namespace STK
56{
57
58namespace lapack
59{
60// forward declaration
61template<class ArrayB, class ArrayA> class MultiLeastSquare;
62}
63
64namespace hidden
65{
69template<class ArrayB_, class ArrayA_>
70struct AlgebraTraits< lapack::MultiLeastSquare<ArrayB_, ArrayA_> >
71{
72 typedef ArrayA_ ArrayA;
73 typedef ArrayB_ ArrayB;
74};
75
76} // namespace hidden
77
78
79namespace lapack
80{
100template<class ArrayB, class ArrayA>
101class MultiLeastSquare: public ILeastSquare< MultiLeastSquare<ArrayB, ArrayA> >
102{
103 public:
105 using Base::b_;
106 using Base::a_;
107 using Base::x_;
108 using Base::rank_;
113 MultiLeastSquare( ArrayB const& b, ArrayA const& a, bool isBref=false, bool isAref=false)
114 : Base(b, a, isBref, isAref), rcond_(-1) {};
119 template<class ArrayB_, class ArrayA_>
123 virtual ~MultiLeastSquare() {};
125 inline Real rcond() const { return rcond_;}
127 inline CVectorX const& s() const { return s_;}
130 inline void setRcond(Real rcond) { rcond_ =rcond;}
135 bool runImpl();
140 template<class Weights>
141 bool runImpl(Weights const& weights);
142
143 protected:
148
149 private:
151 bool computeLS(CArrayXX& b, CArrayXX& a);
152};
153
154/* @brief Run LS solution
155 * Launch gelsd LAPACK routine to compute the solution.
156 * @return @c true if no error occur, @c false otherwise
157 */
158template<class ArrayB, class ArrayA>
160{
161 Range brows = (b_.sizeRows()< a_.sizeCols()) ? a_.cols() : b_.rows();
162 // local arrays, b is resized if necessary
163 CArrayXX a(a_), b(brows, b_.cols());
164 b.sub(b_.rows(), b_.cols()) = b_;
165 // start
166 return computeLS(b,a);
167}
168/* @brief Run LS solution
169 * Launch gelsd LAPACK routine to compute the solution.
170 * @return @c true if no error occur, @c false otherwise
171 */
172template<class ArrayB, class ArrayA>
173template<class Weights>
175{
177 Range brows = (b_.sizeRows()< a_.sizeCols()) ? a_.cols() : b_.rows();
178 // local arrays, b is resized if necessary
179 CArrayXX a(w.sqrt().diagonalize() * a_), b(brows, b_.cols());
180 b.sub(b_.rows(), b_.cols()) = w.sqrt().diagonalize() * b_;
181 // start
182 return computeLS(b,a);
183}
184
185/* @brief Run LS solution
186 * Launch gelsd LAPACK routine to compute the solution.
187 * @return @c true if no error occur, @c false otherwise
188 */
189template<>
191{ return computeLS(b_,a_);}
192
193
194/* private method for computing the LS solution */
195template<class ArrayB, class ArrayA>
197{
198 Range arows = a.rows(), acols = a.cols(), brows = b.rows(), bcols = b.cols();
199 int m = arows.size(), n= acols.size(), nrhs = bcols.size();
200 // resize if necessary
201 if (brows.size()<n)
202 {
203 if (!b.isRef())
204 {
205 CArrayXX tmp(b);
206 b.resize(acols,bcols);
207 b.sub(brows, bcols) = tmp;
208 }
209 else
211 }
212 int lda = a.sizeRows(), ldb = b.sizeRows();
213 // shift to 0
214 a.shift(0,0);
215 b.shift(0,0);
216 s_.resize(m); s_ = 0.;
217 Range srange = s_.range();
218 s_.shift(0);
219 // get sizes
220 Real wkopt;
221 int lWork = -1, iwkopt;
222 int info = gelsd( m, n, nrhs
223 , a.p_data(), lda
224 , b.p_data(), ldb
225 , s_.p_data()
226 , &rcond_, &rank_
227 , &wkopt, lWork, &iwkopt);
228 if( info != 0 )
229 {
230 if (info>0)
232 return false;
233 }
234 this->msg_error_= STKERROR_1ARG(lapack::MultiLeastSquare::computeLS get,-info,error parameter);
235 return false;
236 }
237 // get working sizes
238 lWork = (int)wkopt;
239 Real* work = new Real[lWork];
240 int* iwork = new int[iwkopt];
241 // Solve the least square problem
242 info = gelsd( m, n, nrhs
243 , a.p_data(), lda
244 , b.p_data(), ldb
245 , s_.p_data()
246 , &rcond_, &rank_
247 , work, lWork, iwork);
248 delete[] iwork;
249 delete[] work;
250 if( info != 0 )
251 {
252 if (info>0)
254 return false;
255 }
256 this->msg_error_= STKERROR_1ARG(lapack::MultiLeastSquare::computeLS get,-info,error parameter);
257 return false;
258 }
259 // shift back
260 a.shift(arows.begin(), acols.begin());
261 b.shift(brows.begin(), bcols.begin());
262 s_.shift(srange.begin());
263 x_ = b.sub(acols,bcols);
264 return true;
265}
266
267} // namespace lapack
268
269} // namespace STK
270
271#endif /* STK_LAPACK_MULTILEASTSQUARE_H */
In this file we implement the final class CArrayVector.
In this file we implement the final class CArray.
In this file we define the interface class ILeastSquare.
#define STKERROR_NO_ARG(Where, Error)
Definition STK_Macros.h:49
#define STKERROR_1ARG(Where, Arg, Error)
Definition STK_Macros.h:61
#define STKRUNTIME_ERROR_NO_ARG(Where, Error)
Definition STK_Macros.h:138
#define STK_STATIC_ASSERT_ONE_DIMENSION_ONLY(EXPR)
In this file we define and implement utilities classes and methods for the interface with lapack.
Derived & resize(Range const &I, Range const &J)
resize the Array.
Derived & shift(int beginRows, int beginCols)
shift the Array.
bool isRef() const
hidden::CSliceDispatcher< Derived, Size >::Result sub(TRange< Size > const &J) const
implement the sub operator for 1D arrays using a reference on the row/column of the allocator
Type *const & p_data() const
The class ILeastSquare is an interface class for the methods solving the least-square problem.
ArrayB b_
Array or vector of the left hand side.
hidden::AlgebraTraits< MultiLeastSquare< ArrayB, ArrayA > >::ArrayB ArrayB
ArrayB x_
Array of the solution (a vector if b is a vector, a matrix otherwise)
hidden::AlgebraTraits< MultiLeastSquare< ArrayB, ArrayA > >::ArrayA ArrayA
The class MultiLeastSQquare solve the least square problem when the response b is multidimensional.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Index sub-vector region: Specialization when the size is unknown.
Definition STK_Range.h:265
The class MultiLeastSQquare solve the least square problem when the response b is multidimensional.
MultiLeastSquare(ExprBase< ArrayB_ > const &b, ExprBase< ArrayA_ > const &a)
template constructor
bool computeLS(CArrayXX &b, CArrayXX &a)
private method for computing the LS solution
ILeastSquare< MultiLeastSquare< ArrayB, ArrayA > > Base
bool runImpl()
solve the multi-linear least square problem.
CVectorX s_
Array of the singular values.
Real rcond_
condition number used for determining the effective rank of A
CVectorX const & s() const
return the array with the singular values of A
MultiLeastSquare(ArrayB const &b, ArrayA const &a, bool isBref=false, bool isAref=false)
constructor
int gelsd(int m, int n, int nrhs, Real *a, int lda, Real *b, int ldb, Real *s, Real *rcond, int *rank, Real *work, int lWork, int *iwork)
wrapper of the LAPACK GELSD routine: computes the minimum-norm solution to a real linear least square...
double Real
STK fundamental type of Real values.
The namespace STK is the main domain space of the Statistical ToolKit project.
traits class for the algebra methods.