cisst-saw
Loading...
Searching...
No Matches
vctDynamicMatrixLoopEngines.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5 Author(s): Ofri Sadowsky, Anton Deguet
6 Created on: 2003-12-16
7
8 (C) Copyright 2003-2019 Johns Hopkins University (JHU), All Rights Reserved.
9
10--- begin cisst license - do not edit ---
11
12This software is provided "as is" under an open source license, with
13no warranty. The complete license can be found in license.txt and
14http://www.cisst.org/cisst/license.txt.
15
16--- end cisst license ---
17*/
18
19#pragma once
20#ifndef _vctDynamicMatrixLoopEngines_h
21#define _vctDynamicMatrixLoopEngines_h
22
27
31
38
39public:
40
43 template <typename _nsize_type>
44 inline static void ThrowSizeMismatchException(const _nsize_type & expected,
45 const _nsize_type & received) CISST_THROW(std::runtime_error) {
46 std::stringstream message;
47 message << "vctDynamicMatrixLoopEngines: Sizes of matrices don't match, expected: [" << expected
48 << "], received: [" << received << "]";
49 cmnThrow(std::runtime_error(message.str()));
50 }
51
55 inline static void ThrowSharedPointersException(void) CISST_THROW(std::runtime_error) {
56 cmnThrow(std::runtime_error("vctDynamicMatrixLoopEngines: Output base pointer is same as one of input base pointers."));
57 }
58
59
91 template<class _elementOperationType>
92 class MoMiMi {
93 public:
94 template<class _outputMatrixType, class _input1MatrixType, class _input2MatrixType>
95 static void Run(_outputMatrixType & outputMatrix,
96 const _input1MatrixType & input1Matrix,
97 const _input2MatrixType & input2Matrix)
98 {
99 typedef _outputMatrixType OutputMatrixType;
100 typedef typename OutputMatrixType::OwnerType OutputOwnerType;
101 typedef typename OutputOwnerType::size_type size_type;
102 typedef typename OutputOwnerType::stride_type stride_type;
103 typedef typename OutputOwnerType::pointer OutputPointerType;
104
105 typedef _input1MatrixType Input1MatrixType;
106 typedef typename Input1MatrixType::OwnerType Input1OwnerType;
107 typedef typename Input1OwnerType::const_pointer Input1PointerType;
108
109 typedef _input2MatrixType Input2MatrixType;
110 typedef typename Input2MatrixType::OwnerType Input2OwnerType;
111 typedef typename Input2OwnerType::const_pointer Input2PointerType;
112
113 // retrieve owners
114 OutputOwnerType & outputOwner = outputMatrix.Owner();
115 const Input1OwnerType & input1Owner = input1Matrix.Owner();
116 const Input2OwnerType & input2Owner = input2Matrix.Owner();
117
118 const size_type rows = outputOwner.rows();
119 const size_type cols = outputOwner.cols();
120
121 // check sizes
122 if ((rows != input1Owner.rows())
123 || (cols != input1Owner.cols())) {
124 ThrowSizeMismatchException(outputOwner.sizes(),
125 input1Owner.sizes());
126 } else if ((rows != input2Owner.rows())
127 || (cols != input2Owner.cols())) {
128 ThrowSizeMismatchException(outputOwner.sizes(),
129 input2Owner.sizes());
130 }
131
132 // if compact and same strides
133 if (outputOwner.IsCompact() && input1Owner.IsCompact() && input2Owner.IsCompact()
134 && (outputOwner.strides() == input1Owner.strides())
135 && (outputOwner.strides() == input2Owner.strides())) {
136 vctDynamicCompactLoopEngines::CoCiCi<_elementOperationType>::Run(outputOwner, input1Owner, input2Owner);
137 } else {
138 const stride_type outputColStride = outputOwner.col_stride();
139 const stride_type outputRowStride = outputOwner.row_stride();
140 const stride_type outputStrideToNextRow = outputRowStride - cols * outputColStride;
141
142 const stride_type input1ColStride = input1Owner.col_stride();
143 const stride_type input1RowStride = input1Owner.row_stride();
144 const stride_type input1StrideToNextRow = input1RowStride - cols * input1ColStride;
145
146 const stride_type input2ColStride = input2Owner.col_stride();
147 const stride_type input2RowStride = input2Owner.row_stride();
148 const stride_type input2StrideToNextRow = input2RowStride - cols * input2ColStride;
149
150 OutputPointerType outputPointer = outputOwner.Pointer();
151 const OutputPointerType outputRowEnd = outputPointer + rows * outputRowStride;
152 OutputPointerType outputColEnd = outputPointer + cols * outputColStride;
153
154 Input1PointerType input1Pointer = input1Owner.Pointer();
155 Input2PointerType input2Pointer = input2Owner.Pointer();
156
157 for (;
158 outputPointer != outputRowEnd;
159 outputPointer += outputStrideToNextRow, input1Pointer += input1StrideToNextRow, input2Pointer += input2StrideToNextRow,
160 outputColEnd += outputRowStride) {
161 for (;
162 outputPointer != outputColEnd;
163 outputPointer += outputColStride, input1Pointer += input1ColStride, input2Pointer += input2ColStride) {
164 *outputPointer = _elementOperationType::Operate(*input1Pointer, *input2Pointer);
165 }
166 }
167 }
168 } // Run method
169 }; // MoMiMi class
170
171
172 template<class _elementOperationType>
173 class MoMi {
174 public:
175 template<class _outputMatrixType, class _inputMatrixType>
176 static inline void Run(_outputMatrixType & outputMatrix,
177 const _inputMatrixType & inputMatrix)
178 {
179 typedef _outputMatrixType OutputMatrixType;
180 typedef typename OutputMatrixType::OwnerType OutputOwnerType;
181 typedef typename OutputOwnerType::size_type size_type;
182 typedef typename OutputOwnerType::stride_type stride_type;
183 typedef typename OutputOwnerType::pointer OutputPointerType;
184
185 typedef _inputMatrixType InputMatrixType;
186 typedef typename InputMatrixType::OwnerType InputOwnerType;
187 typedef typename InputOwnerType::const_pointer InputPointerType;
188
189 // retrieve owners
190 const InputOwnerType & inputOwner = inputMatrix.Owner();
191 OutputOwnerType & outputOwner = outputMatrix.Owner();
192
193 const size_type rows = outputMatrix.rows();
194 const size_type cols = outputMatrix.cols();
195
196 // check sizes
197 if ((rows != inputOwner.rows()) || (cols != inputOwner.cols())) {
198 ThrowSizeMismatchException(outputOwner.sizes(), inputOwner.sizes());
199 }
200
201 // if compact and same strides
202 if (outputOwner.IsCompact() && inputOwner.IsCompact()
203 && (outputOwner.strides() == inputOwner.strides())) {
205 } else {
206 // otherwise
207 const stride_type outputColStride = outputOwner.col_stride();
208 const stride_type outputRowStride = outputOwner.row_stride();
209 const stride_type outputStrideToNextRow = outputRowStride - cols * outputColStride;
210
211 const stride_type inputColStride = inputOwner.col_stride();
212 const stride_type inputRowStride = inputOwner.row_stride();
213 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
214
215 OutputPointerType outputPointer = outputOwner.Pointer();
216 const OutputPointerType outputRowEnd = outputPointer + rows * outputRowStride;
217 OutputPointerType outputColEnd = outputPointer + cols * outputColStride;
218
219 InputPointerType inputPointer = inputOwner.Pointer();
220
221 for (;
222 outputPointer != outputRowEnd;
223 outputPointer += outputStrideToNextRow, inputPointer += inputStrideToNextRow,
224 outputColEnd += outputRowStride) {
225 for (;
226 outputPointer != outputColEnd;
227 outputPointer += outputColStride, inputPointer += inputColStride) {
228 *outputPointer = _elementOperationType::Operate(*inputPointer);
229 }
230 }
231 } // Compact engine if
232 } // Run method
233 }; // MoMi class
234
235
236 template<class _elementOperationType>
237 class Mio {
238 public:
239 template<class _inputOutputMatrixType>
240 static inline void Run(_inputOutputMatrixType & inputOutputMatrix)
241 {
242 typedef _inputOutputMatrixType InputOutputMatrixType;
243 typedef typename InputOutputMatrixType::OwnerType InputOutputOwnerType;
244 typedef typename InputOutputOwnerType::size_type size_type;
245 typedef typename InputOutputOwnerType::stride_type stride_type;
246 typedef typename InputOutputOwnerType::pointer PointerType;
247
248 // retrieve owner
249 InputOutputOwnerType & inputOutputOwner = inputOutputMatrix.Owner();
250
251 // if compact
252 if (inputOutputOwner.IsCompact()) {
254 } else {
255 const size_type rows = inputOutputOwner.rows();
256 const size_type cols = inputOutputOwner.cols();
257
258 const stride_type colStride = inputOutputOwner.col_stride();
259 const stride_type rowStride = inputOutputOwner.row_stride();
260 const stride_type strideToNextRow = rowStride - cols * colStride;
261
262 PointerType inputOutputPointer = inputOutputOwner.Pointer();
263 const PointerType rowEnd = inputOutputPointer + rows * rowStride;
264 PointerType colEnd = inputOutputPointer + cols * colStride;
265
266 for (;
267 inputOutputPointer != rowEnd;
268 inputOutputPointer += strideToNextRow, colEnd += rowStride) {
269 for (;
270 inputOutputPointer != colEnd;
271 inputOutputPointer += colStride) {
272 _elementOperationType::Operate(*inputOutputPointer);
273 }
274 }
275 }
276 } // Run method
277 }; // Mio class
278
279
280 template<class _elementOperationType>
281 class MioMi {
282 public:
283 template<class _inputOutputMatrixType, class _inputMatrixType>
284 static inline void Run(_inputOutputMatrixType & inputOutputMatrix,
285 const _inputMatrixType & inputMatrix)
286 {
287 typedef _inputOutputMatrixType InputOutputMatrixType;
288 typedef typename InputOutputMatrixType::OwnerType InputOutputOwnerType;
289 typedef typename InputOutputOwnerType::size_type size_type;
290 typedef typename InputOutputOwnerType::stride_type stride_type;
291 typedef typename InputOutputOwnerType::pointer InputOutputPointerType;
292
293 typedef _inputMatrixType InputMatrixType;
294 typedef typename InputMatrixType::OwnerType InputOwnerType;
295 typedef typename InputOwnerType::const_pointer InputPointerType;
296
297 // retrieve owners
298 InputOutputOwnerType & inputOutputOwner = inputOutputMatrix.Owner();
299 const InputOwnerType & inputOwner = inputMatrix.Owner();
300
301 const size_type rows = inputOutputOwner.rows();
302 const size_type cols = inputOutputOwner.cols();
303
304 // check sizes
305 if ((rows != inputOwner.rows()) || (cols != inputOwner.cols())) {
306 ThrowSizeMismatchException(inputOutputOwner.sizes(), inputOwner.sizes());
307 }
308
309 // if compact and same strides
310 if (inputOutputOwner.IsCompact() && inputOwner.IsCompact()
311 && (inputOutputOwner.strides() == inputOwner.strides())) {
313 } else {
314 const stride_type inputOutputColStride = inputOutputOwner.col_stride();
315 const stride_type inputOutputRowStride = inputOutputOwner.row_stride();
316 const stride_type inputOutputStrideToNextRow = inputOutputRowStride - cols * inputOutputColStride;
317
318 const stride_type inputColStride = inputOwner.col_stride();
319 const stride_type inputRowStride = inputOwner.row_stride();
320 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
321
322 InputOutputPointerType inputOutputPointer = inputOutputOwner.Pointer();
323 const InputOutputPointerType inputOutputRowEnd = inputOutputPointer + rows * inputOutputRowStride;
324 InputOutputPointerType inputOutputColEnd = inputOutputPointer + cols * inputOutputColStride;
325
326 InputPointerType inputPointer = inputOwner.Pointer();
327
328 for (;
329 inputOutputPointer != inputOutputRowEnd;
330 inputOutputPointer += inputOutputStrideToNextRow, inputPointer += inputStrideToNextRow,
331 inputOutputColEnd += inputOutputRowStride) {
332 for (;
333 inputOutputPointer != inputOutputColEnd;
334 inputOutputPointer += inputOutputColStride, inputPointer += inputColStride) {
335 _elementOperationType::Operate(*inputOutputPointer, *inputPointer);
336 }
337 }
338 }
339 } // Run method
340 }; // MioMi class
341
342
343 template<class _elementOperationType>
344 class MoMiSi {
345 public:
346 template<class _outputMatrixType, class _inputMatrixType, class _inputScalarType>
347 static void Run(_outputMatrixType & outputMatrix,
348 const _inputMatrixType & inputMatrix,
349 const _inputScalarType inputScalar)
350 {
351 typedef _outputMatrixType OutputMatrixType;
352 typedef typename OutputMatrixType::OwnerType OutputOwnerType;
353 typedef typename OutputOwnerType::size_type size_type;
354 typedef typename OutputOwnerType::stride_type stride_type;
355 typedef typename OutputOwnerType::pointer OutputPointerType;
356
357 typedef _inputMatrixType InputMatrixType;
358 typedef typename InputMatrixType::OwnerType InputOwnerType;
359 typedef typename InputOwnerType::const_pointer InputPointerType;
360
361 // retrieve owners
362 OutputOwnerType & outputOwner = outputMatrix.Owner();
363 const InputOwnerType & inputOwner = inputMatrix.Owner();
364
365 const size_type rows = outputOwner.rows();
366 const size_type cols = outputOwner.cols();
367
368 // check sizes
369 if ((rows != inputOwner.rows()) || (cols != inputOwner.cols())) {
370 ThrowSizeMismatchException(outputOwner.sizes(), inputOwner.sizes());
371 }
372
373 // if compact and same strides
374 if (outputOwner.IsCompact() && inputOwner.IsCompact()
375 && (outputOwner.strides() == inputOwner.strides())) {
376 vctDynamicCompactLoopEngines::CoCiSi<_elementOperationType>::Run(outputOwner, inputOwner, inputScalar);
377 } else {
378 // otherwise
379 const stride_type outputColStride = outputOwner.col_stride();
380 const stride_type outputRowStride = outputOwner.row_stride();
381 const stride_type outputStrideToNextRow = outputRowStride - cols * outputColStride;
382
383 const stride_type inputColStride = inputOwner.col_stride();
384 const stride_type inputRowStride = inputOwner.row_stride();
385 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
386
387 OutputPointerType outputPointer = outputOwner.Pointer();
388 const OutputPointerType outputRowEnd = outputPointer + rows * outputRowStride;
389 OutputPointerType outputColEnd = outputPointer + cols * outputColStride;
390
391 InputPointerType inputPointer = inputOwner.Pointer();
392
393 for (;
394 outputPointer != outputRowEnd;
395 outputPointer += outputStrideToNextRow, inputPointer += inputStrideToNextRow,
396 outputColEnd += outputRowStride) {
397 for (;
398 outputPointer != outputColEnd;
399 outputPointer += outputColStride, inputPointer += inputColStride) {
400 *outputPointer = _elementOperationType::Operate(*inputPointer, inputScalar);
401 }
402 }
403 }
404 } // Run method
405 }; // MoMiSi
406
407
408 template<class _elementOperationType>
409 class MoSiMi {
410 public:
411 template<class _outputMatrixType, class _inputScalarType, class _inputMatrixType>
412 static void Run(_outputMatrixType & outputMatrix,
413 const _inputScalarType inputScalar,
414 const _inputMatrixType & inputMatrix)
415 {
416 typedef _outputMatrixType OutputMatrixType;
417 typedef typename OutputMatrixType::OwnerType OutputOwnerType;
418 typedef typename OutputOwnerType::size_type size_type;
419 typedef typename OutputOwnerType::stride_type stride_type;
420 typedef typename OutputOwnerType::pointer OutputPointerType;
421
422 typedef _inputMatrixType InputMatrixType;
423 typedef typename InputMatrixType::OwnerType InputOwnerType;
424 typedef typename InputOwnerType::const_pointer InputPointerType;
425
426 // retrieve owners
427 OutputOwnerType & outputOwner = outputMatrix.Owner();
428 const InputOwnerType & inputOwner = inputMatrix.Owner();
429
430 const size_type rows = outputOwner.rows();
431 const size_type cols = outputOwner.cols();
432
433 // check sizes
434 if ((rows != inputOwner.rows()) || (cols != inputOwner.cols())) {
435 ThrowSizeMismatchException(outputOwner.sizes(), inputOwner.sizes());
436 }
437
438 // if compact and same strides
439 if (outputOwner.IsCompact() && inputOwner.IsCompact()
440 && (outputOwner.strides() == inputOwner.strides())) {
441 vctDynamicCompactLoopEngines::CoSiCi<_elementOperationType>::Run(outputOwner, inputScalar, inputOwner);
442 } else {
443 // otherwise
444 const stride_type outputColStride = outputOwner.col_stride();
445 const stride_type outputRowStride = outputOwner.row_stride();
446 const stride_type outputStrideToNextRow = outputRowStride - cols * outputColStride;
447
448 const stride_type inputColStride = inputOwner.col_stride();
449 const stride_type inputRowStride = inputOwner.row_stride();
450 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
451
452 OutputPointerType outputPointer = outputOwner.Pointer();
453 const OutputPointerType outputRowEnd = outputPointer + rows * outputRowStride;
454 OutputPointerType outputColEnd = outputPointer + cols * outputColStride;
455
456 InputPointerType inputPointer = inputOwner.Pointer();
457
458 for (;
459 outputPointer != outputRowEnd;
460 outputPointer += outputStrideToNextRow, inputPointer += inputStrideToNextRow,
461 outputColEnd += outputRowStride) {
462 for (;
463 outputPointer != outputColEnd;
464 outputPointer += outputColStride, inputPointer += inputColStride) {
465 *outputPointer = _elementOperationType::Operate(inputScalar, *inputPointer);
466 }
467 }
468 }
469 } // Run method
470 }; // MoSiMi class
471
472
473 template<class _elementOperationType>
474 class MioSi {
475 public:
476 template<class _inputOutputMatrixType, class _inputScalarType>
477 static void Run(_inputOutputMatrixType & inputOutputMatrix,
478 const _inputScalarType inputScalar)
479 {
480 typedef _inputOutputMatrixType InputOutputMatrixType;
481 typedef typename InputOutputMatrixType::OwnerType InputOutputOwnerType;
482 typedef typename InputOutputOwnerType::size_type size_type;
483 typedef typename InputOutputOwnerType::stride_type stride_type;
484 typedef typename InputOutputOwnerType::pointer InputOutputPointerType;
485
486 // retrieve owner
487 InputOutputOwnerType & inputOutputOwner = inputOutputMatrix.Owner();
488
489 if (inputOutputOwner.IsCompact()) {
491 } else {
492 const size_type rows = inputOutputOwner.rows();
493 const size_type cols = inputOutputOwner.cols();
494
495 const stride_type colStride = inputOutputOwner.col_stride();
496 const stride_type rowStride = inputOutputOwner.row_stride();
497 const stride_type strideToNextRow = rowStride - cols * colStride;
498
499 InputOutputPointerType inputOutputPointer = inputOutputOwner.Pointer();
500 const InputOutputPointerType rowEnd = inputOutputPointer + rows * rowStride;
501 InputOutputPointerType colEnd = inputOutputPointer + cols * colStride;
502
503 for (;
504 inputOutputPointer != rowEnd;
505 inputOutputPointer += strideToNextRow, colEnd += rowStride) {
506 for (;
507 inputOutputPointer != colEnd;
508 inputOutputPointer += colStride) {
509 _elementOperationType::Operate(*inputOutputPointer, inputScalar);
510 }
511 }
512 }
513 } // Run method
514 }; // MioSi class
515
516
517 template<class _incrementalOperationType, class _elementOperationType>
518 class SoMi {
519 public:
520 typedef typename _incrementalOperationType::OutputType OutputType;
521
522 template<class _inputMatrixType>
523 static OutputType Run(const _inputMatrixType & inputMatrix)
524 {
525 typedef _inputMatrixType InputMatrixType;
526 typedef typename InputMatrixType::OwnerType InputOwnerType;
527 typedef typename InputOwnerType::size_type size_type;
528 typedef typename InputOwnerType::stride_type stride_type;
529 typedef typename InputOwnerType::const_pointer InputPointerType;
530
531 // retrieve owner
532 const InputOwnerType & inputOwner = inputMatrix.Owner();
533
534 if (inputOwner.IsCompact()) {
536 ::Run(inputOwner);
537 } else {
538 const size_type rows = inputOwner.rows();
539 const size_type cols = inputOwner.cols();
540
541 OutputType incrementalResult = _incrementalOperationType::NeutralElement();
542
543 const stride_type inputColStride = inputOwner.col_stride();
544 const stride_type inputRowStride = inputOwner.row_stride();
545 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
546 InputPointerType inputPointer = inputOwner.Pointer();
547 const InputPointerType inputRowEnd = inputPointer + rows * inputRowStride;
548 InputPointerType inputColEnd = inputPointer + cols * inputColStride;
549
550 for (;
551 inputPointer != inputRowEnd;
552 inputPointer += inputStrideToNextRow, inputColEnd += inputRowStride) {
553 for (;
554 inputPointer != inputColEnd;
555 inputPointer += inputColStride) {
556 incrementalResult = _incrementalOperationType::Operate(
557 incrementalResult, _elementOperationType::Operate(*inputPointer) );
558 }
559 }
560 return incrementalResult;
561 }
562 } // Run method
563 }; // SoMi class
564
565
566 template<class _incrementalOperationType, class _elementOperationType>
567 class SoMiMi {
568 public:
569 typedef typename _incrementalOperationType::OutputType OutputType;
570
571 template<class _input1MatrixType, class _input2MatrixType>
572 static OutputType Run(const _input1MatrixType & input1Matrix,
573 const _input2MatrixType & input2Matrix) {
574 typedef _input1MatrixType Input1MatrixType;
575 typedef typename Input1MatrixType::OwnerType Input1OwnerType;
576 typedef typename Input1OwnerType::size_type size_type;
577 typedef typename Input1OwnerType::stride_type stride_type;
578 typedef typename Input1OwnerType::const_pointer Input1PointerType;
579
580 typedef _input2MatrixType Input2MatrixType;
581 typedef typename Input2MatrixType::OwnerType Input2OwnerType;
582 typedef typename Input2OwnerType::const_pointer Input2PointerType;
583
584 // retrieve owners
585 const Input1OwnerType & input1Owner = input1Matrix.Owner();
586 const Input2OwnerType & input2Owner = input2Matrix.Owner();
587
588 const size_type rows = input1Owner.rows();
589 const size_type cols = input1Owner.cols();
590
591 // check sizes
592 if ((rows != input2Owner.rows()) || (cols != input2Owner.cols())) {
593 ThrowSizeMismatchException(input1Owner.sizes(), input2Owner.sizes());
594 }
595
596 // if compact and same strides
597 if (input1Owner.IsCompact() && input2Owner.IsCompact()
598 && (input1Owner.strides() == input2Owner.strides())) {
600 } else {
601 // otherwise
602 OutputType incrementalResult = _incrementalOperationType::NeutralElement();
603 const stride_type input1ColStride = input1Owner.col_stride();
604 const stride_type input1RowStride = input1Owner.row_stride();
605 const stride_type input1StrideToNextRow = input1RowStride - cols * input1ColStride;
606
607 const stride_type input2ColStride = input2Owner.col_stride();
608 const stride_type input2RowStride = input2Owner.row_stride();
609 const stride_type input2StrideToNextRow = input2RowStride - cols * input2ColStride;
610
611 Input1PointerType input1Pointer = input1Owner.Pointer();
612 const Input1PointerType input1RowEnd = input1Pointer + rows * input1RowStride;
613 Input1PointerType input1ColEnd = input1Pointer + cols * input1ColStride;
614
615 Input2PointerType input2Pointer = input2Owner.Pointer();
616
617 for (;
618 input1Pointer != input1RowEnd;
619 input1Pointer += input1StrideToNextRow, input2Pointer += input2StrideToNextRow,
620 input1ColEnd += input1RowStride) {
621 for (;
622 input1Pointer != input1ColEnd;
623 input1Pointer += input1ColStride, input2Pointer += input2ColStride) {
624 incrementalResult = _incrementalOperationType::Operate(incrementalResult,
625 _elementOperationType::Operate(*input1Pointer, *input2Pointer) );
626 }
627 }
628 return incrementalResult;
629 }
630 }
631 };
632
633
659 template<class _ioElementOperationType, class _scalarMatrixElementOperationType>
661 {
662 public:
663
664 template<class _ioMatrixType, class _inputScalarType, class _inputMatrixType>
665 static inline void Run(_ioMatrixType & ioMatrix,
666 const _inputScalarType & inputScalar,
667 const _inputMatrixType & inputMatrix)
668 {
669 typedef _ioMatrixType IoMatrixType;
670 typedef typename IoMatrixType::OwnerType IoOwnerType;
671 typedef typename IoOwnerType::size_type size_type;
672 typedef typename IoOwnerType::stride_type stride_type;
673 typedef typename IoOwnerType::pointer IoPointerType;
674
675 typedef _inputMatrixType InputMatrixType;
676 typedef typename InputMatrixType::OwnerType InputOwnerType;
677 typedef typename InputOwnerType::const_pointer InputPointerType;
678
679 // retrieve owners
680 IoOwnerType & ioOwner = ioMatrix.Owner();
681 const InputOwnerType & inputOwner = inputMatrix.Owner();
682
683 const size_type rows = ioOwner.rows();
684 const size_type cols = ioOwner.cols();
685
686 // check sizes
687 if ((rows != inputOwner.rows()) || (cols != inputOwner.cols())) {
688 ThrowSizeMismatchException(ioOwner.sizes(), inputOwner.sizes());
689 }
690
691 // if compact and same strides
692 if (ioOwner.IsCompact() && inputOwner.IsCompact()
693 && (ioOwner.strides() == inputOwner.strides())) {
695 } else {
696 // otherwise
697 const stride_type ioColStride = ioOwner.col_stride();
698 const stride_type ioRowStride = ioOwner.row_stride();
699 const stride_type ioStrideToNextRow = ioRowStride - cols * ioColStride;
700
701 const stride_type inputColStride = inputOwner.col_stride();
702 const stride_type inputRowStride = inputOwner.row_stride();
703 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
704
705 IoPointerType ioPointer = ioOwner.Pointer();
706 InputPointerType inputPointer = inputOwner.Pointer();
707
708 size_type rowIndex, colIndex;
709 for (rowIndex = 0;
710 rowIndex < rows;
711 ++rowIndex, ioPointer += ioStrideToNextRow, inputPointer += inputStrideToNextRow) {
712 for (colIndex = 0;
713 colIndex < cols;
714 ++colIndex, ioPointer += ioColStride, inputPointer += inputColStride) {
715 _ioElementOperationType::Operate(*ioPointer,
716 _scalarMatrixElementOperationType::Operate(inputScalar, *inputPointer));
717 }
718 }
719 }
720 }
721 };
722
723
750 template<class _ioElementOperationType, class _matrixElementOperationType>
752 {
753 public:
754
755 template<class _ioMatrixType, class _input1MatrixType, class _input2MatrixType>
756 static inline void Run(_ioMatrixType & ioMatrix,
757 const _input1MatrixType & input1Matrix,
758 const _input2MatrixType & input2Matrix)
759 {
760 typedef _ioMatrixType IoMatrixType;
761 typedef typename IoMatrixType::OwnerType IoOwnerType;
762 typedef typename IoOwnerType::size_type size_type;
763 typedef typename IoOwnerType::stride_type stride_type;
764 typedef typename IoOwnerType::pointer IoPointerType;
765
766 typedef _input1MatrixType Input1MatrixType;
767 typedef typename Input1MatrixType::OwnerType Input1OwnerType;
768 typedef typename Input1OwnerType::const_pointer Input1PointerType;
769
770 typedef _input2MatrixType Input2MatrixType;
771 typedef typename Input2MatrixType::OwnerType Input2OwnerType;
772 typedef typename Input2OwnerType::const_pointer Input2PointerType;
773
774 // retrieve owners
775 IoOwnerType & ioOwner = ioMatrix.Owner();
776 const Input1OwnerType & input1Owner = input1Matrix.Owner();
777 const Input2OwnerType & input2Owner = input2Matrix.Owner();
778
779 const size_type rows = ioOwner.rows();
780 const size_type cols = ioOwner.cols();
781
782 // check sizes
783 if ((rows != input1Owner.rows())
784 || (cols != input1Owner.cols())) {
785 ThrowSizeMismatchException(ioOwner.sizes(),
786 input1Owner.sizes());
787 } else if ((rows != input2Owner.rows())
788 || (cols != input2Owner.cols())) {
789 ThrowSizeMismatchException(ioOwner.sizes(),
790 input2Owner.sizes());
791 }
792
793 // if compact and same strides
794 if (ioOwner.IsCompact() && input1Owner.IsCompact() && input2Owner.IsCompact()
795 && (ioOwner.strides() == input1Owner.strides())
796 && (ioOwner.strides() == input2Owner.strides())) {
798 } else {
799 // otherwise
800 const stride_type ioColStride = ioOwner.col_stride();
801 const stride_type ioRowStride = ioOwner.row_stride();
802 const stride_type ioStrideToNextRow = ioRowStride - cols * ioColStride;
803
804 const stride_type input1ColStride = input1Owner.col_stride();
805 const stride_type input1RowStride = input1Owner.row_stride();
806 const stride_type input1StrideToNextRow = input1RowStride - cols * input1ColStride;
807
808 const stride_type input2ColStride = input2Owner.col_stride();
809 const stride_type input2RowStride = input2Owner.row_stride();
810 const stride_type input2StrideToNextRow = input2RowStride - cols * input2ColStride;
811
812 IoPointerType ioPointer = ioOwner.Pointer();
813 Input1PointerType input1Pointer = input1Owner.Pointer();
814 Input2PointerType input2Pointer = input2Owner.Pointer();
815
816 size_type rowIndex, colIndex;
817 for (rowIndex = 0;
818 rowIndex < rows;
819 ++rowIndex, ioPointer += ioStrideToNextRow,
820 input1Pointer += input1StrideToNextRow,
821 input2Pointer += input2StrideToNextRow) {
822 for (colIndex = 0;
823 colIndex < cols;
824 ++colIndex, ioPointer += ioColStride,
825 input1Pointer += input1ColStride,
826 input2Pointer += input2ColStride) {
827 _ioElementOperationType::Operate(*ioPointer,
828 _matrixElementOperationType::Operate(*input1Pointer, *input2Pointer));
829 }
830 }
831 }
832 }
833 };
834
835
836 template<class _incrementalOperationType, class _elementOperationType>
837 class SoMiSi {
838 public:
839 typedef typename _incrementalOperationType::OutputType OutputType;
840
841 template<class _inputMatrixType, class _inputScalarType>
842 static OutputType Run(const _inputMatrixType & inputMatrix,
843 const _inputScalarType & inputScalar)
844 {
845 typedef _inputMatrixType InputMatrixType;
846 typedef typename InputMatrixType::OwnerType InputOwnerType;
847 typedef typename InputOwnerType::size_type size_type;
848 typedef typename InputOwnerType::stride_type stride_type;
849 typedef typename InputOwnerType::const_pointer InputPointerType;
850
851 // retrieve owners
852 const InputOwnerType & inputOwner = inputMatrix.Owner();
853
854 const size_type rows = inputOwner.rows();
855 const size_type cols = inputOwner.cols();
856
857 // if compact and same strides
858 if (inputOwner.IsCompact()) {
860 } else {
861 // otherwise
862 OutputType incrementalResult = _incrementalOperationType::NeutralElement();
863
864 const stride_type inputColStride = inputOwner.col_stride();
865 const stride_type inputRowStride = inputOwner.row_stride();
866 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
867 InputPointerType inputPointer = inputOwner.Pointer();
868 const InputPointerType inputRowEnd = inputPointer + rows * inputRowStride;
869 InputPointerType inputColEnd = inputPointer + cols * inputColStride;
870
871 for (;
872 inputPointer != inputRowEnd;
873 inputPointer += inputStrideToNextRow, inputColEnd += inputRowStride) {
874 for (;
875 inputPointer != inputColEnd;
876 inputPointer += inputColStride) {
877 incrementalResult =
878 _incrementalOperationType::Operate(incrementalResult,
879 _elementOperationType::Operate(*inputPointer, inputScalar));
880 }
881 }
882 return incrementalResult;
883 }
884 }
885 };
886
887
888
889 template<class _operationType>
890 class Product {
891 public:
892 template<class _outputMatrixType, class _input1MatrixType, class _input2MatrixType>
893 static void Run(_outputMatrixType & outputMatrix,
894 const _input1MatrixType & input1Matrix,
895 const _input2MatrixType & input2Matrix)
896 {
897 typedef _outputMatrixType OutputMatrixType;
898 typedef typename OutputMatrixType::size_type size_type;
899 typedef typename OutputMatrixType::stride_type stride_type;
900 typedef typename OutputMatrixType::pointer OutputPointerType;
901
902 typedef _input1MatrixType Input1MatrixType;
903 typedef typename Input1MatrixType::const_pointer Input1PointerType;
904
905 typedef _input2MatrixType Input2MatrixType;
906 typedef typename Input2MatrixType::const_pointer Input2PointerType;
907
908 const size_type rows = outputMatrix.rows();
909 const size_type cols = outputMatrix.cols();
910 const size_type input1Cols = input1Matrix.cols();
911 // check sizes
912 if (rows != input1Matrix.rows()) {
913 std::stringstream message;
914 message << "vctDynamicMatrixLoopEngines::Product: Sizes of matrices don't match, expected rows: " << rows
915 << ", received: " << input1Matrix.rows();
916 cmnThrow(std::runtime_error(message.str()));
917 } else if ((cols != input2Matrix.cols())
918 || (input1Cols != input2Matrix.rows())) {
919 std::stringstream message;
920 message << "vctDynamicMatrixLoopEngines: Sizes of matrices don't match, expected: ["
921 << input1Cols << " " << cols << "], received: " << input2Matrix.sizes();
922 cmnThrow(std::runtime_error(message.str()));
923 }
924
925 // Otherwise
926 const stride_type outputColStride = outputMatrix.col_stride();
927 const stride_type outputRowStride = outputMatrix.row_stride();
928 const stride_type outputStrideToNextRow = outputRowStride - cols * outputColStride;
929
930 const stride_type input1ColStride = input1Matrix.col_stride();
931 const stride_type input1RowStride = input1Matrix.row_stride();
932
933 const stride_type input2ColStride = input2Matrix.col_stride();
934 const stride_type input2RowStride = input2Matrix.row_stride();
935
936 OutputPointerType outputPointer = outputMatrix.Pointer();
937 const OutputPointerType outputRowEnd = outputPointer + rows * outputRowStride;
938 OutputPointerType outputColEnd = outputPointer + cols * outputColStride;
939
940 Input1PointerType input1Pointer = input1Matrix.Pointer();
941 Input2PointerType input2Pointer = input2Matrix.Pointer();
942
943 typename Input1MatrixType::ConstRowRefType input1Row;
944 typename Input2MatrixType::ConstColumnRefType input2Col;
945
946 if ((outputPointer == input1Pointer) ||
947 (outputPointer == input2Pointer)) {
949 }
950
951 for (; outputPointer != outputRowEnd;
952 outputPointer += outputStrideToNextRow,
953 input1Pointer += input1RowStride,
954 input2Pointer = input2Matrix.Pointer(),
955 outputColEnd += outputRowStride)
956 {
957 input1Row.SetRef(input1Cols, input1Pointer, input1ColStride);
958 for (; outputPointer != outputColEnd;
959 outputPointer += outputColStride,
960 input2Pointer += input2ColStride)
961 {
962 input2Col.SetRef(input1Cols, input2Pointer, input2RowStride);
963 *outputPointer = _operationType::Operate(input1Row, input2Col);
964 }
965 }
966 } // Run method
967 }; // Product class
968
969
975 {
976 public:
977 template<class _inputMatrixType>
978 static void Run(const _inputMatrixType & inputMatrix,
979 typename _inputMatrixType::value_type & minValue, typename _inputMatrixType::value_type & maxValue)
980 {
981 typedef _inputMatrixType InputMatrixType;
982 typedef typename InputMatrixType::OwnerType InputOwnerType;
983 typedef typename InputOwnerType::size_type size_type;
984 typedef typename InputOwnerType::stride_type stride_type;
985 typedef typename InputOwnerType::const_pointer InputPointerType;
986 typedef typename InputOwnerType::value_type value_type;
987
988 // retrieve owner
989 const InputOwnerType & inputOwner = inputMatrix.Owner();
990 InputPointerType inputPointer = inputOwner.Pointer();
991
992 if (inputPointer == 0)
993 return;
994
995 if (inputOwner.IsCompact()) {
996 vctDynamicCompactLoopEngines::MinAndMax::Run(inputOwner, minValue, maxValue);
997 } else {
998 // otherwise
999 const size_type rows = inputOwner.rows();
1000 const size_type cols = inputOwner.cols();
1001
1002 const stride_type inputColStride = inputOwner.col_stride();
1003 const stride_type inputRowStride = inputOwner.row_stride();
1004 const stride_type inputStrideToNextRow = inputRowStride - cols * inputColStride;
1005 const InputPointerType inputRowEnd = inputPointer + rows * inputRowStride;
1006 InputPointerType inputColEnd = inputPointer + cols * inputColStride;
1007
1008 value_type minElement, maxElement;
1009 maxElement = minElement = *inputPointer;
1010
1011 for (;
1012 inputPointer != inputRowEnd;
1013 inputPointer += inputStrideToNextRow, inputColEnd += inputRowStride) {
1014 for (;
1015 inputPointer != inputColEnd;
1016 inputPointer += inputColStride) {
1017 const value_type element = *inputPointer;
1018 if (element < minElement) {
1019 minElement = element;
1020 } else if (maxElement < element) {
1021 maxElement = element;
1022 }
1023 }
1024 }
1025 minValue = minElement;
1026 maxValue = maxElement;
1027 }
1028 } // Run method
1029 }; // MinAndMax class
1030
1031
1033 {
1034 public:
1035 template<class _outputMatrixType, class _inputMatrixType, class _indexVectorType>
1036 static void Run(_outputMatrixType & outputMatrix, const _inputMatrixType & inputMatrix,
1037 const _indexVectorType & indexVector)
1038 {
1039 typedef _outputMatrixType OutputMatrixType;
1040 // check sizes
1041 typedef _outputMatrixType OutputMatrixType;
1042 typedef typename OutputMatrixType::size_type size_type;
1043 typedef typename OutputMatrixType::stride_type stride_type;
1044 typedef typename OutputMatrixType::pointer OutputPointerType;
1045
1046 typedef _inputMatrixType InputMatrixType;
1047 typedef typename InputMatrixType::const_pointer InputPointerType;
1048 typedef _indexVectorType IndexVectorType;
1049 typedef typename IndexVectorType::const_pointer IndexPointerType;
1050
1051 const size_type rows = outputMatrix.rows();
1052 const size_type cols = outputMatrix.cols();
1053 if (cols != inputMatrix.cols()) {
1054 std::stringstream message;
1055 message << "vctDynamicMatrixLoopEngines::SelectRowsByIndex: Sizes of matrices don't match, expected cols: "
1056 << cols << ", received: " << inputMatrix.cols();
1057 cmnThrow(std::runtime_error(message.str()));
1058 } else if (rows != indexVector.size()) {
1059 std::stringstream message;
1060 message << "vctDynamicMatrixLoopEngines::SelectRowsByIndex: Sizes of matrices don't match, expected rows: "
1061 << rows << ", received: " << indexVector.size();
1062 cmnThrow(std::runtime_error(message.str()));
1063 }
1064
1065 // otherwise
1066 const stride_type outputColStride = outputMatrix.col_stride();
1067 const stride_type outputRowStride = outputMatrix.row_stride();
1068 const stride_type outputStrideToNextRow = outputRowStride - cols * outputColStride;
1069
1070 const stride_type inputColStride = inputMatrix.col_stride();
1071 const stride_type indexStride = indexVector.stride();
1072
1073 OutputPointerType outputPointer = outputMatrix.Pointer();
1074 const OutputPointerType outputRowEnd = outputPointer + rows * outputRowStride;
1075 OutputPointerType outputColEnd = outputPointer + cols * outputColStride;
1076
1077 InputPointerType inputPointer;
1078 IndexPointerType indexPointer = indexVector.Pointer();
1079
1080 for (; outputPointer != outputRowEnd;
1081 outputPointer += outputStrideToNextRow,
1082 indexPointer += indexStride,
1083 outputColEnd += outputRowStride)
1084 {
1085 inputPointer = inputMatrix.Pointer(*indexPointer, 0);
1086 for (; outputPointer != outputColEnd;
1087 outputPointer += outputColStride,
1088 inputPointer += inputColStride)
1089 {
1090 *outputPointer = *inputPointer;
1091 }
1092 }
1093
1094 }
1095 };
1096
1097
1098};
1099
1100
1101#endif // _vctDynamicMatrixLoopEngines_h
static void Run(_ioOwnerType &ioOwner, const _input1OwnerType &input1Owner, const _input2OwnerType &input2Owner)
Definition vctDynamicCompactLoopEngines.h:549
static void Run(_inputOutputOwnerType &inputOutputOwner, const _inputOwnerType &inputOwner)
Definition vctDynamicCompactLoopEngines.h:121
static void Run(_inputOutputOwnerType &inputOutputOwner)
Definition vctDynamicCompactLoopEngines.h:367
static void Run(_ioOwnerType &ioOwner, const _inputScalarType inputScalar, const _inputOwnerType &inputOwner)
Definition vctDynamicCompactLoopEngines.h:500
static void Run(_inputOutputOwnerType &inputOutputOwner, const _inputScalarType inputScalar)
Definition vctDynamicCompactLoopEngines.h:289
static void Run(_outputOwnerType &outputOwner, const _input1OwnerType &input1Owner, const _input2OwnerType &input2Owner)
Definition vctDynamicCompactLoopEngines.h:75
static void Run(_outputOwnerType &outputOwner, const _inputOwnerType &inputOwner)
Definition vctDynamicCompactLoopEngines.h:325
static void Run(_outputOwnerType &outputOwner, const _inputOwnerType &inputOwner, const _inputScalarType inputScalar)
Definition vctDynamicCompactLoopEngines.h:204
static void Run(_outputOwnerType &outputOwner, const _inputScalarType inputScalar, const _inputOwnerType &inputOwner)
Definition vctDynamicCompactLoopEngines.h:246
static void Run(const _inputOwnerType &inputOwner, typename _inputOwnerType::value_type &minValue, typename _inputOwnerType::value_type &maxValue)
Definition vctDynamicCompactLoopEngines.h:630
static OutputType Run(const _input1OwnerType &input1Owner, const _input2OwnerType &input2Owner)
Definition vctDynamicCompactLoopEngines.h:450
Implement operation of the form for compact containers.
Definition vctDynamicCompactLoopEngines.h:401
static OutputType Run(const _inputOwnerType &inputOwner, const _inputScalarType &inputScalar)
Definition vctDynamicCompactLoopEngines.h:603
Definition vctDynamicMatrixLoopEngines.h:975
static void Run(const _inputMatrixType &inputMatrix, typename _inputMatrixType::value_type &minValue, typename _inputMatrixType::value_type &maxValue)
Definition vctDynamicMatrixLoopEngines.h:978
Definition vctDynamicMatrixLoopEngines.h:237
static void Run(_inputOutputMatrixType &inputOutputMatrix)
Definition vctDynamicMatrixLoopEngines.h:240
Definition vctDynamicMatrixLoopEngines.h:281
static void Run(_inputOutputMatrixType &inputOutputMatrix, const _inputMatrixType &inputMatrix)
Definition vctDynamicMatrixLoopEngines.h:284
Implement operation of the form for fixed size matrices.
Definition vctDynamicMatrixLoopEngines.h:752
static void Run(_ioMatrixType &ioMatrix, const _input1MatrixType &input1Matrix, const _input2MatrixType &input2Matrix)
Definition vctDynamicMatrixLoopEngines.h:756
Definition vctDynamicMatrixLoopEngines.h:474
static void Run(_inputOutputMatrixType &inputOutputMatrix, const _inputScalarType inputScalar)
Definition vctDynamicMatrixLoopEngines.h:477
Implement operation of the form for fixed size matrices.
Definition vctDynamicMatrixLoopEngines.h:661
static void Run(_ioMatrixType &ioMatrix, const _inputScalarType &inputScalar, const _inputMatrixType &inputMatrix)
Definition vctDynamicMatrixLoopEngines.h:665
Definition vctDynamicMatrixLoopEngines.h:173
static void Run(_outputMatrixType &outputMatrix, const _inputMatrixType &inputMatrix)
Definition vctDynamicMatrixLoopEngines.h:176
Definition vctDynamicMatrixLoopEngines.h:92
static void Run(_outputMatrixType &outputMatrix, const _input1MatrixType &input1Matrix, const _input2MatrixType &input2Matrix)
Definition vctDynamicMatrixLoopEngines.h:95
Definition vctDynamicMatrixLoopEngines.h:344
static void Run(_outputMatrixType &outputMatrix, const _inputMatrixType &inputMatrix, const _inputScalarType inputScalar)
Definition vctDynamicMatrixLoopEngines.h:347
Definition vctDynamicMatrixLoopEngines.h:409
static void Run(_outputMatrixType &outputMatrix, const _inputScalarType inputScalar, const _inputMatrixType &inputMatrix)
Definition vctDynamicMatrixLoopEngines.h:412
Definition vctDynamicMatrixLoopEngines.h:890
static void Run(_outputMatrixType &outputMatrix, const _input1MatrixType &input1Matrix, const _input2MatrixType &input2Matrix)
Definition vctDynamicMatrixLoopEngines.h:893
Definition vctDynamicMatrixLoopEngines.h:1033
static void Run(_outputMatrixType &outputMatrix, const _inputMatrixType &inputMatrix, const _indexVectorType &indexVector)
Definition vctDynamicMatrixLoopEngines.h:1036
Definition vctDynamicMatrixLoopEngines.h:518
_incrementalOperationType::OutputType OutputType
Definition vctDynamicMatrixLoopEngines.h:520
static OutputType Run(const _inputMatrixType &inputMatrix)
Definition vctDynamicMatrixLoopEngines.h:523
Definition vctDynamicMatrixLoopEngines.h:567
static OutputType Run(const _input1MatrixType &input1Matrix, const _input2MatrixType &input2Matrix)
Definition vctDynamicMatrixLoopEngines.h:572
_incrementalOperationType::OutputType OutputType
Definition vctDynamicMatrixLoopEngines.h:569
Definition vctDynamicMatrixLoopEngines.h:837
_incrementalOperationType::OutputType OutputType
Definition vctDynamicMatrixLoopEngines.h:839
static OutputType Run(const _inputMatrixType &inputMatrix, const _inputScalarType &inputScalar)
Definition vctDynamicMatrixLoopEngines.h:842
Container class for the dynamic matrix engines.
Definition vctDynamicMatrixLoopEngines.h:37
static void ThrowSizeMismatchException(const _nsize_type &expected, const _nsize_type &received) CISST_THROW(std
Definition vctDynamicMatrixLoopEngines.h:44
static void ThrowSharedPointersException(void) CISST_THROW(std
Definition vctDynamicMatrixLoopEngines.h:55
Portability across compilers and operating systems tools.
#define CISST_THROW(exceptionParameter)
Somewhat portable compilation warning message. This works with very recent versions of gcc (4....
Definition cmnPortability.h:559
Declaration of the template function cmnThrow.
void cmnThrow(const _exceptionType &except, cmnLogLevel lod=CMN_LOG_LEVEL_INIT_ERROR)
Definition cmnThrow.h:76
Declaration of vctDynamicCompactLoopEngines.
size_type cols() const
Definition vctDynamicConstMatrixBase.h:243
size_type rows() const
Definition vctDynamicConstMatrixBase.h:238