LILAC
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
utils.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2014, Sam Schetterer, Nathan Kutz, University of Washington
3 Authors: Sam Schetterer
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 
10 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
11 
12 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 
16 */
17 #include "defs.hpp"
18 #include "engine/item.h"
19 #include <map>
20 #include <set>
21 extern "C"{
22 #include <complex.h>
23 #include <acml.h>
24 }
25 
26 
37 void err(std::string message, std::string function, std::string file, _fatal f){
38  std::cerr<<"A fatal error has occurred in function "<<function<<" in file "<<file<<
39  std::endl<<"Error message is:"<<std::endl<<message<<
40  std::endl<<"Exiting program"<<std::endl;
41  exit(1);
42 }
43 
54 void err(std::string message, std::string function, std::string file, _warning w){
55  std::cerr<<"A non-fatal error has occurred in function "<<function<<" in file "<<file<<
56  std::endl<<"Error message is:"<<std::endl<<message<<std::endl;
57 }
58 void err(std::string message, std::string function, std::string file, const item* p, _fatal f){
59  std::cerr<<"A fatal error has occurred in function "<<function<<" in file "<<file<<
60  "\nError message is:\n"<<message<<"\n";
61  p->print();
62  std::cerr << "\nExiting program\n";
63  exit(1);
64 }
65 void err(std::string message, std::string function, std::string file, const item* p, _warning f){
66  std::cerr<<"A non-fatal error has occurred in function "<<function<<" in file "<<file<<
67  "\nError message is:\n"<<message<<"\n";
68  p->print();
69  std::cerr << "\nContinuing program\n";
70 }
71 void err(std::string message, std::string function, std::string file, std::shared_ptr<item> p, _fatal f){
72  std::cerr<<"A fatal error has occurred in function "<<function<<" in file "<<file<<
73  "\nError message is:\n"<<message<<"\n";
74  p->print();
75  std::cerr << "\nExiting program\n";
76  exit(1);
77 }
78 void err(std::string message, std::string function, std::string file, std::shared_ptr<item> p, _warning f){
79  std::cerr<<"A non-fatal error has occurred in function "<<function<<" in file "<<file<<
80  "\nError message is:\n"<<message<<"\n";
81  p->print();
82  std::cerr << "\nContinuing program\n";
83 }
84 
85 //Since everything has fftw wrappers, I'm writing in terms of that although we use the acml functions
86 
91  public:
92  doublecomplex* comm;
93  int info;
94  size_t len;
96  fft_plan_holder(size_t n):comm(new doublecomplex[3*n+100]), len(n){
97  zfft1dx(0, 1.0, 0, (int)n, 0, 1, 0, 1, comm, &info);
98  }
99  fft_plan_holder(const fft_plan_holder& cpy):comm(new doublecomplex[cpy.len*3+100]), len(cpy.len){
100  zfft1dx(0, 1.0, 0, (int)len, 0, 1, 0, 1, comm, &info);
101  }
103  if(comm){
104  delete[] comm;
105  }
106  }
107 };
108 
110 void _fft(comp* _in, comp* _out, const size_t len, int dir, double scale){
111  doublecomplex* in = (doublecomplex*)_in;
112  doublecomplex* out = (doublecomplex*)_out;
113  static std::map<size_t, fft_plan_holder> fft_plans;
114  if(in != out && (size_t)std::abs((std::ptrdiff_t)(_in - _out)) < len){
115  err("Input arrays to fft alias each other, and are not equal", "fft", "utils/utils.cpp",
116  FATAL_ERROR);
117  }
118  if(fft_plans.count(len)==0){
119  fft_plans.insert(std::pair<size_t, fft_plan_holder>(len, fft_plan_holder(len)));
120  }
121  auto& fplan = fft_plans[len];
122  zfft1dx(dir, scale, in==out, (int)len, in, 1, out, 1, fplan.comm, &(fplan.info));
123 }
124 /*
125  * This function calculates the non-normalized forwards fourier transform of complex input data, and stores it
126  * in an output array. These arrays can point to the same location, but they must not alias in any other fashion
127  *
128  * \sa ifft
129  *
130  * @param _in array an array pointing towards the input values
131  * @param _out an array pointing towards the output locations (may be equal to input)
132  * @param len length of the arrays
133  */
134 void fft(comp* in, comp* out, const size_t len){
135  _fft(in, out, len, 1, 1.0);
136 }
137 
138 /*
139  * This function calculates the normalized backwards fourier transform of complex input data, and stores it
140  * in an output array. These arrays can point to the same location, but they must not alias in any other fashion
141  *
142  * \sa fft
143  *
144  * @param _in array an array pointing towards the input values
145  * @param _out an array pointing towards the output locations (may be equal to input)
146  * @param len length of the arrays
147  */
148 void ifft(comp* in, comp* out, const size_t len){
149  _fft(in, out, len, -1, 1.0/len);
150 }
151 
152 
153 
154 
155 
164 void trim(std::string& curline, const std::string& val){
165  size_t startpos = curline.find_first_not_of(val);
166  if(startpos != std::string::npos){
167  curline=curline.substr(startpos);
168  }
169  startpos = curline.find_last_not_of(val);
170  if(startpos != std::string::npos){
171  curline=curline.substr(0, startpos+1);
172  }
173 }
174 
175 /*
176  * Splits the input string into two at the specified delimiting character
177  * With the delimiting string " ",
178  * "relevant1 garbage" --> "relevant1", "garbage"
179  *
180  * Calling token with a string that doesn't contain the delim will result in
181  * token containing the entirety of the string and str being erased
182  *
183  * "stuffwithnospaces" -> "stuffwithnospaces", ""
184  *
185  * @param tok The string in which the left token will be placed
186  * @param str The initial string, will have the left token removed
187  * @param delim The string at which the input string is to be broken
188  */
189 void ltoken(std::string& tok, std::string& str, std::string delim){
190  size_t tpos = str.find(delim);
191  tok=str.substr(0, tpos);
192  if(tpos == std::string::npos || tpos+delim.length() >= str.size()){
193  str.clear();
194  }
195  else{
196  str.erase(0, tpos + delim.length());
197  }
198 }
199 namespace __HIDER__{
202  std::set<std::string> names;
203  public:
205  nbase.push_back('_');
206  while(names.count(nbase)){
207  nbase.push_back(1 | (char)(rand()));
208  }
209  names.insert(nbase);
210  //ensure that the name will not be alread in the engine
211  nbase.push_back('!');
212  return nbase;
213  }
215  srand(time(0));
216  }
217  };
218 }
219 
228  static __HIDER__::_unique_name nn;
229  return nn.get_unique_name(base);
230 }