NEST main@caf0ae8
 
Loading...
Searching...
No Matches
grid_layer.h
Go to the documentation of this file.
1/*
2 * grid_layer.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 GRID_LAYER_H
24#define GRID_LAYER_H
25
26// Includes from spatial:
27#include "layer.h"
28
29// Includes from C++
30#include <iterator>
31
32namespace nest
33{
34
38template < int D >
39class GridLayer : public Layer< D >
40{
41public:
43 typedef size_t mapped_type;
44 typedef std::pair< Position< D >, size_t > value_type;
47
52 {
53 public:
58 : layer_( layer )
59 , node_()
60 , mask_()
61 , layer_size_()
62 {
63 }
64
68 masked_iterator( const GridLayer< D >& layer, const Mask< D >& mask, const Position< D >& anchor );
69
71
77
83 {
84 masked_iterator tmp = *this;
85 ++*this;
86 return tmp;
87 }
88
92 bool
93 operator==( const masked_iterator& other ) const
94 {
95 return ( other.layer_.get_metadata() == layer_.get_metadata() ) and ( other.node_ == node_ );
96 }
97 bool
98 operator!=( const masked_iterator& other ) const
99 {
100 return ( other.layer_.get_metadata() != layer_.get_metadata() ) or ( other.node_ != node_ );
101 }
102
103 protected:
109 };
110
112 : Layer< D >()
113 {
114 }
115
116 GridLayer( const GridLayer& layer )
117 : Layer< D >( layer )
118 , dims_( layer.dims_ )
119 {
120 }
121
128 Position< D > get_position( size_t sind ) const override;
129
136 Position< D > lid_to_position( size_t lid ) const;
137
138 size_t gridpos_to_lid( Position< D, int > pos ) const;
139
141
143
144 std::vector< std::pair< Position< D >, size_t > > get_global_positions_vector( const AbstractMask& mask,
145 const Position< D >& anchor,
146 bool allow_oversized,
147 NodeCollectionPTR node_collection );
148
149 masked_iterator masked_begin( const Mask< D >& mask, const Position< D >& anchor );
150 masked_iterator masked_end();
151
153
154 void set_status( const Dictionary& d ) override;
155 void get_status( Dictionary& d, NodeCollection const* const ) const override;
156
157protected:
159
160 template < class Ins >
161 void insert_global_positions_( Ins iter, NodeCollectionPTR node_collection );
162 void insert_global_positions_ntree_( Ntree< D, size_t >& tree, NodeCollectionPTR node_collection ) override;
163 void insert_global_positions_vector_( std::vector< std::pair< Position< D >, size_t > >& vec,
164 NodeCollectionPTR node_collection ) override;
165};
166
167template < int D >
170{
171 return dims_;
172}
173
174template < int D >
175void
177{
178 std::vector< long > new_dims( D );
179
180 d.update_value( names::shape, new_dims );
181
182 size_t new_size = 1;
183 for ( int i = 0; i < D; ++i )
184 {
185 new_size *= new_dims[ i ];
186
187 this->dims_[ i ] = static_cast< size_t >( new_dims[ i ] );
188 }
189
190 if ( new_size != this->node_collection_->size() )
191 {
192 throw BadProperty( "Total size of layer must be unchanged." );
193 }
194
195 if ( d.known( names::extent ) )
196 {
197 Position< D > center = this->get_center();
198 this->extent_ = d.get< std::vector< double > >( names::extent );
199 this->lower_left_ = center - this->extent_ / 2;
200 }
201 if ( d.known( names::center ) )
202 {
203 this->lower_left_ = d.get< std::vector< double > >( names::center );
204 this->lower_left_ -= this->extent_ / 2;
205 }
206
208}
209
210template < int D >
211void
213{
214 Layer< D >::get_status( d, nc );
215
216 const auto dv = dims_.get_vector();
217 d[ names::shape ] = std::vector< long >( dv.begin(), dv.end() );
218}
219
220template < int D >
223{
224 Position< D, int > gridpos;
225 for ( int i = D - 1; i > 0; --i )
226 {
227 gridpos[ i ] = lid % dims_[ i ];
228 lid = lid / dims_[ i ];
229 }
230 assert( lid < dims_[ 0 ] );
231 gridpos[ 0 ] = lid;
232 return gridpos_to_position( gridpos );
233}
234
235template < int D >
238{
239 // grid layer uses "matrix convention", i.e. reversed y axis
240 Position< D > ext = this->extent_;
241 Position< D > upper_left = this->lower_left_;
242 if ( D > 1 )
243 {
244 upper_left[ 1 ] += ext[ 1 ];
245 ext[ 1 ] = -ext[ 1 ];
246 }
247 return upper_left + ext / dims_ * gridpos + ext / dims_ * 0.5;
248}
249
250template < int D >
253{
254 return lid_to_position( lid );
255}
256
257template < int D >
258size_t
260{
261 size_t lid = 0;
262
263 // In case of periodic boundaries, allow grid positions outside layer
264 for ( int i = 0; i < D; ++i )
265 {
266 if ( this->periodic_[ i ] )
267 {
268 pos[ i ] %= int( dims_[ i ] );
269 if ( pos[ i ] < 0 )
270 {
271 pos[ i ] += dims_[ i ];
272 }
273 }
274 }
275
276 for ( int i = 0; i < D; ++i )
277 {
278 lid *= dims_[ i ];
279 lid += pos[ i ];
280 }
281
282 return lid;
283}
284
285template < int D >
286template < class Ins >
287void
289{
290 for ( auto gi = node_collection->begin(); gi < node_collection->end(); ++gi )
291 {
292 const auto triple = *gi;
293 *iter++ = std::pair< Position< D >, size_t >( lid_to_position( triple.nc_index ), triple.node_id );
294 }
295}
296
297template < int D >
298void
300{
301 auto ins2 = std::back_inserter( tree );
302 insert_global_positions_( ins2, node_collection );
303}
304
305
306template < int D >
307void
308GridLayer< D >::insert_global_positions_vector_( std::vector< std::pair< Position< D >, size_t > >& vec,
309 NodeCollectionPTR node_collection )
310{
311 insert_global_positions_( std::back_inserter( vec ), node_collection );
312}
313
314template < int D >
317{
318 return masked_iterator( *this, mask, anchor );
319}
320
321template < int D >
324{
325 return masked_iterator( *this );
326}
327
328template < int D >
330 const Mask< D >& mask,
331 const Position< D >& anchor )
332 : layer_( layer )
333 , mask_( &mask )
334 , anchor_( anchor )
335{
336 layer_size_ = layer.global_size();
337
338 Position< D, int > lower_left;
339 Position< D, int > upper_right;
340 Box< D > bbox = mask.get_bbox();
341 bbox.lower_left += anchor;
342 bbox.upper_right += anchor;
343 for ( int i = 0; i < D; ++i )
344 {
345 if ( layer.periodic_[ i ] )
346 {
347 lower_left[ i ] =
348 ceil( ( bbox.lower_left[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] - 0.5 );
349 upper_right[ i ] =
350 round( ( bbox.upper_right[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] );
351 }
352 else
353 {
354 lower_left[ i ] = std::min(
355 size_t( std::max(
356 ceil( ( bbox.lower_left[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] - 0.5 ),
357 0.0 ) ),
358 layer.dims_[ i ] );
359 upper_right[ i ] = std::min(
360 size_t( std::max(
361 round( ( bbox.upper_right[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] ), 0.0 ) ),
362 layer.dims_[ i ] );
363 }
364 }
365 if ( D > 1 )
366 {
367 // grid layer uses "matrix convention", i.e. reversed y axis
368 int tmp = lower_left[ 1 ];
369 lower_left[ 1 ] = layer.dims_[ 1 ] - upper_right[ 1 ];
370 upper_right[ 1 ] = layer.dims_[ 1 ] - tmp;
371 }
372
373 node_ = MultiIndex< D >( lower_left, upper_right );
374
375 if ( not mask_->inside( layer_.gridpos_to_position( node_ ) - anchor_ ) )
376 {
377 ++( *this );
378 }
379}
380
381template < int D >
382inline std::pair< Position< D >, size_t >
384{
385 return std::pair< Position< D >, size_t >(
386 layer_.gridpos_to_position( node_ ), layer_.node_collection_->operator[]( layer_.gridpos_to_lid( node_ ) ) );
387}
388
389template < int D >
392{
393 do
394 {
395 ++node_;
396
397 if ( node_ == node_.get_upper_right() )
398 {
399 // Mark as invalid
400 node_ = MultiIndex< D >();
401 return *this;
402 }
403
404 } while ( not mask_->inside( layer_.gridpos_to_position( node_ ) - anchor_ ) );
405
406 return *this;
407}
408
409template < int D >
410std::vector< std::pair< Position< D >, size_t > >
412 const Position< D >& anchor,
413 bool,
415{
416 std::vector< std::pair< Position< D >, size_t > > positions;
417
418 const Mask< D >& mask_d = dynamic_cast< const Mask< D >& >( mask );
419 for ( typename GridLayer< D >::masked_iterator mi = masked_begin( mask_d, anchor ); mi != masked_end(); ++mi )
420 {
421 positions.push_back( *mi );
422 }
423
424 return positions;
425}
426
427} // namespace nest
428
429#endif
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
Abstract base class for masks with unspecified dimension.
Definition mask.h:51
Exception to be thrown if a status parameter is incomplete or inconsistent.
Definition exceptions.h:680
Iterator iterating over the nodes inside a Mask.
Definition grid_layer.h:52
bool operator!=(const masked_iterator &other) const
Definition grid_layer.h:98
const Mask< D > * mask_
Definition grid_layer.h:106
int layer_size_
Definition grid_layer.h:105
value_type operator*()
Definition grid_layer.h:383
const GridLayer< D > & layer_
Definition grid_layer.h:104
masked_iterator operator++(int)
Postfix increment operator.
Definition grid_layer.h:82
MultiIndex< D > node_
Definition grid_layer.h:108
masked_iterator & operator++()
Move the iterator to the next node within the mask.
Definition grid_layer.h:391
masked_iterator(const GridLayer< D > &layer)
Constructor for an invalid iterator.
Definition grid_layer.h:57
bool operator==(const masked_iterator &other) const
Iterators are equal if they point to the same node in the same layer.
Definition grid_layer.h:93
Position< D > anchor_
Definition grid_layer.h:107
Layer with neurons placed in a grid.
Definition grid_layer.h:40
masked_iterator masked_begin(const Mask< D > &mask, const Position< D > &anchor)
Definition grid_layer.h:316
GridLayer(const GridLayer &layer)
Definition grid_layer.h:116
GridLayer()
Definition grid_layer.h:111
void insert_global_positions_(Ins iter, NodeCollectionPTR node_collection)
Definition grid_layer.h:288
void get_status(Dictionary &d, NodeCollection const *const) const override
Export properties of the layer by setting entries in the status dictionary, respects slicing of given...
Definition grid_layer.h:212
masked_iterator masked_end()
Definition grid_layer.h:323
size_t mapped_type
Definition grid_layer.h:43
std::vector< std::pair< Position< D >, size_t > > get_global_positions_vector(const AbstractMask &mask, const Position< D > &anchor, bool allow_oversized, NodeCollectionPTR node_collection)
Definition grid_layer.h:411
Position< D > lid_to_position(size_t lid) const
Get position of node.
Definition grid_layer.h:222
std::pair< Position< D >, size_t > value_type
Definition grid_layer.h:44
Position< D, size_t > get_dims() const
Definition grid_layer.h:169
Position< D > key_type
Definition grid_layer.h:42
void set_status(const Dictionary &d) override
Change properties of the layer according to the entries in the dictionary.
Definition grid_layer.h:176
void insert_global_positions_ntree_(Ntree< D, size_t > &tree, NodeCollectionPTR node_collection) override
Insert global position info into ntree.
Definition grid_layer.h:299
Position< D > gridpos_to_position(Position< D, int > gridpos) const
Definition grid_layer.h:237
Position< D > get_position(size_t sind) const override
Get position of node.
Definition grid_layer.h:252
value_type & reference
Definition grid_layer.h:45
void insert_global_positions_vector_(std::vector< std::pair< Position< D >, size_t > > &vec, NodeCollectionPTR node_collection) override
Insert global position info into vector.
Definition grid_layer.h:308
size_t gridpos_to_lid(Position< D, int > pos) const
Definition grid_layer.h:259
Position< D, size_t > dims_
number of nodes in each direction.
Definition grid_layer.h:158
const value_type & const_reference
Definition grid_layer.h:46
Abstract base class for Layer of given dimension (D=2 or 3).
Definition layer.h:218
Position< D > extent_
size of layer
Definition layer.h:440
void set_status(const Dictionary &) override
Change properties of the layer according to the entries in the dictionary.
Definition layer_impl.h:80
void get_status(Dictionary &, NodeCollection const *const) const override
Retrieve status, slice according to node collection if given.
Definition layer_impl.h:93
std::bitset< D > periodic_
periodic b.c.
Definition layer.h:441
Position< D > lower_left_
lower left corner (minimum coordinates) of layer
Definition layer.h:439
Abstract base class for masks with given dimension.
Definition mask.h:101
An index into a multidimensional array.
Definition position.h:340
Superclass for NodeCollections.
Definition node_collection.h:565
A Ntree object represents a subtree or leaf in a Ntree structure.
Definition ntree.h:55
Definition position.h:57
const std::string shape("shape")
const std::string center("center")
const std::string extent("extent")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
std::shared_ptr< NodeCollection > NodeCollectionPTR
Definition node_collection.h:50
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
Position< D > upper_right
Definition position.h:332