Vespucci  1.0.0
fft.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright (C) 2014-2016 Wright State University - All Rights Reserved
3  Daniel P. Foose - Maintainer/Lead Developer
4 
5  This file is part of Vespucci.
6 
7  Vespucci is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  Vespucci is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with Vespucci. If not, see <http://www.gnu.org/licenses/>.
19 *******************************************************************************/
20 #include <Math/Transform/fft.h>
29 void Vespucci::Math::Transform::fft_mat(const arma::mat &t_signal,
30  const arma::vec &t_abscissa,
31  arma::cx_mat &f_signal,
32  arma::vec &f_abscissa,
33  arma::uword n)
34 {
35  //we transform dt into df
36  arma::vec df = Vespucci::Math::diff(t_abscissa, 1);
37  arma::rowvec new_row = {df(0)};
38  df.insert_rows(0, new_row);
39 
40  //df = 1.0/(n*dt)
41  df = n*df;
42  df.transform([](double val){return 1.0/val;});
43 
44  //abs(k) = k*df
45  f_abscissa = arma::linspace(1, df.n_rows+1, df.n_rows) % df;
46 
47  //truncate or extend abscissa so it has size n
48  if (f_abscissa.n_rows > n)
49  f_abscissa = f_abscissa.rows(0, n-1);
50  if (f_abscissa.n_rows < n){
51  double last_df = df(df.n_rows - 1);
52  double last_abs = f_abscissa(f_abscissa.n_rows - 1);
53  arma::uword rows_to_add = n - f_abscissa.n_rows;
54  arma::vec abs_end = arma::linspace(last_abs + last_df,
55  last_abs + (rows_to_add*last_df),
56  rows_to_add);
57  f_abscissa = arma::join_vert(f_abscissa, abs_end);
58  }
59 
60 
61  f_signal = arma::fft(t_signal, n);
62 }
63 
72 void Vespucci::Math::Transform::ifft_mat(const arma::cx_mat &f_signal,
73  const arma::vec f_abscissa,
74  arma::cx_mat &t_signal,
75  arma::vec &t_abscissa,
76  arma::uword n)
77 {
78 
79  //we transform df into dt
80  arma::vec dt = Vespucci::Math::diff(f_abscissa, 1); //==df
81  arma::rowvec new_row = {dt(0)}; //insert so we have dt for the first value
82  dt.insert_rows(0, new_row);
83 
84  //dt = 1.0/(n*df)
85  dt = n * dt;
86  dt.transform([](double val){return 1.0/val;});
87 
88  //abs(k) = k*dt
89  t_abscissa = arma::linspace(1, dt.n_rows+1, dt.n_rows) % dt;
90 
91 
92 
93  //truncate or pad abscissa to match size of spectra
94  if (t_abscissa.n_rows > n)
95  t_abscissa = t_abscissa.rows(0, n-1);
96  if (t_abscissa.n_rows < n){
97  double last_dt = dt(dt.n_rows - 1);
98  double last_abs = t_abscissa(t_abscissa.n_rows - 1);
99  arma::uword rows_to_add = n - t_abscissa.n_rows;
100  arma::vec abs_end = arma::linspace(last_abs + last_dt,
101  last_abs + (rows_to_add*last_dt),
102  rows_to_add);
103  t_abscissa = arma::join_vert(t_abscissa, abs_end);
104  }
105  t_signal = arma::ifft(f_signal, n);
106 
107 
108 
109 }
110 
119 arma::mat Vespucci::Math::Transform::ApplyWeights(const arma::mat &signal,
120  const arma::vec &abscissa,
121  const std::string &weight,
122  const double &param)
123 {
124  arma::vec weights;
125  if (weight == "gaus"){
126  double coef = -1 * std::pow(param, 2.0);
127  weights = (coef * arma::pow(abscissa, 2.0)) / 2;
128  }
129  else if (weight == "exp"){
130  weights = arma::exp(-1*param*abscissa);
131  }
132  else{
133  throw std::runtime_error("Unsupported value of weight");
134  }
135  arma::mat weighted_signal(signal.n_rows, signal.n_cols);
136  for (arma::uword i = 0; i < signal.n_cols; ++i)
137  weighted_signal.col(i) = signal.col(i) % weights;
138  return weighted_signal;
139 }
140 
150 arma::mat Vespucci::Math::Transform::ApplySBWeights(const arma::mat &signal,
151  const arma::vec &abscissa,
152  const double &starting_offset,
153  const double &ending_offset,
154  const double &power)
155 {
156  arma::vec weights;
157 
158  //what is in front of the equation (one over the denominator)
159  double out_coef = 1.0/(abscissa.n_rows - 1);
160 
161  //what the time is multiplied by
162  double coef = arma::datum::pi * (starting_offset - ending_offset);
163 
164  //what is added to coef*time
165  arma::vec offset = arma::datum::pi * starting_offset * arma::ones(abscissa.n_rows);
166  weights = arma::pow(arma::sin(out_coef*(offset+(coef*abscissa))), power);
167 
168  arma::mat weighted_signal(signal.n_rows, signal.n_cols);
169  for (arma::uword i = 0; i < signal.n_cols; ++i)
170  weighted_signal.col(i) = signal.col(i) % weights;
171  return weighted_signal;
172 }
VESPUCCI_EXPORT arma::mat ApplyWeights(const arma::mat &signal, const arma::vec &abscissa, const std::string &weight, const double &param)
Vespucci::Math::Transform::ApplyWeights.
Definition: fft.cpp:119
T diff(const T &X, arma::uword deriv_order=1)
Vespucci::Math::diff.
VESPUCCI_EXPORT void ifft_mat(const arma::cx_mat &f_signal, const arma::vec f_abscissa, arma::cx_mat &t_signal, arma::vec &t_abscissa, arma::uword n)
Vespucci::Math::Transform::ifft_mat.
Definition: fft.cpp:72
VESPUCCI_EXPORT arma::mat ApplySBWeights(const arma::mat &signal, const arma::vec &abscissa, const double &starting_offset, const double &ending_offset, const double &power)
Vespucci::Math::Transform::ApplyWeights.
Definition: fft.cpp:150
VESPUCCI_EXPORT void fft_mat(const arma::mat &t_signal, const arma::vec &t_abscissa, arma::cx_mat &f_signal, arma::vec &f_abscissa, arma::uword n)
Vespucci::Math::Transform::fft_mat.
Definition: fft.cpp:29