Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AminoAcidNeighborSparseMatrix.hh
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/pack/interaction_graph/AminoAcidNeighborSparseMatrix.hh
11 /// @brief Amino acid neighbor sparse matrix template class
12 /// @author Andrew Leaver-Fay (aleaverfay@gmail.com)
13 
14 #ifndef INCLUDED_core_pack_interaction_graph_AminoAcidNeighborSparseMatrix_hh
15 #define INCLUDED_core_pack_interaction_graph_AminoAcidNeighborSparseMatrix_hh
16 
17 // Utility headers
18 #include <utility/vector1.hh>
19 
20 // ObjexxFCL Headers
21 // AUTO-REMOVED #include <ObjexxFCL/ObjexxFCL.Project.hh>
22 #include <ObjexxFCL/FArray1.hh>
23 #include <ObjexxFCL/FArray1D.hh>
24 // AUTO-REMOVED #include <ObjexxFCL/FArray1A.hh>
25 #include <ObjexxFCL/FArray2.hh>
26 #include <ObjexxFCL/FArray2D.hh>
27 
28 // Rosetta headers
30 
31 //Auto using namespaces
32 namespace ObjexxFCL { } using namespace ObjexxFCL; // AUTO USING NS
33 //Auto using namespaces end
34 
35 
36 namespace core {
37 namespace pack {
38 namespace interaction_graph {
39 
40 // A sparse matrix for rotamer pair energies.
41 //
42 // Chris Saunders introduced the idea of reducing the rotamer pair
43 // energy table's memory usage by keeping a list for each residue pair
44 // of all their amino-acid pairs that have non-zero interaction energy.
45 // This sparse matrix did not allocate space for rotamer pairs that
46 // belonged to a pair of non-interacting-amino-acid pairs. The sparse
47 // matrix representation Chris introduced when Rosetta was in Fortran
48 // has been extracted into its own C++ class so it can be easily reused
49 // in the various InteractionGraph classes.
50 
51 template < typename T >
52 class AminoAcidNeighborSparseMatrix
53 {
54 public:
55 
56  typedef T value_type;
57 
58 
59 /// @brief Constructor. The amino acid neighbor sparse matrix stores the rotamer
60 /// pair energies for a pair of residues - or more generally - for a pair of
61 /// nodes in an interaction graph. Template type T must support:
62 /// operator <
63 /// operator =
64 /// operator +=
65 ///
66 /// The constructor requires references to the arrays holding state counts
67 /// for each amino acid type. Multiple sparse-matrices may refer to the same
68 /// state-count-per-amino acid arrays. By using proxy arrays instead of copying
69 /// the state-counts, the sparse-matrix saves memory.
70 ///
71 /// @param first_node_num_states_per_aa - [in] - reference to array with the
72 /// number of states for the first dimension for each amino acid.
73 /// @param second_node_num_states_per_aa - [in] - reference to array with
74 /// the number of states for the second dimension for each amino acid.
75  inline
77  (
78  utility::vector1< int > const & first_node_num_states_per_aa,
79  utility::vector1< int > const & second_node_num_states_per_aa
80  ) :
81  num_aa_( first_node_num_states_per_aa.size() ),
82  first_node_num_states_per_aatype_( first_node_num_states_per_aa ),
83  second_node_num_states_per_aatype_( second_node_num_states_per_aa ),
84  table_size_( 0 )
85  {}
86 
87 /// @brief Method for telling the sparse matrix which amino acid pairs to allocate
88 /// space for. The input is a 2D FArray where the first dimension
89 /// indexes over the amino-acids of the second node, and the second dimension
90 /// indexes over the amino-acids of the first node. This is somewhat iverted,
91 /// but it is the natural consequence of a column-major 2D array.
92 ///
93 /// @param sparse_conn_info - [in] - table of boolean values representing which
94 /// amino acid pairs that neighbor.
95  void
96  set_sparse_aa_info
97  (
98  FArray2_bool const & sparse_conn_info
99  )
100  {
101  aa_offsets_.dimension( num_aa_, num_aa_ );
102  aa_offsets_ = 0;
103  int next_offset = 0;
104 
105  for (int ii = 1; ii <= num_aa_; ++ii) {
106  int node1_num_states_for_aatype =
107  first_node_num_states_per_aatype_[ ii ];
108  for (int jj = 1; jj <= num_aa_; ++jj) {
109  int node2_num_states_for_aatype =
110  second_node_num_states_per_aatype_[ jj ];
111  if ( ! sparse_conn_info( jj, ii) ||
112  node1_num_states_for_aatype == 0 ||
113  node2_num_states_for_aatype == 0) {
114  aa_offsets_(jj, ii) = -1;
115  } else {
116  aa_offsets_(jj, ii) = next_offset;
117  next_offset +=
118  node1_num_states_for_aatype * node2_num_states_for_aatype;
119  }
120  }
121  }
122 
123  table_size_ = next_offset;
124  sparse_matrix_.dimension(table_size_);
125  if (next_offset != 0) {
126  sparse_matrix_ = 0.0f;
127  }
128  }
129 
130 
131 /// @brief returns true if node1aa and node2aa neighbor
132 ///
133 /// @param node1aa - [in] - amino acid on node 1
134 /// @param node2aa - [in] - amino acid on node 2
135  inline
136  bool get_sparse_aa_info( int node1aa, int node2aa) const
137  {
138  return (aa_offsets_(node2aa, node1aa) != -1);
139  }
140 
141 /// @brief returns the number of entries in the sparse matrix
142  inline
143  int
145  {
146  return table_size_;
147  }
148 
149 
150 /// @brief returns the number of bytes spent on the offset table
151  unsigned int
153  {
154  return aa_offsets_.size() * sizeof( int );
155  }
156 
157 
158 /// @brief retrieves the value held for a pair of states. State pairs without
159 /// entries in the sparse matrix interact with zero energy.
160 ///
161 /// @param ind1 - [in] - the SparseMatrixIndex for node1's state.
162 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
163  inline
164  value_type
165  get( SparseMatrixIndex const & ind1, SparseMatrixIndex const & ind2 )
166  const
167  {
168  int offset = get_offset( ind1, ind2);
169  if (offset == -1) return (value_type) 0;
170 
171  return sparse_matrix_( offset + get_submatrix_index(ind1, ind2) );
172  }
173 
174 /// @brief cache efficient version of the energy lookup function. All private data
175 /// for a particular sparse matrix has been held at a node, and now the node
176 /// provides that data back to this static method. Saves a considerable amount
177 /// of time in simulated annealing - enough that this OO version of Chris's
178 /// energy2b table is as fast as his was.
179 ///
180 /// called when node2 is entertaining an alternate state during sim annealing
181 ///
182 /// @param ind1 - [in] - the SparseMatrixIndex for node1's state.
183 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
184 /// @param ind2num_states_per_aatype - [in] - for node2's state, how many other
185 /// states does node2 have of the same amino acid type.
186 /// @param aa_offset - [in] - offset into sparse matrix. Node2 does not need
187 /// to know what this offset represents; it only needs to know that it must
188 /// provide this data to this method.
189 /// @param sparse_matrix - [in] - the sparse matrix that this method reads from
190  static
191  inline
192  value_type
193  get
194  (
195  SparseMatrixIndex const & ind1,
196  SparseMatrixIndex const & ind2,
197  int ind2num_states_per_aatype,
198  int aa_offset,
199  FArray1< value_type > const & sparse_matrix
200  )
201  {
202  if (aa_offset == -1)
203  return (value_type) 0;
204 
205  int index = aa_offset +
206  (ind2num_states_per_aatype *
207  (ind1.get_state_ind_for_this_aa_type() - 1) ) +
208  ind2.get_state_ind_for_this_aa_type();
209 
210  return sparse_matrix( index );
211  }
212 
213 /// @brief cache efficient version of the energy lookup function. All private data
214 /// for a particular sparse matrix has been held at a node, and now the node
215 /// provides that data back to this static method. Saves a considerable amount
216 /// of time in simulated annealing - enough that this OO version of Chris's
217 /// energy2b table is as fast as his was.
218 ///
219 /// called when node1 is entertaining an alternate state during sim annealing
220 ///
221 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
222 /// @param ind1_node_state_offset_minus_1 - [in] -
223 /// @param ind2_num_states_per_aatype [in] -
224 /// @param aa_offset - [in] - offset into sparse matrix. Node1 does not need
225 /// to know what this offset represents; it only needs to know that it must
226 /// provide this data to this method.
227 /// @param sparse_matrix - [in] - the sparse matrix that this method reads from
228 ///
229  static
230  inline
231  value_type
232  get
233  (
234  SparseMatrixIndex ind2,
235  int ind1_node_state_offset_minus_1,
236  int ind2_num_states_per_aatype,
237  int aa_offset,
238  FArray1< value_type > const & sparse_matrix
239  )
240  {
241 
242  if (aa_offset == -1)
243  return (value_type) 0;
244 
245  int index = aa_offset +
246  (ind2_num_states_per_aatype * ind1_node_state_offset_minus_1 ) +
247  ind2.get_state_ind_for_this_aa_type();
248  return sparse_matrix( index );
249  }
250 
251  /// @brief how many values are stored in this sparse matrix? Valid indices are 1 to size() for the
252  /// operator [] method
253  int
254  size() const {
255  return sparse_matrix_.size();
256  }
257 
258  /// @brief accessor that does not use sparse matrix data -- ignorant of aa type for both dimensions.
259  /// useful for when traversing all of the values stored in the sparse matrix.
260  value_type
261  operator [] ( int index ) const {
262  return sparse_matrix_( index );
263  }
264 
265  /// @brief non-const accessor for sparse matrix data -- ignorant of hte aa type for both dimensions.
266  /// useful for when traversing all of the values stored in the sparse matrix.
267  value_type &
268  operator [] ( int index ) {
269  return sparse_matrix_( index );
270  }
271 
272 
273 /// @brief stores a value for a pair of states. Does not store anything for state
274 /// pairs without entries in the sparse matrix. Does not give a warning
275 /// if you try to store a value where you cannot. Maybe it should.
276 ///
277 /// @param ind1 - [in] - the SparseMatrixIndex for node1's state.
278 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
279 /// @param val - [in] - the value to store for this state pair
280  inline
281  void
282  set
283  (
284  SparseMatrixIndex const & ind1,
285  SparseMatrixIndex const & ind2,
286  value_type const val
287  )
288  {
289  int offset = get_offset( ind1, ind2);
290  if (offset == -1) return;
291 
292  sparse_matrix_( offset + get_submatrix_index( ind1, ind2) ) = val;
293  return;
294  }
295 
296 /// @brief
297 /// cache efficient version of the energy lookup function. All private data
298 /// for a particular sparse matrix has been held at a node, and now the node
299 /// provides that data back to this static method. Saves a considerable amount
300 /// of time in simulated annealing - enough that this OO version of Chris's
301 /// energy2b table is as fast as his was.
302 ///
303 /// called when node2 is entertaining an alternate state during sim annealing
304 ///
305 /// @param ind1 - [in] - the SparseMatrixIndex for node1's state.
306 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
307 /// @param ind2num_states_per_aatype - [in] - for node2's state, how many other
308 /// states does node2 have of the same amino acid type.
309 /// @param aa_offset - [in] - offset into sparse matrix. Node2 does not need
310 /// to know what this offset represents; it only needs to know that it must
311 /// provide this data to this method.
312 /// @param sparse_matrix - [in] - the sparse matrix that this method reads from
313 /// @param val - [in] - the value to store for this state pair
314  static
315  inline
316  void
317  set
318  (
319  SparseMatrixIndex const & ind1,
320  SparseMatrixIndex const & ind2,
321  int ind2num_states_per_aatype,
322  int aa_offset,
323  FArray1< value_type > & sparse_matrix,
324  value_type val
325  )
326  {
327  if (aa_offset == -1)
328  return;
329 
330  int index = aa_offset +
331  (ind2num_states_per_aatype *
332  (ind1.get_state_ind_for_this_aa_type() - 1) ) +
334 
335  sparse_matrix( index ) = val;
336  }
337 
338 /// @brief cache efficient version of the energy lookup function. All private data
339 /// for a particular sparse matrix has been held at a node, and now the node
340 /// provides that data back to this static method. Saves a considerable amount
341 /// of time in simulated annealing - enough that this OO version of Chris's
342 /// energy2b table is as fast as his was.
343 ///
344 /// called when node1 is entertaining an alternate state during sim annealing
345 ///
346 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
347 /// @param ind1_node_state_offset_minus_1 - [in] -
348 /// @param ind2_num_states_per_aatype [in] -
349 /// @param aa_offset - [in] - offset into sparse matrix. Node1 does not need
350 /// to know what this offset represents; it only needs to know that it must
351 /// provide this data to this method.
352 /// @param sparse_matrix - [in] - the sparse matrix that this method reads from
353 /// @param val - [in] - the value to store for this state pair
354  static
355  inline
356  void
357  set
358  (
359  SparseMatrixIndex ind2,
360  int ind1_node_state_offset_minus_1,
361  int ind2_num_states_per_aatype,
362  int aa_offset,
363  FArray1< value_type > & sparse_matrix,
364  value_type val
365  )
366  {
367 
368  if (aa_offset == -1)
369  return;
370 
371  int index = aa_offset +
372  (ind2_num_states_per_aatype * ind1_node_state_offset_minus_1 ) +
374  sparse_matrix( index ) = val;
375  }
376 
377  // @brief Assigns all the entries in the sparse matrix to a single value. Zeroed out
378  // entries in the table remain zeroed out.
379  inline
380  void
381  blanket_set
382  (
383  value_type val
384  )
385  {
386  sparse_matrix_ = val;
387  }
388 
389 /// @brief adds to a value for a pair of states. Does not add anything for state
390 /// pairs without entries in the sparse matrix. Does not give a warning
391 /// if you try to add to a value where you cannot. Maybe it should.
392 ///
393 /// @param ind1 - [in] - the SparseMatrixIndex for node1's state.
394 /// @param ind2 - [in] - the SparseMatrixIndex for node2's state.
395 /// @param val - [in] - the value to add for this state pair
396  inline
397  void
398  add
399  (
400  SparseMatrixIndex const & ind1,
401  SparseMatrixIndex const & ind2,
402  value_type const val
403  )
404  {
405  int offset = get_offset( ind1, ind2);
406  if (offset == -1) return;
407 
408  sparse_matrix_( offset + get_submatrix_index( ind1, ind2) ) += val;
409  return;
410  }
411 
412  /// @brief scale a particular energy by a constant. Danger: There's no undoing a scale-by-zero
413  /// operation.
414  inline
415  void
417  SparseMatrixIndex const & ind1,
418  SparseMatrixIndex const & ind2,
419  value_type const scaler
420  )
421  {
422  int offset = get_offset( ind1, ind2 );
423  if ( offset == -1 ) return;
424 
425  sparse_matrix_( offset + get_submatrix_index( ind1, ind2 ) ) *= scaler;
426  }
427 
428  /// @brief scale all energies by a constant. Danger: There's no undoing a scale-by-zero
429  /// operation.
430  inline
431  void
433  value_type const scaler
434  )
435  {
436  sparse_matrix_ *= scaler;
437  }
438 
439 /// @brief returns a reference to the first position in the sparse matrix
440 /// to be used in a proxy array constructor.
441 ///
442 /// used to offload the private data in this class onto a node for cache
443 /// efficiency during simulated annealing.
444  inline
445  value_type &
447  {
448  return sparse_matrix_(1);
449  }
450 
451 /// @brief returns a reference to the first position in the amion acid pair offset
452 /// matrix to be used in a proxy array constructor.
453 ///
454 /// used to offload the private data in this class onto a node for cache
455 /// efficiency during simulated annealing.
456 ///
457  inline
458  FArray2D_int const &
460  {
461  return aa_offsets_;
462  }
463 
464  ObjexxFCL::FArray2D< value_type >
466  int node1aa,
467  int node2aa
468  ) const
469  {
470  ObjexxFCL::FArray2D< value_type > submatrix(
471  second_node_num_states_per_aatype_[ node2aa ],
472  first_node_num_states_per_aatype_[ node1aa ] );
473 
474  int offset = aa_offsets_( node2aa, node1aa );
475  if ( offset == -1 ) {
476  submatrix = value_type( 0 );
477  } else {
478  int const nvals = submatrix.size();
479  for ( int li_src = offset, li_dest = 0; li_dest < nvals ; ++li_dest, ++li_src ) {
480  submatrix[ li_dest ] = sparse_matrix_[ li_src ];
481  }
482  }
483 
484  return submatrix;
485  }
486 
487 
488 
489 ////////////////////////////////////////////////////////////////////////////////
490 /// @begin AminoAcidNeighborSparseMatrix::force_all_aa_neighbors
491 ///
492 /// @brief
493 /// set this sparse-matrix to a completely-non-sparse state. All entries
494 /// are potentially non-zero. Preserves the already-stored energies.
495 ///
496 /// In some places, its easier to set the matrix to completely-non-sparse first
497 /// and then to deallocate the zero-entry submatrices after computing all
498 /// pair energies.
499 ///
500 /// @global_read
501 ///
502 /// @global_write
503 ///
504 /// @remarks
505 ///
506 /// @references
507 ///
508 /// @authors apl
509 ///
510 /// @last_modified
511 ////////////////////////////////////////////////////////////////////////////////
512  inline
514  {
515  if (table_size_ != 0 ) {
516  FArray2D_int old_aa_offsets( aa_offsets_ ); //deep copy
517  FArray1D< value_type > old_sparse_matrix;
518  old_sparse_matrix.swap( sparse_matrix_ );
519 
520  FArray2D_bool new_aa_neighbors( num_aa_, num_aa_, true);
521 
522  set_sparse_aa_info(new_aa_neighbors);
523  copy_old_data_into_new_table( old_aa_offsets, old_sparse_matrix );
524  } else {
525  FArray2D_bool new_aa_neighbors( num_aa_, num_aa_, true);
526  set_sparse_aa_info(new_aa_neighbors);
527  }
528  }
529 
530 /// @brief Sets a pair of amino acids as neighboring. Preserves energies already
531 /// stored in the table.
532  inline
533  void force_aa_neighbors( int node1aa, int node2aa )
534  {
535  if ( aa_offsets_( node2aa, node1aa ) != -1 ) return;
536 
537  FArray2D_int old_aa_offsets( aa_offsets_ ); //deep copy
538  FArray1D< value_type > old_sparse_matrix;
539  old_sparse_matrix.swap( sparse_matrix_ );
540 
541  FArray2D_bool new_aa_neighbors( num_aa_, num_aa_, false );
542  for ( int ii = 1; ii <= num_aa_; ++ii ) {
543  for ( int jj = 1; jj <= num_aa_; ++jj ) {
544  if ( old_aa_offsets(jj, ii) != -1 ) {
545  new_aa_neighbors(jj, ii) = true;
546  }
547  }
548  }
549  new_aa_neighbors( node2aa, node1aa ) = true;
550 
551  set_sparse_aa_info( new_aa_neighbors );
552  copy_old_data_into_new_table( old_aa_offsets, old_sparse_matrix );
553  }
554 
555 /// @brief Deallocates amino-acid pair submatrices from the table that contain only
556 /// zero-valued entries.
558  {
559  drop_small_submatrices_where_possible( (value_type) 0 );
560  return;
561  }
562 
563 /// @brief Deallocates amino-acid pair submatrices from the table where the largest
564 /// magnitude entry in the submatrix fails to exceed the threshold, epsilon.
565 ///
566 /// @param epsilon - [in] - threshold for submatrix preservation
568  {
569  FArray2D_bool submatrix_worth_keeping( num_aa_, num_aa_, false);
570  bool found_submatrix_not_worth_keeping = false;
571 
572  for ( int ii = 1; ii <= num_aa_; ++ii ) {
573  int first_node_num_states_for_aa =
574  first_node_num_states_per_aatype_[ ii ];
575  if (first_node_num_states_for_aa == 0) continue;
576 
577  for ( int jj = 1; jj <= num_aa_; ++jj ) {
578  int second_node_num_states_for_aa =
579  second_node_num_states_per_aatype_[ jj ];
580  if (second_node_num_states_for_aa == 0) continue;
581 
582  int aa_neighbor_offset = aa_offsets_( jj, ii );
583  bool this_submatrix_worth_keeping = false;
584  if ( aa_neighbor_offset != -1) {
585  int submatrix_index = 1;
586  for (int kk = 1; kk <= first_node_num_states_for_aa; ++kk) {
587  for (int ll = 1; ll <= second_node_num_states_for_aa; ++ll) {
588  int index = aa_neighbor_offset + submatrix_index;
589 
590  value_type energy_mag =
591  std::abs( sparse_matrix_( index ) );
592  if (energy_mag > epsilon) {
593  this_submatrix_worth_keeping = true;
594  break;
595  }
596  ++submatrix_index;
597  }
598  if ( this_submatrix_worth_keeping ) break;
599  }
600  submatrix_worth_keeping( jj, ii ) = this_submatrix_worth_keeping;
601  if (! this_submatrix_worth_keeping ) {
602  found_submatrix_not_worth_keeping = true;
603  }
604  }
605  }
606  }
607 
608  if (! found_submatrix_not_worth_keeping ) return;
609 
610  FArray1D_float old_sparse_matrix;
611  old_sparse_matrix.swap( sparse_matrix_ );
612 
613  FArray2D_int old_aa_offsets( aa_offsets_ ); //deep copy
614  set_sparse_aa_info( submatrix_worth_keeping );
615  copy_old_data_into_new_table( old_aa_offsets, old_sparse_matrix );
616 
617  return;
618  }
619 
620 
621 protected:
622 
623 /// @brief Lookup for offset into sparse table. Prevents index-out-of-bounds error
624 /// if either amino-acid types of the SparseMatrixIndices are 0.
625 ///
626 /// @param ind1 - [in] - the sparse matrix index of node1
627 /// @param ind2 - [in] - the sparse matrix index of node2
628  inline
629  int
630  get_offset( SparseMatrixIndex const & ind1, SparseMatrixIndex const & ind2)
631  const
632  {
633  if (ind1.get_aa_type() == 0 || ind2.get_aa_type() == 0 ) return -1;
634 
635  return aa_offsets_( ind2.get_aa_type(), ind1.get_aa_type() );
636  }
637 
638 /// @brief submatrix indexing function
639 ///
640 /// @param ind1 - [in] - the sparse matrix index of node1
641 /// @param ind2 - [in] - the sparse matrix index of node2
642  inline
643  int
644  get_submatrix_index
645  (
646  SparseMatrixIndex const & ind1,
647  SparseMatrixIndex const & ind2
648  )
649  const
650  {
651  return (ind1.get_state_ind_for_this_aa_type() - 1) *
652  second_node_num_states_per_aatype_[ ind2.get_aa_type() ] +
654  }
655 
656 /// @brief Assigns to the (freshly allocated) sparse_matrix_ member variable the
657 /// values held in the input sparse matrix . Used in both shrinking
658 /// and growing the sparse matrix.
659 ///
660 /// @param old_aa_offsets - [in] - aa offset data for the original table
661 /// @param old_sparse_matrix - [in] - original table
662  void copy_old_data_into_new_table
663  (
664  FArray2D_int const & old_aa_offsets,
665  FArray1D< value_type > const & old_sparse_matrix
666  )
667  {
668  for ( int ii = 1; ii <= num_aa_; ++ii ) {
669  int first_node_num_states_for_aa =
670  first_node_num_states_per_aatype_[ ii ];
671  if (first_node_num_states_for_aa == 0) continue;
672 
673  for ( int jj = 1; jj <= num_aa_; ++jj ) {
674  int second_node_num_states_for_aa =
675  second_node_num_states_per_aatype_[ jj ];
676  if (second_node_num_states_for_aa == 0) continue;
677 
678  int source_aa_offset = old_aa_offsets( jj, ii );
679  int destination_aa_offset = aa_offsets_( jj, ii );
680 
681  if ( source_aa_offset != -1 && destination_aa_offset != -1 ) {
682  int submatrix_index = 1;
683  for (int kk = 1; kk <= first_node_num_states_for_aa; ++kk) {
684  for (int ll = 1; ll <= second_node_num_states_for_aa; ++ll) {
685  int index_destination = destination_aa_offset + submatrix_index;
686  int index_source = source_aa_offset + submatrix_index;
687 
688  sparse_matrix_( index_destination ) =
689  old_sparse_matrix( index_source );
690  submatrix_index++;
691  }
692  }
693  }
694  }
695  }
696  }
697 
698 // Protected Member Data
699 
700  int const num_aa_;
701  FArray2D_int aa_offsets_;
704  FArray1D< value_type > sparse_matrix_;
706 };
707 
708 } //end namespace interaction_graph
709 } //end namespace pack
710 } //end namespace core
711 
712 
713 #endif