STK++ 0.9.13
STK_ArrayBaseAssign.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::Arrays
27 * created on: 16 oct. 2012
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
36#ifndef STK_ARRAYBASEASSIGN_H
37#define STK_ARRAYBASEASSIGN_H
38
40
41// this macro will be true if the assignation is correct and false otherwise
42#define IS_VALID_ASSIGN(lhs,rhs) \
43( ( ( lhs==Arrays::array2D_ || lhs==Arrays::square_) \
44 && \
45 ( rhs==Arrays::array2D_ || rhs==Arrays::square_ \
46 || rhs==Arrays::diagonal_ || rhs==Arrays::number_ \
47 || rhs==Arrays::lower_triangular_ || rhs==Arrays::upper_triangular_ \
48 || rhs==Arrays::lower_symmetric_ || rhs==Arrays::upper_symmetric_ \
49 || rhs==Arrays::symmetric_ \
50 ) \
51 ) \
52 || \
53 ( ( lhs==Arrays::array2D_) \
54 && \
55 (rhs==Arrays::vector_ || rhs==Arrays::point_|| rhs==Arrays::number_) \
56 ) \
57 || \
58 ( lhs==Arrays::lower_triangular_ && rhs==Arrays::lower_triangular_) \
59 || \
60 ( lhs==Arrays::upper_triangular_ && rhs==Arrays::upper_triangular_) \
61 || \
62 ( ( lhs==Arrays::diagonal_ || lhs==Arrays::vector_ || lhs==Arrays::point_) \
63 && \
64 (rhs==Arrays::diagonal_ || rhs==Arrays::vector_ || rhs==Arrays::point_) \
65 ) \
66 || \
67 ( lhs==Arrays::number_ && rhs==Arrays::number_) \
68)
69
70namespace STK
71{
72
73/* @brief assign rhs to this **/
74template<class Derived>
75template<class Rhs>
76inline Derived& ArrayBase<Derived>::assign(ExprBase<Rhs> const& rhs)
77{
78 enum
79 {
80 rhs_structure_ = hidden::Traits<Rhs>::structure_
84 , is_valid_ = IS_VALID_ASSIGN((Arrays::Structure)structure_, (Arrays::Structure)rhs_structure_)
85 };
86 STK_STATIC_ASSERT(is_valid_,YOU_TRIED_TO_ASSIGN_A_NOT_COMPATIBLE_ARRAY);
87 // check if assignment is possible
88 if (structure_ == int(Arrays::square_) && rhs.cols() != rhs.rows() )
90 // choose the correct way to resize this if necessary
91 hidden::resizeSelector<Derived, Rhs, rhs_structure_>::run(this->asDerived(), rhs.asDerived());
92 // choose the correct way to copy
93 hidden::CopycatSelector<Derived, Rhs, rhs_orient_>::run(this->asDerived(), rhs.asDerived());
94 return this->asDerived();
95}
96
97/* @return the matrix or vector obtained by setting this constant*/
98template<class Derived>
99inline Derived& ArrayBase<Derived>::operator=( Type const& value) { return setValue(value);}
100/* @return the matrix or vector obtained by evaluating this expression */
101template<class Derived>
102inline Derived& ArrayBase<Derived>::operator=( Derived const& rhs) { return assign(rhs);}
103/* @return the matrix or vector obtained by evaluating this expression */
104template<class Derived>
105template<typename Rhs>
107{ return assign(rhs.asDerived());}
108
109//------------------------------------------------
110// Rhs array
111template<class Derived>
112template<typename Rhs>
114{
115 enum { orient_ = hidden::Traits<Derived>::orient_
117 };
119 hidden::CopycatSelector<Derived, Res, orient_>::run(this->asDerived(), this->asDerived() + rhs.asDerived());
120 return this->asDerived();
121}
122template<class Derived>
123template<typename Rhs>
125{
126 enum { orient_ = hidden::Traits<Derived>::orient_
128 };
130 hidden::CopycatSelector<Derived, Res, orient_>::run(this->asDerived(), this->asDerived() - rhs.asDerived());
131 return this->asDerived();
132}
133
134template<class Derived>
135template<typename Rhs>
137{
138 enum { orient_ = hidden::Traits<Derived>::orient_
140 };
142 hidden::CopycatSelector<Derived, Res, orient_>::run(this->asDerived(), this->asDerived() / rhs.asDerived());
143 return this->asDerived();
144}
145// TODO: implement direct call to CopyCat
146template<class Derived>
147template<typename Rhs>
149{
152 };
153 //typedef typename ProductProductType<Derived, Rhs>::ProductType Res;
154// typedef BinaryOperator< ProductOp<Type, typename hidden::Traits<Rhs>::Type>, Derived, Rhs> Res;
155// hidden::CopycatSelector<Derived, Res, orient_>::run(this->asDerived(), this->asDerived() * rhs.asDerived());
156 this->asDerived() = this->asDerived() * rhs.asDerived();
157 return this->asDerived();
158}
160template<class Derived>
161template<typename Rhs>
163{
164 enum { orient_ = hidden::Traits<Derived>::orient_
166 };
168 hidden::CopycatSelector<Derived, Res, orient_>::run(this->asDerived(), this->asDerived() % rhs.asDerived());
169 return this->asDerived();
170}
172//------------------------------------------------
173// rhs value
174template<class Derived>
175inline Derived& ArrayBase<Derived>::operator+=( Type const& value)
177 enum { orient_ = hidden::Traits<Derived>::orient_};
179 hidden::CopycatSelector<Derived, Rhs, orient_>::run(this->asDerived(), this->asDerived() + value);
180 return this->asDerived();
181}
182template<class Derived>
183inline Derived& ArrayBase<Derived>::operator-=( Type const& value)
184{
185 enum { orient_ = hidden::Traits<Derived>::orient_};
186 typedef UnaryOperator<SumWithOp<Type>, Derived> Rhs;
187 hidden::CopycatSelector<Derived, Rhs, orient_>::run(this->asDerived(), this->asDerived() + (-value));
188 return this->asDerived();
190template<class Derived>
191inline Derived& ArrayBase<Derived>::operator*=( Type const& value)
192{
193 enum { orient_ = hidden::Traits<Derived>::orient_};
194 typedef UnaryOperator<ProductWithOp<Type>, Derived> Rhs;
195 hidden::CopycatSelector<Derived, Rhs, orient_>::run(this->asDerived(), this->asDerived() * value);
196 return this->asDerived();
197}
198template<class Derived>
199inline Derived& ArrayBase<Derived>::operator/=( Type const& value)
200{
201 enum { orient_ = hidden::Traits<Derived>::orient_};
202 typedef UnaryOperator<DivisionWithOp<Type>, Derived> Rhs;
203 hidden::CopycatSelector<Derived, Rhs, orient_>::run(this->asDerived(), this->asDerived() / value);
204 return this->asDerived();
205}
206template<class Derived>
207inline Derived& ArrayBase<Derived>::operator%=( Type const& value)
208{
209 enum { orient_ = hidden::Traits<Derived>::orient_};
210 typedef UnaryOperator<ModuloWithOp<Type>, Derived> Rhs;
211 hidden::CopycatSelector<Derived, Rhs, orient_>::run(this->asDerived(), this->asDerived() % value);
212 return this->asDerived();
213}
214
215/* overwrite @c this with @c rhs.
216 * @note this method does not take care of the possibility of overlapping
217 * @param rhs the array to copy
218 **/
219template<class Derived>
220template<class Rhs>
221inline Derived& ArrayBase<Derived>::copy( ExprBase<Rhs> const& rhs)
222{
224 // check
225 if (this->sizeRows() != rhs.sizeRows())
226 { STKRUNTIME_ERROR_2ARG(ArrayBase<Derived>::copy,this->sizeRows(), rhs.sizeRows(),sizeRows are not the sames);}
227 if (this->sizeCols() != rhs.sizeCols())
228 { STKRUNTIME_ERROR_2ARG(ArrayBase<Derived>::copy,this->sizeCols(), rhs.sizeCols(),sizeCols are not the sames);}
229 // copy. TODO: Use iterators
230 //this->asDerived().reserve(this->sizeRows(), this->sizeCols());
231 for ( int jRhs=rhs.beginCols(), jLhs=this->beginCols(); jRhs<rhs.endCols(); jLhs++, jRhs++)
232 for ( int iRhs=rhs.beginRows(), iLhs=this->beginRows(); iRhs<rhs.endRows(); iLhs++, iRhs++)
233 {
234 setValue(iLhs, jLhs, rhs.elt(iRhs, jRhs));
235 }
236 // return this
237 return this->asDerived();
238}
239
240} // namespace STK
241
242#undef IS_VALID_ASSIGN
243
244#endif /* STK_ARRAYBASEASSIGN_H */
#define IS_VALID_ASSIGN(lhs, rhs)
In this file we implement the copy and assign methods used when copying an array or an expression (rh...
#define STKRUNTIME_ERROR_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:120
#define STK_STATIC_ASSERT(COND, MSG)
#define STK_STATIC_ASSERT_DENSE_ONLY(EXPR)
base class for template arrays.
Derived & operator+=(ExprBase< Rhs > const &other)
Add Rhs to this.
Derived & operator=(Type const &value)
Derived & copy(ExprBase< Rhs > const &rhs)
overwrite this with src.
hidden::Traits< Derived >::Type Type
Derived & assign(ExprBase< Rhs > const &rhs)
Derived & operator/=(ExprBase< Rhs > const &other)
divide this by Rhs.
Derived & operator*=(ExprBase< Rhs > const &other)
multiply this by Rhs.
Derived & operator-=(ExprBase< Rhs > const &other)
subtract a Rhs to this.
Derived & operator%=(ExprBase< Rhs > const &other)
Take modulo of this by Rhs.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Structure
structures of Arrays that can be handled by STK++
String structureToString(Structure const &type)
convert an Arrays::Structure to a String.
@ square_
square matrix/array/expression
The namespace STK is the main domain space of the Statistical ToolKit project.
utility class that select if the copy will be by row or by column
helper defining the return type of the selector involving expressions of the form expr + number and e...
static void run(Lhs &lhs, ExprBase< Rhs > const &rhs)