NEST main@caf0ae8
 
Loading...
Searching...
No Matches
position.h
Go to the documentation of this file.
1/*
2 * position.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef POSITION_H
24#define POSITION_H
25
26// C++ includes:
27#include <algorithm>
28#include <array>
29#include <cassert>
30#include <cmath>
31#include <iostream>
32#include <sstream>
33#include <string>
34#include <utility>
35#include <vector>
36
37// Includes from libnestutil:
38#include "compose.hpp"
39
40// Includes from nestkernel:
41#include "exceptions.h"
42#include "nest_types.h"
43
44namespace nest
45{
46
47// It is necessary to declare the template for operator<< first in order
48// to get the friend declaration to work
49template < int D, class T >
50class Position;
51
52template < int D, class T >
53std::ostream& operator<<( std::ostream& os, const Position< D, T >& pos );
54
55template < int D, class T = double >
57{
58public:
59 template < int OD, class OT >
60 friend class Position;
61
66
70 Position( const T&, const T& );
71
75 Position( const T&, const T&, const T& );
76
80 Position( const T* const y );
81
85 Position( const std::vector< T >& y );
86
87 Position( const Position& other );
88
89 template < class U >
90 Position( const Position< D, U >& other );
91
95 Position( Position&& other );
96
100 Position& operator=( const Position& other ) = default;
101 Position& operator=( const std::vector< T >& y );
102
106 Position& operator=( Position&& other ) = default;
107
111 T& operator[]( int i );
112
116 const T& operator[]( int i ) const;
117
118 const std::vector< T > get_vector() const;
119 void get_vector( std::vector< T >& vector ) const;
120
126 template < class OT >
127 Position operator+( const Position< D, OT >& other ) const;
128
134 template < class OT >
135 Position operator-( const Position< D, OT >& other ) const;
136
143
149 template < class OT >
150 Position operator*( const Position< D, OT >& other ) const;
151
157 template < class OT >
158 Position operator/( const Position< D, OT >& other ) const;
159
165 Position operator+( const T& ) const;
166
172 Position operator-( const T& ) const;
173
179 Position operator*( const T& ) const;
180
186 Position operator/( const T& ) const;
187
194 template < class OT >
196
203 template < class OT >
205
212 template < class OT >
214
221 template < class OT >
223
229 Position& operator+=( const T& );
230
237 Position& operator-=( const T& );
238
244 Position& operator*=( const T& );
245
251 Position& operator/=( const T& );
252
256 bool operator==( const Position& y ) const;
257
261 bool operator!=( const Position& y ) const;
262
266 bool operator<( const Position& y ) const;
267
271 bool operator>( const Position& y ) const;
272
276 bool operator<=( const Position& y ) const;
277
281 bool operator>=( const Position& y ) const;
282
288 T length() const;
289
293 operator std::string() const;
294
304 void print( std::ostream& out, char sep = ' ' ) const;
305
309 friend std::ostream& operator<< <>( std::ostream& os, const Position< D, T >& pos );
310
311protected:
312 std::array< T, D > x_;
313};
314
319template < int D >
334
338template < int D >
339class MultiIndex : public Position< D, int >
340{
341public:
343 : Position< D, int >()
344 , lower_left_()
345 , upper_right_()
346 {
347 }
348
349 explicit MultiIndex( const Position< D, int >& ur )
350 : Position< D, int >()
351 , lower_left_()
352 , upper_right_( ur )
353 {
354 }
355
356 MultiIndex( const Position< D, int >& lower_left, const Position< D, int >& upper_right )
357 : Position< D, int >( lower_left )
358 , lower_left_( lower_left )
359 , upper_right_( upper_right )
360 {
361 }
362
365 {
366 // Try increasing the first coordinate first, resetting it and
367 // continuing with the next if the first one overflows, and so on
368 for ( int i = 0; i < D; ++i )
369 {
370 this->x_[ i ]++;
371 if ( this->x_[ i ] < upper_right_[ i ] )
372 {
373 return *this;
374 }
375 this->x_[ i ] = lower_left_[ i ];
376 }
377 // If we reach this point, we are outside of bounds. The upper
378 // right point is used as a marker to show that we have reached the end.
379 for ( int i = 0; i < D; ++i )
380 {
381 this->x_[ i ] = upper_right_[ i ];
382 }
383 return *this;
384 }
385
388 {
389 MultiIndex tmp = *this;
390 ++*this;
391 return tmp;
392 }
393
396 {
397 return lower_left_;
398 }
401 {
402 return upper_right_;
403 }
404
405private:
408};
409
410
411template < int D, class T >
413{
414 x_.fill( 0 );
415}
416
417template < int D, class T >
418inline Position< D, T >::Position( const T& x, const T& y )
419{
420 assert( D == 2 );
421 x_[ 0 ] = x;
422 x_[ 1 ] = y;
423}
424
425template < int D, class T >
426inline Position< D, T >::Position( const T& x, const T& y, const T& z )
427{
428 assert( D == 3 );
429 x_[ 0 ] = x;
430 x_[ 1 ] = y;
431 x_[ 2 ] = z;
432}
433
434template < int D, class T >
435inline Position< D, T >::Position( const T* const y )
436{
437 for ( int i = 0; i < D; ++i )
438 {
439 x_[ i ] = y[ i ];
440 }
441}
442
443template < int D, class T >
444inline Position< D, T >::Position( const std::vector< T >& y )
445{
446 if ( y.size() != D )
447 {
448 throw BadProperty( String::compose( "Expected a %1-dimensional position.", D ) );
449 }
450 std::copy( y.begin(), y.end(), x_.begin() );
451}
452
453template < int D, class T >
455 : x_( other.x_ )
456{
457}
458
459template < int D, class T >
460template < class U >
462 : x_( other.x_ )
463{
464}
465
466template < int D, class T >
468{
469 x_ = std::move( other.x_ );
470}
471
472template < int D, class T >
473inline Position< D, T >&
474Position< D, T >::operator=( const std::vector< T >& y )
475{
476 if ( y.size() != D )
477 {
478 throw BadProperty( String::compose( "Expected a %1-dimensional position.", D ) );
479 }
480 std::copy( y.begin(), y.end(), x_.begin() );
481
482 return *this;
483}
484
485template < int D, class T >
486inline T&
488{
489 return x_[ i ];
490}
491
492template < int D, class T >
493inline const T&
495{
496 return x_[ i ];
497}
498
499template < int D, class T >
500const std::vector< T >
502{
503 return std::vector< T >( x_.begin(), x_.end() ); // should be efficient due to RVO
504}
505
506template < int D, class T >
507void
508Position< D, T >::get_vector( std::vector< T >& vector ) const
509{
510 assert( vector.size() == D );
511 std::copy( x_.begin(), x_.end(), vector.begin() );
512}
513
514
515template < int D, class T >
516template < class OT >
517inline Position< D, T >
519{
520 Position p = *this;
521 p += other;
522 return p;
523}
524
525template < int D, class T >
526template < class OT >
527inline Position< D, T >
529{
530 Position p = *this;
531 p -= other;
532 return p;
533}
534
535template < int D, class T >
536inline Position< D, T >
538{
539 Position p;
540 p -= *this;
541 return p;
542}
543
544template < int D, class T >
545template < class OT >
546inline Position< D, T >
548{
549 Position p = *this;
550 p *= other;
551 return p;
552}
553
554template < int D, class T >
555template < class OT >
556inline Position< D, T >
558{
559 Position p = *this;
560 p /= other;
561 return p;
562}
563
564template < int D, class T >
565inline Position< D, T >
567{
568 Position p = *this;
569 p += a;
570 return p;
571}
572
573template < int D, class T >
574inline Position< D, T >
576{
577 Position p = *this;
578 p -= a;
579 return p;
580}
581
582template < int D, class T >
583inline Position< D, T >
585{
586 Position p = *this;
587 p *= a;
588 return p;
589}
590
591template < int D, class T >
592inline Position< D, T >
594{
595 Position p = *this;
596 p /= a;
597 return p;
598}
599
600template < int D, class T >
601template < class OT >
602inline Position< D, T >&
604{
605 for ( int i = 0; i < D; ++i )
606 {
607 x_[ i ] += other.x_[ i ];
608 }
609 return *this;
610}
611
612template < int D, class T >
613template < class OT >
614inline Position< D, T >&
616{
617 for ( int i = 0; i < D; ++i )
618 {
619 x_[ i ] -= other.x_[ i ];
620 }
621 return *this;
622}
623
624template < int D, class T >
625template < class OT >
626inline Position< D, T >&
628{
629 for ( int i = 0; i < D; ++i )
630 {
631 x_[ i ] *= other.x_[ i ];
632 }
633 return *this;
634}
635
636template < int D, class T >
637template < class OT >
638inline Position< D, T >&
640{
641 for ( int i = 0; i < D; ++i )
642 {
643 x_[ i ] /= other.x_[ i ];
644 }
645 return *this;
646}
647
648template < int D, class T >
649inline Position< D, T >&
651{
652 for ( int i = 0; i < D; ++i )
653 {
654 x_[ i ] += a;
655 }
656 return *this;
657}
658
659template < int D, class T >
660inline Position< D, T >&
662{
663 for ( int i = 0; i < D; ++i )
664 {
665 x_[ i ] -= a;
666 }
667 return *this;
668}
669
670template < int D, class T >
671inline Position< D, T >&
673{
674 for ( int i = 0; i < D; ++i )
675 {
676 x_[ i ] *= a;
677 }
678 return *this;
679}
680
681template < int D, class T >
682inline Position< D, T >&
684{
685 for ( int i = 0; i < D; ++i )
686 {
687 x_[ i ] /= a;
688 }
689 return *this;
690}
691
692template < int D, class T >
693inline bool
695{
696 for ( int i = 0; i < D; ++i )
697 {
698 if ( x_[ i ] != y.x_[ i ] )
699 {
700 return false;
701 }
702 }
703 return true;
704}
705
706template < int D, class T >
707inline bool
709{
710 for ( int i = 0; i < D; ++i )
711 {
712 if ( x_[ i ] != y.x_[ i ] )
713 {
714 return true;
715 }
716 }
717 return false;
718}
719
720template < int D, class T >
721inline bool
723{
724 for ( int i = 0; i < D; ++i )
725 {
726 if ( x_[ i ] >= y.x_[ i ] )
727 {
728 return false;
729 }
730 }
731 return true;
732}
733
734template < int D, class T >
735inline bool
737{
738 for ( int i = 0; i < D; ++i )
739 {
740 if ( x_[ i ] <= y.x_[ i ] )
741 {
742 return false;
743 }
744 }
745 return true;
746}
747
748template < int D, class T >
749inline bool
751{
752 for ( int i = 0; i < D; ++i )
753 {
754 if ( x_[ i ] > y.x_[ i ] )
755 {
756 return false;
757 }
758 }
759 return true;
760}
761
762template < int D, class T >
763inline bool
765{
766 for ( int i = 0; i < D; ++i )
767 {
768 if ( x_[ i ] < y.x_[ i ] )
769 {
770 return false;
771 }
772 }
773 return true;
774}
775
776template < int D, class T >
777T
779{
780 T lensq = 0;
781 for ( int i = 0; i < D; ++i )
782 {
783 lensq += x_[ i ] * x_[ i ];
784 }
785 return std::sqrt( lensq );
786}
787
788template < int D, class T >
790operator std::string() const
791{
792 std::stringstream ss;
793 ss << *this;
794 return ss.str();
795}
796
797template < int D, class T >
798void
799Position< D, T >::print( std::ostream& out, char sep ) const
800{
801 out << x_[ 0 ];
802 for ( int i = 1; i < D; ++i )
803 {
804 out << sep << x_[ i ];
805 }
806}
807
808template < int D, class T >
809std::ostream&
810operator<<( std::ostream& os, const Position< D, T >& pos )
811{
812 os << "(";
813 if ( D > 0 )
814 {
815 os << pos.x_[ 0 ];
816 }
817 for ( int i = 1; i < D; ++i )
818 {
819 os << ", " << pos.x_[ i ];
820 }
821 os << ")";
822 return os;
823}
824
825} // namespace nest
826
827#endif
Exception to be thrown if a status parameter is incomplete or inconsistent.
Definition exceptions.h:680
An index into a multidimensional array.
Definition position.h:340
MultiIndex(const Position< D, int > &ur)
Definition position.h:349
Position< D, int > lower_left_
Definition position.h:406
Position< D, int > get_lower_left() const
Definition position.h:395
MultiIndex()
Definition position.h:342
Position< D, int > upper_right_
Definition position.h:407
Position< D, int > get_upper_right() const
Definition position.h:400
MultiIndex(const Position< D, int > &lower_left, const Position< D, int > &upper_right)
Definition position.h:356
MultiIndex & operator++()
Definition position.h:364
MultiIndex operator++(int)
Definition position.h:387
Definition position.h:57
void print(std::ostream &out, char sep=' ') const
Print position to output stream.
Definition position.h:799
Position operator-() const
Unary minus.
Definition position.h:537
Position operator+(const T &) const
Elementwise addition with scalar.
Definition position.h:566
void get_vector(std::vector< T > &vector) const
Definition position.h:508
bool operator<=(const Position &y) const
Definition position.h:750
friend class Position
Definition position.h:60
Position()
Default constructor, initializing all coordinates to zero.
Definition position.h:412
Position & operator=(const std::vector< T > &y)
Definition position.h:474
Position & operator+=(const Position< D, OT > &)
In-place elementwise addition.
Position(const T *const y)
Constructor initializing a Position from an array.
Definition position.h:435
Position & operator/=(const Position< D, OT > &)
In-place elementwise division.
T & operator[](int i)
Definition position.h:487
Position(Position &&other)
Move constructor.
Definition position.h:467
Position & operator*=(const T &)
In-place multiplication by scalar.
Definition position.h:672
Position(const T &, const T &, const T &)
3D Constructor.
Definition position.h:426
T length() const
Length of Position vector.
Definition position.h:778
Position(const T &, const T &)
2D Constructor.
Definition position.h:418
Position(const Position &other)
Definition position.h:454
const std::vector< T > get_vector() const
Definition position.h:501
Position operator/(const Position< D, OT > &other) const
Elementwise division.
bool operator<(const Position &y) const
Definition position.h:722
bool operator!=(const Position &y) const
Definition position.h:708
Position operator/(const T &) const
Division with scalar.
Definition position.h:593
bool operator>=(const Position &y) const
Definition position.h:764
Position(const Position< D, U > &other)
Definition position.h:461
Position operator+(const Position< D, OT > &other) const
Elementwise addition.
Position operator-(const Position< D, OT > &other) const
Elementwise subtraction.
Position & operator-=(const Position< D, OT > &)
In-place elementwise subtraction.
Position & operator=(Position &&other)=default
Move assignment constructor.
Position & operator-=(const T &)
In-place elementwise subtraction with scalar.
Definition position.h:661
std::array< T, D > x_
Definition position.h:312
Position(const std::vector< T > &y)
Constructor initializing a Position from a std::vector.
Definition position.h:444
Position operator-(const T &) const
Elementwise subtraction with scalar.
Definition position.h:575
Position & operator=(const Position &other)=default
Assignment constructor.
Position operator*(const Position< D, OT > &other) const
Elementwise multiplication.
Position & operator/=(const T &)
In-place elementwise division.
Definition position.h:683
Position & operator+=(const T &)
In-place elementwise addition with scalar.
Definition position.h:650
bool operator>(const Position &y) const
Definition position.h:736
Position & operator*=(const Position< D, OT > &)
In-place elementwise multiplication.
Position operator*(const T &) const
Multiplication with scalar.
Definition position.h:584
const T & operator[](int i) const
Definition position.h:494
bool operator==(const Position &y) const
Definition position.h:694
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
std::ostream & operator<<(std::ostream &out, const LoggingEvent &e)
Definition logging_event.cpp:58
A box is defined by the lower left corner (minimum coordinates) and the upper right corner (maximum c...
Definition position.h:321
Position< D > lower_left
Definition position.h:331
Box()
Definition position.h:322
Position< D > upper_right
Definition position.h:332
Box(const Position< D > &lower_left, const Position< D > &upper_right)
Definition position.h:325