SIRF  3.8.0
DataContainer.h
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2015 - 2019, 2021, 2023 Rutherford Appleton Laboratory STFC
4 Copyright 2024 University College London
5 
6 This is software developed for the Collaborative Computational
7 Project in Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR)
8 (http://www.ccpsynerbi.ac.uk/).
9 
10 Licensed under the Apache License, Version 2.0 (the "License");
11 you may not use this file except in compliance with the License.
12 You may obtain a copy of the License at
13 http://www.apache.org/licenses/LICENSE-2.0
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19 
20 */
21 
22 #ifndef SIRF_ABSTRACT_DATA_CONTAINER_TYPE
23 #define SIRF_ABSTRACT_DATA_CONTAINER_TYPE
24 
25 #include<complex>
26 #include <map>
28 
29 namespace sirf {
30 
31  typedef std::map<std::string, int> Dimensions;
32 
44  class ContainerBase {
45  public:
46  virtual ~ContainerBase() {}
47  //virtual ObjectHandle<DataContainer>* new_data_container_handle() const = 0;
48  };
58  class DataContainer: public virtual ContainerBase {
59  public:
60  virtual ~DataContainer() {}
61  //virtual DataContainer* new_data_container() const = 0;
62  virtual ObjectHandle<DataContainer>* new_data_container_handle() const = 0;
63  virtual unsigned int items() const = 0;
64  virtual bool is_complex() const = 0;
66  virtual int bits() const
67  {
68  // default value
69  return is_complex() ? 16 * sizeof(float) : 8 * sizeof(float);
70  }
71 
73  virtual float norm() const = 0;
74 
77 
79  virtual void dot(const DataContainer& dc, void* ptr) const = 0;
80 
82  virtual void sum(void* ptr) const = 0;
83 
85  virtual void max(void* ptr) const = 0;
86 
88  virtual void min(void* ptr) const = 0;
89 
91  virtual void multiply
92  (const DataContainer& x, const DataContainer& y) = 0;
94  virtual void multiply
95  (const DataContainer& x, const void* ptr_y) = 0;
96 
98  virtual void add
99  (const DataContainer& x, const void* ptr_y) = 0;
100 
102  virtual void divide
103  (const DataContainer& x, const DataContainer& y) = 0;
104 
106  virtual void maximum
107  (const DataContainer& x, const DataContainer& y) = 0;
108  virtual void maximum
109  (const DataContainer& x, const void* ptr_y) = 0;
110 
112  virtual void minimum
113  (const DataContainer& x, const DataContainer& y) = 0;
114  virtual void minimum
115  (const DataContainer& x, const void* ptr_y) = 0;
116 
118  virtual void power
119  (const DataContainer& x, const DataContainer& y) = 0;
120  virtual void power
121  (const DataContainer& x, const void* ptr_y) = 0;
122 
124  virtual void exp(const DataContainer& x) = 0;
126  virtual void log(const DataContainer& x) = 0;
128  virtual void sqrt(const DataContainer& x) = 0;
130  virtual void sign(const DataContainer& x) = 0;
132  virtual void abs(const DataContainer& x) = 0;
133 
135  virtual void axpby(
136  const void* ptr_a, const DataContainer& x,
137  const void* ptr_b, const DataContainer& y) = 0;
139  virtual void xapyb(
140  const DataContainer& x, const void* ptr_a,
141  const DataContainer& y, const void* ptr_b) = 0;
142 
144  virtual void xapyb(
145  const DataContainer& x, const DataContainer& a,
146  const DataContainer& y, const DataContainer& b) = 0;
147 
149  virtual void xapyb(
150  const DataContainer& a_x, const void* ptr_a,
151  const DataContainer& a_y, const DataContainer& a_b) = 0;
152 
154  void xapyb(
155  const DataContainer& a_x, const DataContainer& a_a,
156  const DataContainer& a_y, const void* ptr_b)
157  {
158  xapyb(a_y, ptr_b, a_x, a_a);
159  }
160 
161  virtual void write(const std::string &filename) const = 0;
162 
163  bool is_empty() const
164  {
165  return items() < 1;
166  }
167 
168  std::unique_ptr<DataContainer> clone() const
169  {
170  return std::unique_ptr<DataContainer>(this->clone_impl());
171  }
172 
174  void conjugate()
175  {
176  this->conjugate_impl();
177  }
178 
180  std::unique_ptr<DataContainer> conjugate() const
181  {
182  DataContainer* ptr = this->clone_impl();
183  ptr->conjugate();
184  return std::unique_ptr<DataContainer>(ptr);
185  }
186 
187  template<typename T>
188  static T product(T x, T y)
189  {
190  return x * y;
191  }
192 
193  template<typename T>
194  static T ratio(T x, T y)
195  {
196  return x / y;
197  }
198 
199  template<typename T>
200  static T inverse_ratio(T x, T y)
201  {
202  return y / x;
203  }
204 
205  template<typename T>
206  static T sum(T x, T y)
207  {
208  return x + y;
209  }
210 
211  template<typename T>
212  static T maximum(T x, T y)
213  {
214  return std::max(x, y);
215  }
216  template<typename T>
217  static T maxabs(T x, T y)
218  {
219  return std::max(std::abs(x), std::abs(y));
220  }
221  template<typename T>
222  static T maxreal(T x, T y)
223  {
224  return std::real(x) > std::real(y) ? x : y;
225  }
226 
227  template<typename T>
228  static T minimum(T x, T y)
229  {
230  return std::min(x, y);
231  }
232  template<typename T>
233  static T minabs(T x, T y)
234  {
235  return std::min(std::abs(x), std::abs(y));
236  }
237  template<typename T>
238  static T minreal(T x, T y)
239  {
240  return std::real(x) < std::real(y) ? x : y;
241  }
242  static std::complex<float> power(std::complex<float> x, std::complex<float> y)
243  {
244  return std::pow(x, y);
245  }
246  static std::complex<float> exp(std::complex<float> x)
247  {
248  return std::exp(x);
249  }
250  static std::complex<float> log(std::complex<float> x)
251  {
252  return std::log(x);
253  }
254  static std::complex<float> sqrt(std::complex<float> x)
255  {
256  return std::sqrt(x);
257  }
258  template<typename T>
259  static T sign(T x)
260  {
261  return (std::real(x) > 0) - (std::real(x) < 0);
262  }
263  template<typename T>
264  static T abs(T x)
265  {
266  return T(std::abs(x));
267  }
268 
269  protected:
270  virtual DataContainer* clone_impl() const = 0;
272  virtual void conjugate_impl()
273  {
274  if (is_complex())
275  THROW("complex data containes must override conjugate_impl()");
276  }
277  };
278 }
279 
280 #endif
Execution status type and wrappers for C++ objects.
Definition: DataHandle.h:159
Abstract data container.
Definition: DataContainer.h:44
Abstract data container with numerical operations.
Definition: DataContainer.h:58
virtual void conjugate_impl()
we assume data to be real, complex data containers must override this
Definition: DataContainer.h:272
std::unique_ptr< DataContainer > conjugate() const
returns unique pointer to the complex-conjugated copy of this container
Definition: DataContainer.h:180
void xapyb(const DataContainer &a_x, const DataContainer &a_a, const DataContainer &a_y, const void *ptr_b)
*this = elementwise sum of elementwise x*a and y*b
Definition: DataContainer.h:154
virtual void xapyb(const DataContainer &x, const DataContainer &a, const DataContainer &y, const DataContainer &b)=0
*this = elementwise sum of two elementwise products x*a and y*b
virtual void sum(void *ptr) const =0
calculates the sum of this container elements
virtual float norm() const =0
returns the norm of this container viewed as a vector
virtual void xapyb(const DataContainer &a_x, const void *ptr_a, const DataContainer &a_y, const DataContainer &a_b)=0
*this = elementwise sum of x*a and elementwise y*b
virtual void add(const DataContainer &x, const void *ptr_y)=0
*this = the sum x + y with scalar y
virtual void multiply(const DataContainer &x, const void *ptr_y)=0
*this = the product x * y with scalar y
virtual void multiply(const DataContainer &x, const DataContainer &y)=0
*this = the elementwise product x*y
virtual void maximum(const DataContainer &x, const DataContainer &y)=0
*this = the elementwise max(x, y)
void conjugate()
overwrites this container's complex data with complex conjugate values
Definition: DataContainer.h:174
virtual void sign(const DataContainer &x)=0
*this = the elementwise sign(x)
virtual void abs(const DataContainer &x)=0
*this = the elementwise abs(x)
virtual void exp(const DataContainer &x)=0
*this = the elementwise exp(x)
virtual void power(const DataContainer &x, const DataContainer &y)=0
*this = the elementwise pow(x, y)
virtual void axpby(const void *ptr_a, const DataContainer &x, const void *ptr_b, const DataContainer &y)=0
*this = the linear combination of x and y
virtual void minimum(const DataContainer &x, const DataContainer &y)=0
*this = the elementwise min(x, y)
virtual void dot(const DataContainer &dc, void *ptr) const =0
calculates the dot product of this container with another one
virtual void divide(const DataContainer &x, const DataContainer &y)=0
*this = the elementwise ratio x / y
virtual void min(void *ptr) const =0
calculates the value of this container's element with the smallest real part
virtual void log(const DataContainer &x)=0
*this = the elementwise log(x)
virtual int bits() const
returns the size of data elements
Definition: DataContainer.h:66
virtual void xapyb(const DataContainer &x, const void *ptr_a, const DataContainer &y, const void *ptr_b)=0
alternative interface to the above
virtual void sqrt(const DataContainer &x)=0
*this = the elementwise sqrt(x)
virtual void max(void *ptr) const =0
calculates the value of this container's element with the largest real part
Abstract base class for SIRF image data.
Definition: GeometricalInfo.cpp:141