VinaLC: Parallel Molecular Docking Program

Biochemical and Biophysical Systems Group
VinaLC version: 1.1.2

matrix.h
Go to the documentation of this file.
1 /*
2 
3  Copyright (c) 2006-2010, The Scripps Research Institute
4 
5  Licensed under the Apache License, Version 2.0 (the "License");
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16 
17  Author: Dr. Oleg Trott <ot14@columbia.edu>,
18  The Olson Lab,
19  The Scripps Research Institute
20 
21 */
22 
23 #ifndef VINA_MATRIX_H
24 #define VINA_MATRIX_H
25 
26 #include <vector>
28 
29 // these 4 lines are used 3 times verbatim - defining a temp macro to ease the pain
30 #define VINA_MATRIX_DEFINE_OPERATORS \
31  const T& operator()(sz i) const { return m_data[i]; } \
32  T& operator()(sz i) { return m_data[i]; } \
33  const T& operator()(sz i, sz j) const { return m_data[index(i, j)]; } \
34  T& operator()(sz i, sz j) { return m_data[index(i, j)]; }
35 
36 template<typename T>
37 class matrix {
38  std::vector<T> m_data;
40 public:
41  sz index(sz i, sz j) const {
42  assert(j < m_j);
43  assert(i < m_i);
44  return i + m_i*j; // column-major
45  }
46  matrix() : m_i(0), m_j(0) {}
47  matrix(sz i, sz j, const T& filler_val) : m_data(i*j, filler_val), m_i(i), m_j(j) {}
48  void resize(sz m, sz n, const T& filler_val) { // new sizes should be the same or greater than the old
49  if(m == dim_1() && n == dim_2()) return; // no-op
50  VINA_CHECK(m >= dim_1());
51  VINA_CHECK(n >= dim_2());
52  std::vector<T> tmp(m*n, filler_val);
53  VINA_FOR(i, m_i)
54  VINA_FOR(j, m_j)
55  tmp[i+m*j] = (*this)(i, j);
56  m_data = tmp;
57  m_i = m;
58  m_j = n;
59  }
60  void append(const matrix<T>& x, const T& filler_val) {
61  sz m = dim_1();
62  sz n = dim_2();
63  resize(m + x.dim_1(), n + x.dim_2(), filler_val);
64  VINA_FOR(i, x.dim_1())
65  VINA_FOR(j, x.dim_2())
66  (*this)(i+m, j+n) = x(i, j);
67  }
68  VINA_MATRIX_DEFINE_OPERATORS // temp macro defined above
69  sz dim_1() const { return m_i; }
70  sz dim_2() const { return m_j; }
71 };
72 
73 template<typename T>
75  std::vector<T> m_data;
77 public:
78  sz index(sz i, sz j) const { return triangular_matrix_index(m_dim, i, j); }
79  sz index_permissive(sz i, sz j) const { return (i < j) ? index(i, j) : index(j, i); }
81  triangular_matrix(sz n, const T& filler_val) : m_data(n*(n+1)/2, filler_val), m_dim(n) {}
82  VINA_MATRIX_DEFINE_OPERATORS // temp macro defined above
83  sz dim() const { return m_dim; }
84 };
85 
86 template<typename T>
88  std::vector<T> m_data;
90 public:
91  sz index(sz i, sz j) const {
92  assert(j < m_dim);
93  assert(i < j);
94  assert(j >= 1); // by implication, really
95  return i + j*(j-1)/2;
96  }
97  sz index_permissive(sz i, sz j) const { return (i < j) ? index(i, j) : index(j, i); }
99  strictly_triangular_matrix(sz n, const T& filler_val) : m_data(n*(n-1)/2, filler_val), m_dim(n) {}
100  void resize(sz n, const T& filler_val) {
101  if(n == m_dim) return; // no-op
102  VINA_CHECK(n > m_dim);
103  m_dim = n;
104  m_data.resize(n*(n-1)/2, filler_val); // preserves original data
105  }
106  void append(const strictly_triangular_matrix<T>& m, const T& filler_val) {
107  sz n = dim();
108  resize(n + m.dim(), filler_val);
109  VINA_FOR(i, m.dim())
110  VINA_RANGE(j, i+1, m.dim())
111  (*this)(i+n, j+n) = m(i, j);
112  }
113  void append(const matrix<T>& rectangular, const strictly_triangular_matrix<T>& triangular) {
114  VINA_CHECK(dim() == rectangular.dim_1());
115  VINA_CHECK(rectangular.dim_2() == triangular.dim());
116 
117  // a filler value is needed by append or resize
118  // we will use a value from rectangular as the filler value
119  // but it can not be obtained if dim_1 or dim_2 is 0
120  // these cases have to be considered separately
121  if(rectangular.dim_2() == 0) return;
122  if(rectangular.dim_1() == 0) {
123  (*this) = triangular;
124  return;
125  }
126  const T& filler_val = rectangular(0, 0); // needed by 'append below'
127 
128  sz n = dim();
129  append(triangular, filler_val);
130  VINA_FOR(i, rectangular.dim_1())
131  VINA_FOR(j, rectangular.dim_2())
132  (*this)(i, n + j) = rectangular(i, j);
133  }
134  VINA_MATRIX_DEFINE_OPERATORS // temp macro defined above
135  sz dim() const { return m_dim; }
136 };
137 
138 #undef VINA_MATRIX_DEFINE_OPERATORS
139 
140 #endif