1 /*
  2  *   Copyright (c) 2007, Michael Lehn
  3  *
  4  *   All rights reserved.
  5  *
  6  *   Redistribution and use in source and binary forms, with or without
  7  *   modification, are permitted provided that the following conditions
  8  *   are met:
  9  *
 10  *   1) Redistributions of source code must retain the above copyright
 11  *      notice, this list of conditions and the following disclaimer.
 12  *   2) Redistributions in binary form must reproduce the above copyright
 13  *      notice, this list of conditions and the following disclaimer in
 14  *      the documentation and/or other materials provided with the
 15  *      distribution.
 16  *   3) Neither the name of the FLENS development group nor the names of
 17  *      its contributors may be used to endorse or promote products derived
 18  *      from this software without specific prior written permission.
 19  *
 20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31  */
 32 
 33 #ifndef FLENS_MATRIXTYPES_SYMMETRIC_IMPL_SYMATRIX_TCC
 34 #define FLENS_MATRIXTYPES_SYMMETRIC_IMPL_SYMATRIX_TCC 1
 35 
 36 #include <flens/matrixtypes/general/impl/gematrix.h>
 37 #include <flens/matrixtypes/symmetric/impl/symatrix.h>
 38 #include <flens/typedefs.h>
 39 
 40 namespace flens {
 41 
 42 template <typename FS>
 43 SyMatrix<FS>::SyMatrix(const Engine &engine, StorageUpLo upLo)
 44     : _engine(engine), _upLo(upLo)
 45 {
 46     ASSERT(_engine.numRows()==_engine.numCols());
 47 }
 48 
 49 template <typename FS>
 50 SyMatrix<FS>::SyMatrix(const SyMatrix &rhs)
 51     : SymmetricMatrix<SyMatrix<FS> >(),
 52       _engine(rhs.engine()), _upLo(rhs.upLo())
 53 {
 54 }
 55 
 56 template <typename FS>
 57 template <typename RHS>
 58 SyMatrix<FS>::SyMatrix(const SyMatrix<RHS> &rhs)
 59     : _engine(rhs.engine()), _upLo(rhs.upLo())
 60 {
 61 }
 62 
 63 template <typename FS>
 64 template <typename RHS>
 65 SyMatrix<FS>::SyMatrix(SyMatrix<RHS> &rhs)
 66     : _engine(rhs.engine()), _upLo(rhs.upLo())
 67 {
 68 }
 69 
 70 template <typename FS>
 71 template <typename RHS>
 72 SyMatrix<FS>::SyMatrix(const Matrix<RHS> &rhs)
 73 {
 74     assign(rhs, *this);
 75 }
 76 
 77 // -- operators ----------------------------------------------------------------
 78 
 79 template <typename FS>
 80 void
 81 SyMatrix<FS>::operator=(const ElementType &value)
 82 {
 83     engine().fill(_upLo, value);
 84 }
 85 
 86 template <typename FS>
 87 SyMatrix<FS> &
 88 SyMatrix<FS>::operator=(const SyMatrix &rhs)
 89 {
 90     if (this!=&rhs) {
 91         assign(rhs, *this);
 92     }
 93     return *this;
 94 }
 95 
 96 template <typename FS>
 97 template <typename RHS>
 98 SyMatrix<FS> &
 99 SyMatrix<FS>::operator=(const Matrix<RHS> &rhs)
100 {
101     assign(rhs, *this);
102     return *this;
103 }
104 
105 template <typename FS>
106 const typename SyMatrix<FS>::ElementType &
107 SyMatrix<FS>::operator()(IndexType row, IndexType col) const
108 {
109 #   ifndef NDEBUG
110     if (_upLo==Upper) {
111         ASSERT(col-firstCol()>=row-firstRow());
112     } else {
113         ASSERT(col-firstCol()<=row-firstRow());
114     }
115 #   endif
116 
117     return _engine(row, col);
118 }
119 
120 template <typename FS>
121 typename SyMatrix<FS>::ElementType &
122 SyMatrix<FS>::operator()(IndexType row, IndexType col)
123 {
124 #   ifndef NDEBUG
125     if (_upLo==Upper) {
126         ASSERT(col-firstCol()>=row-firstRow());
127     } else {
128         ASSERT(col-firstCol()<=row-firstRow());
129     }
130 #   endif
131 
132     return _engine(row, col);
133 }
134 
135 // rectangular views
136 template <typename FS>
137 const typename SyMatrix<FS>::ConstGeneralView
138 SyMatrix<FS>::operator()(const Range<IndexType> &rows,
139                          const Range<IndexType> &cols) const
140 {
141     return general()(rows, cols);
142 }
143 
144 template <typename FS>
145 typename SyMatrix<FS>::GeneralView
146 SyMatrix<FS>::operator()(const Range<IndexType> &rows,
147                          const Range<IndexType> &cols)
148 {
149     return general()(rows, cols);
150 }
151 
152 // rectangular views (all rows selected)
153 template <typename FS>
154 const typename SyMatrix<FS>::ConstGeneralView
155 SyMatrix<FS>::operator()(const Underscore<IndexType> &_,
156                          const Range<IndexType> &cols) const
157 {
158     return general()(_,cols);
159 }
160 
161 template <typename FS>
162 typename SyMatrix<FS>::GeneralView
163 SyMatrix<FS>::operator()(const Underscore<IndexType> &_,
164                          const Range<IndexType> &cols)
165 {
166     return general()(_,cols);
167 }
168 
169 // rectangular views (all columns selected)
170 template <typename FS>
171 const typename SyMatrix<FS>::ConstGeneralView
172 SyMatrix<FS>::operator()(const Range<IndexType> &rows,
173                          const Underscore<IndexType> &_) const
174 {
175     return general()(rows,_);
176 }
177 
178 template <typename FS>
179 typename SyMatrix<FS>::GeneralView
180 SyMatrix<FS>::operator()(const Range<IndexType> &rows,
181                          const Underscore<IndexType> &_)
182 {
183     return general()(rows,_);
184 }
185 
186 // row view (vector view)
187 template <typename FS>
188 const typename SyMatrix<FS>::ConstVectorView
189 SyMatrix<FS>::operator()(IndexType row, const Underscore<IndexType> &_) const
190 {
191     return general()(row,_);
192 }
193 
194 template <typename FS>
195 typename SyMatrix<FS>::VectorView
196 SyMatrix<FS>::operator()(IndexType row, const Underscore<IndexType> &_)
197 {
198     return general()(row,_);
199 }
200 
201 template <typename FS>
202 const typename SyMatrix<FS>::ConstVectorView
203 SyMatrix<FS>::operator()(IndexType row, const Range<IndexType> &cols) const
204 {
205     return general()(row,cols);
206 }
207 
208 template <typename FS>
209 typename SyMatrix<FS>::VectorView
210 SyMatrix<FS>::operator()(IndexType row, const Range<IndexType> &cols)
211 {
212     return general()(row,cols);
213 }
214 
215 // column view (vector view)
216 template <typename FS>
217 const typename SyMatrix<FS>::ConstVectorView
218 SyMatrix<FS>::operator()(const Underscore<IndexType> &_, IndexType col) const
219 {
220     return general()(_,col);
221 }
222 
223 template <typename FS>
224 typename SyMatrix<FS>::VectorView
225 SyMatrix<FS>::operator()(const Underscore<IndexType> &_, IndexType col)
226 {
227     return general()(_,col);
228 }
229 
230 template <typename FS>
231 const typename SyMatrix<FS>::ConstVectorView
232 SyMatrix<FS>::operator()(const Range<IndexType> &rows, IndexType col) const
233 {
234     return general()(rows,col);
235 }
236 
237 template <typename FS>
238 typename SyMatrix<FS>::VectorView
239 SyMatrix<FS>::operator()(const Range<IndexType> &rows, IndexType col)
240 {
241     return general()(rows,col);
242 }
243 
244 // -- views --------------------------------------------------------------------
245 // general views
246 template <typename FS>
247 const typename SyMatrix<FS>::ConstGeneralView
248 SyMatrix<FS>::general() const
249 {
250     return ConstGeneralView(_engine);
251 }
252 
253 template <typename FS>
254 typename SyMatrix<FS>::GeneralView
255 SyMatrix<FS>::general()
256 {
257     return GeneralView(_engine);
258 }
259 
260 // hermitian views
261 template <typename FS>
262 const typename SyMatrix<FS>::ConstHermitianView
263 SyMatrix<FS>::hermitian() const
264 {
265     return ConstHermitianView(_engine, upLo());
266 }
267 
268 template <typename FS>
269 typename SyMatrix<FS>::HermitianView
270 SyMatrix<FS>::hermitian()
271 {
272     return HermitianView(_engine, upLo());
273 }
274 
275 // triangular views
276 template <typename FS>
277 const typename SyMatrix<FS>::ConstTriangularView
278 SyMatrix<FS>::triangular() const
279 {
280     if (upLo()==Upper) {
281         return general().upper();
282     }
283     return general().lower();
284 }
285 
286 template <typename FS>
287 typename SyMatrix<FS>::TriangularView
288 SyMatrix<FS>::triangular()
289 {
290     if (upLo()==Upper) {
291         return general().upper();
292     }
293     return general().lower();
294 }
295 
296 // -- methods ------------------------------------------------------------------
297 template <typename FS>
298 typename SyMatrix<FS>::IndexType
299 SyMatrix<FS>::dim() const
300 {
301     ASSERT(_engine.numRows()==_engine.numCols());
302 
303     return _engine.numRows();
304 }
305 
306 template <typename FS>
307 typename SyMatrix<FS>::IndexType
308 SyMatrix<FS>::numRows() const
309 {
310     return _engine.numRows();
311 }
312 
313 template <typename FS>
314 typename SyMatrix<FS>::IndexType
315 SyMatrix<FS>::numCols() const
316 {
317     return _engine.numCols();
318 }
319 
320 
321 template <typename FS>
322 typename SyMatrix<FS>::IndexType
323 SyMatrix<FS>::firstRow() const
324 {
325     return _engine.firstRow();
326 }
327 
328 template <typename FS>
329 typename SyMatrix<FS>::IndexType
330 SyMatrix<FS>::lastRow() const
331 {
332     return _engine.lastRow();
333 }
334 
335 template <typename FS>
336 typename SyMatrix<FS>::IndexType
337 SyMatrix<FS>::firstCol() const
338 {
339     return _engine.firstCol();
340 }
341 
342 template <typename FS>
343 typename SyMatrix<FS>::IndexType
344 SyMatrix<FS>::lastCol() const
345 {
346     return _engine.lastCol();
347 }
348 
349 template <typename FS>
350 const typename SyMatrix<FS>::ElementType *
351 SyMatrix<FS>::data() const
352 {
353     return _engine.data();
354 }
355 
356 template <typename FS>
357 typename SyMatrix<FS>::ElementType *
358 SyMatrix<FS>::data()
359 {
360     return _engine.data();
361 }
362 
363 template <typename FS>
364 typename SyMatrix<FS>::IndexType
365 SyMatrix<FS>::leadingDimension() const
366 {
367     return _engine.leadingDimension();
368 }
369 
370 template <typename FS>
371 StorageOrder
372 SyMatrix<FS>::order() const
373 {
374     return _engine.order;
375 }
376 
377 template <typename FS>
378 template <typename RHS>
379 bool
380 SyMatrix<FS>::resize(const SyMatrix<RHS> &rhs,
381                      const ElementType &value)
382 {
383     return _engine.resize(rhs.engine(), value);
384 }
385 
386 template <typename FS>
387 bool
388 SyMatrix<FS>::resize(IndexType dim, IndexType firstIndex,
389                      const ElementType &value)
390 {
391     return _engine.resize(dim, dim, firstIndex, firstIndex, value);
392 }
393 
394 // -- implementation -----------------------------------------------------------
395 
396 template <typename FS>
397 const typename SyMatrix<FS>::Engine &
398 SyMatrix<FS>::engine() const
399 {
400     return _engine;
401 }
402 
403 template <typename FS>
404 typename SyMatrix<FS>::Engine &
405 SyMatrix<FS>::engine()
406 {
407     return _engine;
408 }
409 
410 template <typename FS>
411 StorageUpLo
412 SyMatrix<FS>::upLo() const
413 {
414     return _upLo;
415 }
416 
417 template <typename FS>
418 StorageUpLo &
419 SyMatrix<FS>::upLo()
420 {
421     return _upLo;
422 }
423 
424 // namespace flens
425 
426 #endif // FLENS_MATRIXTYPES_SYMMETRIC_IMPL_SYMATRIX_TCC