Openholo  v4.0
Open Source Digital Holographic Library
function.h
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install, copy or use the software.
7 //
8 //
9 // License Agreement
10 // For Open Source Digital Holographic Library
11 //
12 // Openholo library is free software;
13 // you can redistribute it and/or modify it under the terms of the BSD 2-Clause license.
14 //
15 // Copyright (C) 2017-2024, Korea Electronics Technology Institute. All rights reserved.
16 // E-mail : contact.openholo@gmail.com
17 // Web : http://www.openholo.org
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 // 1. Redistribution's of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistribution's in binary form must reproduce the above copyright notice,
26 // this list of conditions and the following disclaimer in the documentation
27 // and/or other materials provided with the distribution.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the copyright holder or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // This software contains opensource software released under GNU Generic Public License,
41 // NVDIA Software License Agreement, or CUDA supplement to Software License Agreement.
42 // Check whether software you use contains licensed software.
43 //
44 //M*/
45 
46 #ifndef __function_h
47 #define __function_h
48 
49 #include "complex.h"
50 #include "mat.h"
51 #include "vec.h"
52 
53 #include <chrono>
54 #include <random>
55 
56 namespace oph
57 {
58 #define CUR_TIME std::chrono::system_clock::now()
59 #define ELAPSED_TIME(x,y) ((std::chrono::duration<double>)(y - x)).count()
60 #define CUR_TIME_DURATION CUR_TIME.time_since_epoch()
61 #define CUR_TIME_DURATION_MILLI_SEC std::chrono::duration_cast<std::chrono::milliseconds>(CUR_TIME_DURATION).count()
62 
63  template<typename type, typename T>
64  inline type force_cast(const Complex<T>& p) {
65  return type(p.real());
66  }
67 
68  template<typename type, typename T>
69  inline type force_cast(const T& p) {
70  return type(p);
71  }
72 
73  inline Real minOfArr(const std::vector<Real>& arr) {
74  Real min = MAX_DOUBLE;
75  for (auto item : arr) { if (item < min) min = item; }
76  return min;
77  }
78 
79  inline Real minOfArr(const Real* src, const int& size) {
80  Real min = MAX_DOUBLE;
81  for (int i = 0; i < size; i++) {
82  if (*(src + i) < min) min = *(src + i);
83  }
84  return min;
85  }
86 
87  inline Real maxOfArr(const std::vector<Real>& arr) {
88  Real max = MIN_DOUBLE;
89  for (auto item : arr) { if (item > max) max = item; }
90  return max;
91  }
92 
93  inline Real maxOfArr(const Real* src, const int& size) {
94  Real max = MIN_DOUBLE;
95  for (int i = 0; i < size; i++) {
96  if (*(src + i) > max) max = *(src + i);
97  }
98  return max;
99  }
100 
101  inline Real average(const Real* src, const int& size) {
102  Real ave;
103  Real sum = 0;
104  for (int i = 0; i < size; i++) {
105  sum += *(src + i);
106  }
107  ave = sum / size;
108 
109  return ave;
110  }
111 
112  template<typename T>
113  inline void abs(const oph::Complex<T>& src, oph::Complex<T>& dst) {
114  dst = std::abs(force_cast<std::complex<Real>>(src));
115  }
116 
117  template<typename T>
118  inline void absArr(const std::vector<Complex<T>>& src, std::vector<oph::Complex<T>>& dst) {
119  dst.clear();
120  dst.reserve(src.size());
121  for (auto item : src) dst.push_back(oph::abs(item));
122  }
123 
124  template<typename T>
126  if (src.getSize() != dst.getSize()) return;
127  oph::ivec2 matSize;
128  for (int x = 0; x < matSize[_X]; x++) {
129  for (int y = 0; y < matSize[_Y]; y++)
130  oph::abs(src[x][y], dst[x][y]);
131  }
132  }
133 
134  template<typename T>
135  inline void absCplx(const oph::Complex<T>& src, T& dst) {
136  dst = sqrt(src.real() * src.real() + src.imag() * src.imag());
137  }
138 
139  template<typename T>
140  inline void absCplxArr(const oph::Complex<T>* src, T* dst, const int& size) {
141  for (int i = 0; i < size; i++) {
142  absCplx<T>(*(src + i), *(dst + i));
143  }
144  }
145 
146  template<typename T>
147  inline T getReal(const oph::Complex<T> src) {
148  return src->real();
149  }
150 
151  template<typename T>
152  inline void realPart(const oph::Complex<T>* src, T* dst, const int& size) {
153  for (int i = 0; i < size; i++) {
154  *(dst + i) = (src + i)->real();
155  }
156  }
157 
158  template<typename T>
159  inline void angle(const std::vector<Complex<T>>& src, std::vector<T>& dst) {
160  dst.clear();
161  dst.reserve(src.size());
162  for (auto item : src) { dst.push_back(src.angle()); }
163  }
164 
165  template<typename T>
166  inline T angle(const oph::Complex<T>& src) {
167  T dst;
168  dst = atan2(src.imag(), src.real());
169  return dst;
170  }
171 
175  template<typename T>
176  inline void normalize(const Complex<T>* src, Complex<T>* dst, const int& size) {
177  Real* abs = new Real[size];
178  oph::absCplxArr<Real>(src, abs, size);
179 
180  Real max = oph::maxOfArr(abs, size);
181 
182  for (int i = 0; i < size; i++) {
183  *(dst + i) = *(src + i) / max;
184  }
185  delete[] abs;
186  }
187  template<typename T>
188  inline void normalize(const T* src, T* dst, const int& size) {
189 
190  Real min = oph::minOfArr(src, size);
191  Real max = oph::maxOfArr(src, size);
192 
193  for (int i = 0; i < size; i++) {
194  *(dst + i) = (*(src + i) - min) / (max - min);
195  }
196  }
197 
201  template<typename T>
202  inline void normalize(T* src, oph::uchar* dst, const oph::uint nx, const oph::uint ny) {
203  T minVal, maxVal;
204  minVal = maxVal = src[0];
205  for (oph::uint ydx = 0; ydx < ny; ydx++){
206  for (oph::uint xdx = 0; xdx < nx; xdx++){
207  T *temp_pos = src + xdx + ydx * nx;
208  if ((xdx == 0) && (ydx == 0)) { minVal = *(temp_pos); maxVal = *(temp_pos); }
209  else {
210  if ((*temp_pos) < minVal) minVal = (*temp_pos);
211  if ((*temp_pos) > maxVal) maxVal = (*temp_pos);
212  }
213  }
214  }
215 
216  for (oph::uint ydx = 0; ydx < ny; ydx++) {
217  for (oph::uint xdx = 0; xdx < nx; xdx++) {
218  T *src_pos = src + xdx + ydx * nx;
219  //oph::uchar *res_pos = dst + xdx + (ny - ydx - 1)*nx;
220  oph::uchar *res_pos = dst + xdx + ydx * nx;
221  *(res_pos) = oph::force_cast<oph::uchar>(((*(src_pos)-minVal) / (maxVal - minVal)) * 255 + 0.5);
222  }
223  }
224  }
225 
229  template<typename T>
230  inline void normalize(const std::vector<T>* src, std::vector<oph::uchar>* dst) {
231  T minVal, maxVal;
232  if (src->size() != dst->size())
233  {
234  dst->clear();
235  dst->reserve(src->size());
236  }
237 
238  for (auto iter = src->begin(); iter != src->end(); iter++) {
239  if (iter == src->begin()) {
240  minVal = *iter;
241  maxVal = *iter;
242  } else {
243  if (*iter < minVal) minVal = *iter;
244  if (*iter > maxVal) maxVal = *iter;
245  }
246  }
247 
248  for (auto iter = src->begin(); iter != src->end(); iter++)
249  dst->push_back(oph::force_cast<oph::uchar>((((*iter) - minVal) / (maxVal - minVal)) * 255 + 0.5));
250  }
251 
255  template<typename T>
256  inline void memsetArr(const std::vector<T>* pArr, T _Value, oph::uint beginIndex, oph::uint endIndex){
257  auto iter = pArr->begin() + (beginIndex);
258  auto it_end = pArr->begin() + (endIndex);
259  for (; iter != it_end; iter++) { (*iter) = _Value; }
260  }
261 
262  template<typename T>
263  void memsetArr(T* pArr, const T& _Value, const oph::uint& beginIndex, const oph::uint& endIndex) {
264  for (uint i = beginIndex; i <= endIndex; i++) {
265  *(pArr + i) = _Value;
266  }
267  }
268 
272  template<typename T>
273  inline void circShift(const T* src, T* dst, int shift_x, int shift_y, int xdim, int ydim) {
274  for (int i = 0; i < xdim; i++) {
275  int ti = (i + shift_x) % xdim;
276  if (ti < 0) ti = xdim + ti;
277  for (int j = 0; j < ydim; j++) {
278  int tj = (j + shift_y) % ydim;
279  if (tj < 0) tj = ydim + tj;
280  dst[ti * ydim + tj] = src[i * ydim + j];
281  }
282  }
283  }
284 
294  inline Real rand(const Real min, const Real max, oph::ulong _SEED_VALUE = 0) {
295  std::mt19937_64 rand_dev;
296  if (!_SEED_VALUE) rand_dev = std::mt19937_64(CUR_TIME_DURATION_MILLI_SEC);
297  else rand_dev = std::mt19937_64(_SEED_VALUE);
298 
299  std::uniform_real_distribution<Real> dist(min, max);
300 
301  return dist(rand_dev);
302  }
303 
313  inline int rand(const int min, const int max, oph::ulong _SEED_VALUE = 0) {
314  std::mt19937_64 rand_dev;
315  if (!_SEED_VALUE) rand_dev = std::mt19937_64(CUR_TIME_DURATION_MILLI_SEC);
316  else rand_dev = std::mt19937_64(_SEED_VALUE);
317 
318  std::uniform_int_distribution<int> dist(min, max);
319 
320  return dist(rand_dev);
321  }
322 
323  inline void getPhase(oph::Complex<Real>* src, Real* dst, const int& size)
324  {
325  for (int i = 0; i < size; i++) {
326  *(dst + i) = angle<Real>(*(src + i)) + M_PI;
327  }
328  }
329 
330  inline void getAmplitude(oph::Complex<Real>* src, Real* dst, const int& size) {
331  absCplxArr<Real>(src, dst, size);
332  }
333 
334  template<typename T>
335  inline void Field2Buffer(matrix<T>& src, T** dst) {
336  ivec2 bufferSize = src.getSize();
337 
338  *dst = new oph::Complex<Real>[bufferSize[_X] * bufferSize[_Y]];
339 
340  int idx = 0;
341  for (int x = 0; x < bufferSize[_X]; x++) {
342  for (int y = 0; y < bufferSize[_Y]; y++) {
343  (*dst)[idx] = src[x][y];
344  idx++;
345  }
346  }
347  }
348 
349  template<typename T>
350  inline void Buffer2Field(const T* src, matrix<T>& dst, const ivec2 buffer_size) {
351  ivec2 matSize = buffer_size;
352 
353  int idx = 0;
354  for (int x = 0; x < matSize[_X]; x++) {
355  for (int y = 0; y < matSize[_Y]; y++) {
356  dst[x][y] = src[idx];
357  idx++;
358  }
359  }
360  }
364  inline void meshGrid() {
365 
366  }
367 }
368 
369 
370 #endif // !__function_h
void abs(const oph::Complex< T > &src, oph::Complex< T > &dst)
Definition: function.h:113
oph::ivec2 & getSize(void)
Definition: mat.h:115
class for the complex number and its arithmetic. type T == type cplx type only float || double T real...
Definition: complex.h:354
void absMat(const oph::matrix< oph::Complex< T >> &src, oph::matrix< oph::Complex< T >> &dst)
Definition: function.h:125
unsigned long ulong
Definition: typedef.h:65
unsigned char uchar
Definition: typedef.h:64
void circShift(const T *src, T *dst, int shift_x, int shift_y, int xdim, int ydim)
Shifts the elements by shift_x, shift_y.
Definition: function.h:273
float Real
Definition: typedef.h:55
Real average(const Real *src, const int &size)
Definition: function.h:101
void absCplxArr(const oph::Complex< T > *src, T *dst, const int &size)
Definition: function.h:140
structure for 2-dimensional integer vector and its arithmetic.
Definition: ivec.h:66
void getPhase(oph::Complex< Real > *src, Real *dst, const int &size)
Definition: function.h:323
void normalize(const Complex< T > *src, Complex< T > *dst, const int &size)
Normalize all elements of Complex<T>* src from 0 to 1.
Definition: function.h:176
#define MIN_DOUBLE
Definition: define.h:148
#define _Y
Definition: define.h:96
void realPart(const oph::Complex< T > *src, T *dst, const int &size)
Definition: function.h:152
#define _X
Definition: define.h:92
void absArr(const std::vector< Complex< T >> &src, std::vector< oph::Complex< T >> &dst)
Definition: function.h:118
#define CUR_TIME_DURATION_MILLI_SEC
Definition: function.h:61
void memsetArr(const std::vector< T > *pArr, T _Value, oph::uint beginIndex, oph::uint endIndex)
Set elements to specific values from begin index to end index.
Definition: function.h:256
#define MAX_DOUBLE
Definition: define.h:140
void Field2Buffer(matrix< T > &src, T **dst)
Definition: function.h:335
type force_cast(const Complex< T > &p)
Definition: function.h:64
void meshGrid()
Definition: function.h:364
T getReal(const oph::Complex< T > src)
Definition: function.h:147
Real rand(const Real min, const Real max, oph::ulong _SEED_VALUE=0)
Get random Real value from min to max.
Definition: function.h:294
void getAmplitude(oph::Complex< Real > *src, Real *dst, const int &size)
Definition: function.h:330
void angle(const std::vector< Complex< T >> &src, std::vector< T > &dst)
Definition: function.h:159
Real minOfArr(const std::vector< Real > &arr)
Definition: function.h:73
Real maxOfArr(const std::vector< Real > &arr)
Definition: function.h:87
void Buffer2Field(const T *src, matrix< T > &dst, const ivec2 buffer_size)
Definition: function.h:350
Definition: Bitmap.h:49
Real sum(const vec2 &a)
Definition: vec.h:401
void absCplx(const oph::Complex< T > &src, T &dst)
Definition: function.h:135
unsigned int uint
Definition: typedef.h:62
#define M_PI
Definition: define.h:52