Vespucci  1.0.0
accessory.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 *******************************************************************************/
21 #include <climits>
23 
30 arma::uword Vespucci::Math::LocalMaximum(const arma::vec &X, double &value)
31 {
32  arma::sp_mat local_maxima = Vespucci::Math::LocalMaxima(X);
33  if (!local_maxima.n_nonzero){
34  value = X.max();
35  arma::uvec ind = arma::find(X == value);
36  return ind(0);
37  }
38  else{
39  value = local_maxima.max();
40  arma::uvec ind = arma::find(arma::vec(local_maxima) == value);
41  return ind(0);
42  }
43 }
44 
45 
54 arma::uword Vespucci::Math::LocalMaximum(const arma::vec &X, const arma::vec &dX, const arma::vec &d2X, double &value)
55 {
56  arma::sp_mat local_maxima = Vespucci::Math::LocalMaxima(X, dX, d2X);
57  value = local_maxima.max();
58  if (!local_maxima.n_nonzero){
59  value = X.max();
60  arma::uvec ind = arma::find(X == value);
61  return ind(0);
62  }
63  else{
64  value = local_maxima.max();
65  arma::uvec ind = arma::find(arma::vec(local_maxima) == value);
66  return ind(0);
67  }
68 
69 }
70 
77 arma::uword Vespucci::Math::LocalMinimum(const arma::mat &X, double &value)
78 {
79  arma::sp_mat local_minima = Vespucci::Math::LocalMinima(X);
80  value = local_minima.min();
81  if (!local_minima.n_nonzero){
82  value = X.max();
83  arma::uvec ind = arma::find(X == value);
84  return ind(0);
85  }
86  else{
87  value = local_minima.max();
88  arma::uvec ind = arma::find(arma::vec(local_minima) == value);
89  return ind(0);
90  }
91 
92 }
93 
94 
103 arma::uword Vespucci::Math::LocalMinimum(const arma::vec &X, const arma::vec &dX, const arma::mat &d2X, double &value)
104 {
105  arma::sp_mat local_minima = Vespucci::Math::LocalMinima(X, dX, d2X);
106  value = local_minima.min();
107  if (!local_minima.n_nonzero){
108  value = X.max();
109  arma::uvec ind = arma::find(X == value);
110  return ind(0);
111  }
112  else{
113  value = local_minima.max();
114  arma::uvec ind = arma::find(arma::vec(local_minima) == value);
115  return ind(0);
116  }
117 }
118 
119 
120 
121 
122 
123 
124 
137 arma::mat Vespucci::Math::spdiags(arma::mat B, arma::ivec d, arma::uword m, arma::uword n)
138 {
139  arma::uword i, j, k;
140  arma::uword size = B.n_cols;
141  arma::uword number = d.size();
142  arma::uword diag_size;
143  arma::uword column_size = B.n_rows;
144  arma::colvec column;
145  arma::mat output;
146  output.zeros();
147  output.set_size(m, n);
148  arma::colvec diagonal;
149  arma::ivec subdiagonals;
150  arma::ivec superdiagonals;
151 
152  if (number > size){
153  throw std::invalid_argument("spdiags: vector larger than diagonal of arma::matrix");
154  return output;
155  }
156 
157  superdiagonals = d(find (d >= 0));
158  subdiagonals = d(find (d < 0));
159 
160 
161 
162  for (i = 0; i < subdiagonals.size(); ++i){
163  k = subdiagonals(i);
164  diagonal = output.diag(k);
165  diag_size = diagonal.n_elem;
166  column = B.col(i);
167 
168  if (diag_size < column_size){
169  for (i = 0; i < diag_size; ++i){
170  output.diag(k)(i) = column(i);
171  }
172  }
173 
174  else {
175  for (i = 0; i < column_size; ++i){
176  output.diag(k)(i) = column(i);
177  }
178  }
179  }
180 
181  for (i = 0; i < superdiagonals.size(); ++i){
182  k = superdiagonals(i);
183  diag_size = output.diag(k).n_elem;
184  column = B.col(i);
185  if (diag_size < column_size){
186  j = column_size;
187  for (i = diag_size; i <=0; --i){
188  output.diag(k)(i) = column(j);
189  --j;
190  }
191  }
192 
193  else {
194  for (i = 0; i < column_size; ++i){
195  output.diag(k)(i) = column(i);
196  }
197  }
198  }
199  return output;
200 }
201 
208 arma::mat Vespucci::Math::orth(arma::mat X)
209 {
210  double eps = arma::datum::eps;
211  arma::mat U, V;
212  arma::vec s;
213  svd(U, s, V, X);
214  double tol;
215  tol = std::max(X.n_rows*s(1)*eps, X.n_cols*s(1)*eps);
216  arma::uvec q1 = find(s > tol);
217  double rank = q1.n_elem;
218 
219  if (rank > 0){
220  return -1*U.cols(0, rank-1);
221  }
222  else{
223  std::cerr << "orth: no basis found" << std::endl;
224  return arma::zeros(X.n_rows, X.n_cols);
225  }
226 }
227 
228 
229 
237 arma::uword Vespucci::Math::max(arma::uword a, arma::uword b)
238 {
239  return (a > b ? a : b);
240 }
241 
249 arma::uword Vespucci::Math::min(arma::uword a, arma::uword b)
250 {
251  return (a < b ? a : b);
252 }
253 
254 
255 
256 
257 
258 
259 arma::vec Vespucci::Math::ExtendToNextPow(arma::vec X, arma::uword n)
260 {
261  if (X.n_rows % n == 0){
262  return X;
263  }
264 
265  else{
266  arma::uword nextpow = Vespucci::Math::NextPow(X.n_rows, n);
267  arma::uword new_size = std::pow(n, nextpow);
268  arma::vec padding;
269  arma::uword extend_by = new_size - X.n_rows;
270  if (extend_by == 1){
271  padding = flipud(X.row(X.n_rows-1));
272  }
273  else{
274  padding = flipud(X.rows(X.n_rows - extend_by, X.n_rows-1));
275  }
276 
277  return join_vert(X, padding);
278  }
279 }
280 
281 arma::uword Vespucci::Math::NextPow(arma::uword number, arma::uword power)
282 {
283  return std::ceil(std::log(number) / std::log(power));
284 }
285 
293 
294 arma::sp_mat Vespucci::Math::LocalMaxima(const arma::mat &X)
295 {
296  arma::mat dX = Vespucci::Math::diff(X, 1);
297  arma::mat d2X = Vespucci::Math::diff(dX, 1);
298  //make everything line up.
299  try{
300  dX.insert_rows(0, 1, true);
301  d2X.insert_rows(0, 2, true);
302  }catch(std::exception e){
303  std::cerr << "Error in LocalMaxima with diff calc" << std::endl;
304  throw e;
305  }
306 
307  return Vespucci::Math::LocalMaxima(X, dX, d2X);
308 }
309 
317 arma::sp_mat Vespucci::Math::LocalMaxima(const arma::mat &X, const arma::mat &dX, const arma::mat &d2X)
318 {
319 
320  arma::uvec maxima_indices, extrema_indices;
321  arma::vec d2X_extrema;
322  arma::umat locations;
323  arma::vec values;
324  arma::vec extrema_buf;
325  arma::vec X_buf;
326  arma::uvec position_buf_vec;
327  arma::umat position_buf;
328 
329  for (arma::uword i = 0; i < X.n_cols; ++i){
330  X_buf = X.col(i);
331  //find where the first derivative crosses the x axis
332  try{
333  arma::vec search = (arma::conv_to<arma::vec>::from(dX.col(i).rows(0, X.n_rows - 2)) % arma::conv_to<arma::vec>::from(dX.col(i).rows(1, X.n_rows - 1)));
334  extrema_indices = arma::find(search < 0);
335  }catch(std::exception e){
336  std::cerr << "find" << std::endl;
337  throw e;
338  }
339 
340  //find the maxima that are negative in the 2nd derivative
341  try{
342  d2X_extrema = ((arma::vec) d2X.col(i)).rows(extrema_indices);
343  maxima_indices = arma::find(d2X_extrema < 0);
344  }catch(std::exception e){
345  std::cerr << "find second" << std::endl;
346  throw e;
347  }
348 
349  position_buf_vec = extrema_indices.rows(maxima_indices);
350  position_buf.set_size(2, maxima_indices.n_rows);
351  position_buf.row(0) = position_buf_vec.t();
352  position_buf.row(1).fill(i);
353 
354 
355  extrema_buf = X_buf.rows(position_buf_vec);
356  try{
357  values.insert_rows(values.n_rows, extrema_buf);
358  }catch (std::exception e){
359  std::cerr << "values.insert_rows failed" << std::endl;
360  throw e;
361  }
362  try{
363  locations.insert_cols(locations.n_cols, position_buf);
364  }catch(std::exception e){
365  std::cerr << "locations insert_Rows failed" << std::endl;
366  throw e;
367  }
368  }
369 
370  return arma::sp_mat(locations, values, X.n_rows, X.n_cols, false, false);
371 }
372 
378 arma::sp_mat Vespucci::Math::LocalMinima(const arma::mat &X)
379 {
380  arma::mat dX = Vespucci::Math::diff(X, 1);
381  arma::mat d2X = Vespucci::Math::diff(dX, 1);
382  //make everything line up.
383  try{
384  dX.insert_rows(0, 1, true);
385  d2X.insert_rows(0, 2, true);\
386  }catch(std::exception e){
387  std::cerr << "error in LocalMinima with diff calc" << std::endl;
388  throw e;
389  }
390 
391  return Vespucci::Math::LocalMinima(X, dX, d2X);
392 }
393 
401 arma::sp_mat Vespucci::Math::LocalMinima(const arma::mat &X, const arma::mat &dX, const arma::mat &d2X)
402 {
403  arma::uvec minima_indices, extrema_indices;
404  arma::vec d2X_extrema;
405  arma::umat locations;
406  arma::vec values;
407  arma::vec extrema_buf;
408  arma::vec X_buf;
409  arma::uvec position_buf_vec;
410  arma::umat position_buf;
411 
412  for (arma::uword i = 0; i < X.n_cols; ++i){
413  X_buf = X.col(i);
414  //find where the first derivative crosses the x axis
415  try{
416  arma::vec search = (arma::conv_to<arma::vec>::from(dX.col(i).rows(0, X.n_rows - 2)) % arma::conv_to<arma::vec>::from(dX.col(i).rows(1, X.n_rows - 1)));
417  extrema_indices = arma::find(search < 0);
418  }catch(std::exception e){
419  std::cerr << "find" << std::endl;
420  throw e;
421  }
422 
423  //find the extrema that are positive in the 2nd derivative
424  try{
425  d2X_extrema = ((arma::vec) d2X.col(i)).rows(extrema_indices);
426  minima_indices = arma::find(d2X_extrema > 0);
427  }catch(std::exception e){
428  std::cerr << "find second" << std::endl;
429  }
430 
431  position_buf_vec = extrema_indices.rows(minima_indices);
432  position_buf.set_size(2, minima_indices.n_rows);
433  position_buf.row(0) = position_buf_vec.t();
434  position_buf.row(1).fill(i);
435 
436 
437  extrema_buf = X_buf.rows(position_buf_vec);
438  try{
439  values.insert_rows(values.n_rows, extrema_buf);
440  }catch (std::exception e){
441  std::cerr << "values.insert_rows failed" << std::endl;
442  throw e;
443  }
444  try{
445  locations.insert_cols(locations.n_cols, position_buf);
446  }catch(std::exception e){
447  std::cerr << "locations insert_Rows failed" << std::endl;
448  throw e;
449  }
450  }
451 
452  arma::sp_mat out;
453  if (locations.n_rows !=2 || values.n_cols != locations.n_cols)
454  out = arma::sp_mat(X.n_rows, X.n_cols); //all zeros because no minima found
455  else
456  out = arma::sp_mat(locations, values, X.n_rows, X.n_cols, false, false);
457  return out;
458 }
459 
460 
469 void Vespucci::Math::position(arma::uword index, arma::uword n_rows, arma::uword n_cols, arma::uword &i, arma::uword &j)
470 {
471 
472  //first row (0) is 0 to n - 1
473  //second row (1) is n to 2n - 1
474  //third row (2) is 2n to 3n - 1,
475  //etc.
476 
477  //the row number is thus, floor(index/n);
478  //the col number is index - (row number) * n
479 
480 
481  if (index >= n_rows*n_cols)
482  throw std::invalid_argument("index out of bounds");
483  i = (arma::uword) std::floor(index / n_cols);
484  j = (arma::uword) std::floor(index - i*n_cols);
485 }
486 
487 
488 arma::umat Vespucci::Math::to_row_column(arma::uvec indices,
489  arma::uword n_rows, arma::uword n_cols)
490 {
491  arma::umat matrix_indices(indices.n_rows, 2);
492  arma::uword row, column;
493  for(arma::uword i = 0; i < indices.n_rows; ++i){
494  position(indices(i), n_rows, n_cols, row, column);
495  matrix_indices(i, 0) = row;
496  matrix_indices(i, 1) = column;
497  }
498 
499  return matrix_indices;
500 }
501 
502 
503 double Vespucci::Math::quantile(arma::vec &data, double probs)
504 {
505  if (probs > 1 || probs < 0){
506  throw std::invalid_argument("quantile: probs must be between 0 and 1");
507  }
508  if (data.n_rows < 1){
509  throw std::invalid_argument("quantile: empty input vector");
510  }
511 
512  double h = (data.n_rows - 1)*probs; //normally you'd add one here, but remember indexing starts at 0
513 
514  if (data.in_range(data.in_range(std::floor(h) && std::floor(h) + 1))){
515  return data(std::floor(h)) + (h - std::floor(h))*(data(std::floor(h) + 1) - data(std::floor(h)));
516  }
517  //current or next value is too high, so take last
518  else if ((std::floor(h) >= data.n_rows) || (std::floor(h) + 1 >= data.n_rows)){
519  return data(data.n_rows - 1);
520  }
521  else{
522  throw std::runtime_error("quantile not computed");
523  }
524 }
525 
535 double Vespucci::Math::RecalculateAverage(double new_value,
536  double old_average,
537  double old_count)
538 {
539  return ((old_average * old_count) + new_value) / (old_count + 1.0);
540 }
541 
552 double Vespucci::Math::RecalculateStdDev(double new_value,
553  double old_mean,
554  double old_stddev,
555  double old_count)
556 
557 {
558  double sum_x = old_count*old_mean + new_value;
559  double sum_squares = old_count*(std::pow(old_stddev, 2.0)
560  + std::pow(old_mean, 2.0))
561  + std::pow(new_value, 2.0);
562 
563  double new_stddev = std::sqrt(
564  ((old_count + 1.0)*sum_squares - std::pow(sum_x, 2.0))
565  / std::pow((old_count + 1.0), 2.0));
566  return new_stddev;
567 }
568 
576 arma::umat Vespucci::Math::GetClosestValues(arma::vec query,
577  arma::vec target,
578  const arma::uword k)
579 {
580  //ensure sortedness
581  if(!query.is_sorted()){query = arma::sort(query);}
582  if(!target.is_sorted()){target = arma::sort(target);}
583  arma::umat closest_indices(k, query.n_rows);
584 
585  for (arma::uword i = 0; i < query.n_rows; ++i){
586  arma::vec difference = arma::abs(target - query(i));
587  arma::uvec ind = arma::stable_sort_index(difference);
588  closest_indices.col(i) = ind.rows(0, k-1);
589  }
590  return closest_indices;
591 }
592 
599 double Vespucci::Math::CalcPoly(const double x, const arma::vec &coefs)
600 {
601  if (!coefs.n_rows){throw std::invalid_argument("coefs empty!");}
602  double y = coefs(0);
603  for (arma::uword i = 1; i < coefs.n_rows; ++i){y += coefs(i)*std::pow(x,i);}
604  return y;
605 }
606 
614 arma::vec Vespucci::Math::WavelengthToFrequency(const arma::vec &x, double freq_factor, double wl_factor)
615 {
616 
617  //convert input to meters, then Hz, then preferred wavelength
618  //nu = lambda/c
619  return (wl_factor * (1.0/arma::datum::c_0) * freq_factor) * x;
620 }
621 
629 arma::vec Vespucci::Math::FrequencyToWavelength(const arma::vec &x, double wl_factor, double freq_factor)
630 {
631  //convert input to Hz then to wavelength in meters, then to wavelength in perferred units
632  //lambda = nu * c
633  return (freq_factor * arma::datum::c_0 * wl_factor) * x;
634 }
635 
643 arma::vec Vespucci::Math::FrequencyToEnergy(const arma::vec &x, double energy_factor, double freq_factor)
644 {
645  //convert input to Hz then to energy in J, then to energy in preferred units
646  //E = h * nu
647  return (freq_factor * arma::datum::h * energy_factor) * x;
648 }
649 
657 arma::vec Vespucci::Math::EnergyToFrequency(const arma::vec &x, double freq_factor, double energy_factor)
658 {
659  //convert input to Hz then to energy in J, then to energy in preferred units
660  //nu = E/h
661  return (energy_factor * (1.0/arma::datum::h) * freq_factor) * x;
662 }
663 
671 arma::vec Vespucci::Math::WavenumberToFrequency(const arma::vec &x, double freq_factor, double wn_factor)
672 {
673  //convert input to inverse meters, then meters, then preferred units
674  arma::vec foo = x * wn_factor;
675  foo.transform( [](double val) {return (1.0/val); } );
676  return freq_factor * foo;
677 }
678 
686 arma::vec Vespucci::Math::FrequencyToWavenumber(const arma::vec &x, double wn_factor, double freq_factor)
687 {
688  //convert input to meters, then inverse meters, then preferred units
689  arma::vec foo = x * freq_factor;
690  foo.transform( [](double val) {return (1.0/val); } );
691  return wn_factor * foo;
692 }
693 
701 arma::vec Vespucci::Math::WavenumberToWavelength(const arma::vec &x, double wn_factor, double wl_factor)
702 {
703  //convert input to inverse meters, then to meters, then to preferred units
704  arma::vec foo = x * wn_factor;
705  foo.transform( [](double val) {return (1.0/val); } );
706  return wl_factor * foo;
707 }
708 
716 arma::vec Vespucci::Math::WavelengthToWavenumber(const arma::vec &x, double wl_factor, double wn_factor)
717 {
718  //convert to meters, then inverse meters, then desired units
719  arma::vec foo = wl_factor * x;
720  foo.transform( [](double val) {return (1.0/val); } );
721  return wn_factor * foo;
722 }
723 
731 arma::vec Vespucci::Math::WavelengthToEnergy(const arma::vec &x, double energy_factor, double wl_factor)
732 {
733  arma::vec foo = wl_factor * x;
734  //convert to frequency, then to energy
735  foo = Vespucci::Math::WavelengthToFrequency(foo, 1, 1);
736  return Vespucci::Math::FrequencyToEnergy(foo, energy_factor, 1);
737 }
738 
746 arma::vec Vespucci::Math::EnergyToWavelength(const arma::vec &x, double wl_factor, double energy_factor)
747 {
748  arma::vec foo = energy_factor * x;
749  foo = Vespucci::Math::EnergyToFrequency(x, 1, 1);
750  return Vespucci::Math::FrequencyToWavelength(foo, wl_factor, 1);
751 }
752 
760 arma::vec Vespucci::Math::EnergyToWavenumber(const arma::vec &x, double wn_factor, double energy_factor)
761 {
762  arma::vec foo = Vespucci::Math::EnergyToWavelength(x, 1, energy_factor);
763  return Vespucci::Math::WavelengthToWavenumber(foo, 1, wn_factor);
764 }
765 
773 arma::vec Vespucci::Math::WavenumberToEnergy(const arma::vec &x, double energy_factor, double wn_factor)
774 {
775  arma::vec foo = Vespucci::Math::WavenumberToWavelength(x, wn_factor, 1);
776  return Vespucci::Math::WavelengthToEnergy(x, energy_factor, 1);
777 }
778 
779 
780 arma::sp_mat Vespucci::Math::LocalMaximaCWT(arma::mat coefs, arma::uvec scales, arma::uword min_window_size)
781 {
782  arma::uword window_size;
783  arma::vec current_coefs;
784  arma::sp_mat local_maxima_col;
785  arma::sp_mat local_maxima(coefs.n_rows, coefs.n_cols);
786  for (arma::uword i = 0; i < scales.n_rows; ++i){
787  current_coefs = coefs.col(scales(i));
788  window_size = scales(i)*2 + 1;
789  window_size = (min_window_size < window_size ? window_size: min_window_size);
790  local_maxima.col(i) = Vespucci::Math::LocalMaximaWindow(current_coefs, window_size);
791  }
792  return local_maxima;
793 }
794 
801 arma::sp_mat Vespucci::Math::LocalMinimaWindow(const arma::mat &X, const int window_size)
802 {
803  arma::sp_mat local_mins = Vespucci::Math::LocalMinima(X);
804  //keep only the highest value in each window:
805  arma::mat local_min_col;
806  arma::uword length = std::ceil(X.n_rows/window_size);
807  arma::uword old_len = X.n_rows;
808  for (arma::uword j = 0; j < X.n_cols; ++j){
809  local_min_col = local_mins.col(j);
810  local_min_col.resize(length, window_size);
811  arma::vec lowest = arma::min(local_min_col, 1);
812  for (arma::uword i = 0; i < local_min_col.n_rows; ++i){
813  arma::uvec ind = arma::find(local_min_col.row(i) != arma::as_scalar(lowest.row(i)));
814  local_min_col.elem(ind).zeros();
815  }
816  local_min_col.resize(old_len, 1);
817  local_mins.col(j) = arma::sp_vec(local_min_col);
818  }
819 
820  return local_mins;
821 }
822 
830 arma::sp_mat Vespucci::Math::LocalMaximaWindow(const arma::mat &X, const int window_size)
831 {
832  arma::sp_mat local_maxes = Vespucci::Math::LocalMaxima(X);
833  //keep only the highest value in each window:
834  arma::mat local_max_col;
835  arma::uword length = std::ceil(X.n_rows/window_size);
836  arma::uword old_len = X.n_rows;
837  for (arma::uword j = 0; j < X.n_cols; ++j){
838  local_max_col = local_maxes.col(j);
839  local_max_col.resize(length, window_size);
840  arma::vec highest = arma::max(local_max_col, 1);
841  for (arma::uword i = 0; i < local_max_col.n_rows; ++i){
842  arma::uvec ind = arma::find(local_max_col.row(i) != arma::as_scalar(highest.row(i)));
843  local_max_col.elem(ind).zeros();
844  }
845  local_max_col.resize(old_len, 1);
846  local_maxes.col(j) = arma::sp_mat(local_max_col);
847  }
848 
849  return local_maxes;
850 }
851 
858 bool Vespucci::Math::AreEqual(const arma::vec &a, const arma::vec &b)
859 {
860  if (a.n_rows != b.n_rows){
861  return false;
862  }
863  bool equal;
864  arma::uword i = 0;
865  do{
866  equal = a(i) == b(i);
867  i++;
868  }while(equal && (i < a.n_rows));
869  return equal;
870 }
871 
877 bool Vespucci::Math::IsMonotonic(const arma::vec &x)
878 {
879  arma::vec deriv = Vespucci::Math::diff(x, 1);
880  double val = deriv(0);
881  bool equal;
882  arma::uword i = 1;
883  do{
884  equal = (deriv(i++) == val);
885  }while(equal && (i < deriv.n_rows));
886  return equal;
887 }
888 
894 bool Vespucci::Math::IsIncreasing(const arma::vec &x)
895 {
896  arma::vec deriv = Vespucci::Math::diff(x, 1);
897  arma::uword i = 0;
898  bool positive;
899  do{
900  positive = (deriv(i++) > 0);
901  }while(positive && (i < deriv.n_rows));
902  return positive;
903 }
904 
911 arma::cx_mat Vespucci::Math::cx_zeros(arma::uword m, arma::uword n)
912 {
913  return arma::cx_mat(arma::zeros(m, n), arma::zeros(m, n));
914 }
915 
921 arma::cx_vec Vespucci::Math::cx_zeros(arma::uword n)
922 {
923  return arma::cx_vec(arma::zeros(n), arma::zeros(n));
924 }
925 
932 arma::uword Vespucci::Math::ClosestIndex(double value, const arma::vec &vector)
933 {
934  double delta = std::abs(vector(1) - vector(0)); //assumes monotonic to some degree of precision
935  arma::uvec indices = arma::find(((value-delta) <= vector) && (vector <= (value+delta)));
936 
937 
938  arma::uword index;
939  if (indices.n_elem) index = indices(0);
940  else if (!indices.n_elem && value < vector.min()) index = 0;
941  else index = vector.n_elem - 1;
942 
943  return index;
944 }
945 
953 arma::vec Vespucci::Math::RepresentativeSpectrum(const arma::mat &spectra, arma::uword &index, std::string metric_name, std::string center_type)
954 {
955  arma::vec center;
956 
957  if (center_type == "centroid")
958  center = arma::mean(spectra, 1);
959  else if (center_type == "medoid")
960  center = arma::median(spectra, 1);
961  else throw std::invalid_argument("center must be either centroid or medoid");
962 
963  Vespucci::Math::DistanceMetricWrapper metric(metric_name);
964 
965  arma::vec distances(spectra.n_cols);
966 
967 #ifdef _WIN32
968  #pragma omp parallel for default(none) \
969  shared(spectra, metric, distances, center)
970  for (intmax_t i = 0; i < (intmax_t) spectra.n_cols; ++i)
971 #else
972  #pragma omp parallel for default(none) \
973  shared(spectra, metric, distances, center)
974  for (size_t i = 0; i < spectra.n_cols; ++i)
975 #endif
976  {
977  arma::vec spectrum = spectra.col(i);
978  distances(i) = metric.Evaluate(center, spectrum);
979  }
980  index = distances.index_min();
981  return spectra.col(index);
982 }
983 
990 arma::uvec Vespucci::Math::Intersection(arma::uvec &x, arma::uvec &y)
991 {
992  std::vector<arma::uword> intersection;
993  std::sort(x.begin(), x.end());
994  std::sort(y.begin(), y.end());
995  std::set_intersection(x.begin(), x.end(),
996  y.begin(), y.end(),
997  std::back_inserter(intersection));
998  return arma::conv_to<arma::uvec>::from(intersection);
999 }
1000 
1008 double Vespucci::Math::CalculateRSquared(const arma::vec &data,
1009  const arma::vec &fit,
1010  arma::vec &residuals)
1011 {
1012  residuals = data - fit;
1013  arma::vec centered = data - arma::as_scalar(arma::mean(data));
1014  double residual_sumsq = arma::accu(arma::pow(residuals, 2.0));
1015  double total_sumsq = arma::accu(arma::pow(centered, 2.0));
1016  return 1.0 - (residual_sumsq/total_sumsq);
1017 }
1018 
1029 
1030 arma::mat Vespucci::Math::SafeRows(const arma::mat &x, arma::uword a, arma::uword b)
1031 {
1032  if (a > b){
1033  arma::uword a1 = a;
1034  a = b;
1035  b = a1;
1036  }
1037  else if (a == b && a < x.n_rows) return x.row(a);
1038  else if (a < x.n_rows && b >= x.n_rows) return x.rows(a, x.n_rows - 1);
1039  else if (a < x.n_rows) return x.rows(a, b);
1040  return x.row(x.n_rows - 1);
1041 }
VESPUCCI_EXPORT arma::vec WavenumberToWavelength(const arma::vec &x, double wn_factor, double wl_factor)
Vespucci::Math::WavenumberToWavelength.
Definition: accessory.cpp:701
VESPUCCI_EXPORT arma::mat orth(arma::mat X)
orth Returns an orthonormal basis of the range space of A
Definition: accessory.cpp:208
VESPUCCI_EXPORT arma::vec WavelengthToEnergy(const arma::vec &x, double energy_factor, double wl_factor)
Vespucci::Math::WavelengthToEnergy.
Definition: accessory.cpp:731
VESPUCCI_EXPORT arma::vec EnergyToWavelength(const arma::vec &x, double wl_factor, double energy_factor)
Vespucci::Math::EnergyToWavelength.
Definition: accessory.cpp:746
VESPUCCI_EXPORT bool IsMonotonic(const arma::vec &x)
IsMonotonic.
Definition: accessory.cpp:877
VESPUCCI_EXPORT arma::sp_mat LocalMaximaWindow(const arma::mat &X, const int window_size)
Vespucci::Math::LocalMaximaWindow "Cleans" local maximum by window search to remove extraneous values...
Definition: accessory.cpp:830
VESPUCCI_EXPORT arma::vec ExtendToNextPow(arma::vec X, arma::uword n)
Definition: accessory.cpp:259
VESPUCCI_EXPORT bool AreEqual(const arma::vec &a, const arma::vec &b)
AreEqual.
Definition: accessory.cpp:858
VESPUCCI_EXPORT double RecalculateAverage(double new_value, double old_average, double old_count)
Vespucci::Math::RecalculateAverage Recalculate the average value when a new value is added to a list ...
Definition: accessory.cpp:535
VESPUCCI_EXPORT arma::uword max(arma::uword a, arma::uword b)
Vespucci::Math::max.
Definition: accessory.cpp:237
T diff(const T &X, arma::uword deriv_order=1)
Vespucci::Math::diff.
VESPUCCI_EXPORT arma::vec EnergyToFrequency(const arma::vec &x, double freq_factor, double energy_factor)
Vespucci::Math::EnergyToFrequency.
Definition: accessory.cpp:657
VESPUCCI_EXPORT arma::vec RepresentativeSpectrum(const arma::mat &spectra, arma::uword &index, std::string metric_name="euclidean", std::string center="centroid")
Vespucci::Math::RepresentativeSpectrum.
Definition: accessory.cpp:953
VESPUCCI_EXPORT arma::vec WavenumberToEnergy(const arma::vec &x, double energy_factor, double wn_factor)
Vespucci::Math::WavenumberToEnergy.
Definition: accessory.cpp:773
VESPUCCI_EXPORT double CalculateRSquared(const arma::vec &data, const arma::vec &fit, arma::vec &residuals)
Vespucci::Math::CalculateRSquared.
Definition: accessory.cpp:1008
VESPUCCI_EXPORT arma::vec WavelengthToFrequency(const arma::vec &x, double freq_factor, double wl_factor)
Vespucci::Math::WavelengthToFrequency.
Definition: accessory.cpp:614
VESPUCCI_EXPORT void position(arma::uword index, arma::uword n_rows, arma::uword n_cols, arma::uword &i, arma::uword &j)
Vespucci::Math::position Find row and column numbers for index.
Definition: accessory.cpp:469
VESPUCCI_EXPORT arma::uword LocalMinimum(const arma::mat &X, double &value)
Vespucci::Math::LocalMinimum.
Definition: accessory.cpp:77
VESPUCCI_EXPORT arma::mat spdiags(arma::mat B, arma::ivec d, arma::uword m, arma::uword n)
spdiags analgous to the Octave/arma::matLAB function A = spdiags(B, d, m, n).
Definition: accessory.cpp:137
VESPUCCI_EXPORT arma::uword LocalMaximum(const arma::vec &X, double &value)
Vespucci::Math::LocalMaximum.
Definition: accessory.cpp:30
VESPUCCI_EXPORT arma::uvec Intersection(arma::uvec &x, arma::uvec &y)
Vespucci::Math::Intersection.
Definition: accessory.cpp:990
VESPUCCI_EXPORT double RecalculateStdDev(double new_value, double old_mean, double old_stddev, double old_count)
Vespucci::Math::RecalculateStdDev Recalculate a standard deviation when a new value is added to a lis...
Definition: accessory.cpp:552
VESPUCCI_EXPORT arma::sp_mat LocalMinima(const arma::mat &X)
Vespucci::Math::LocalMinima.
Definition: accessory.cpp:378
VESPUCCI_EXPORT bool IsIncreasing(const arma::vec &x)
IsIncreasing.
Definition: accessory.cpp:894
VESPUCCI_EXPORT arma::mat SafeRows(const arma::mat &x, arma::uword a, arma::uword b)
Vespucci::Math::SafeRows.
Definition: accessory.cpp:1030
VESPUCCI_EXPORT arma::sp_mat LocalMaxima(const arma::mat &X)
Vespucci::Math::LocalMaxima.
Definition: accessory.cpp:294
double Evaluate(arma::vec &first, arma::vec &second)
Vespucci::Math::DistanceMetricWrapper::Evaluate.
VESPUCCI_EXPORT arma::vec FrequencyToEnergy(const arma::vec &x, double energy_factor, double freq_factor)
Vespucci::Math::FrequencyToEnergy.
Definition: accessory.cpp:643
VESPUCCI_EXPORT arma::vec FrequencyToWavenumber(const arma::vec &x, double wn_factor, double freq_factor)
Vespucci::Math::FrequencyToWavenumber.
Definition: accessory.cpp:686
VESPUCCI_EXPORT arma::uword min(arma::uword a, arma::uword b)
Vespucci::Math::min.
Definition: accessory.cpp:249
VESPUCCI_EXPORT arma::sp_mat LocalMinimaWindow(const arma::mat &X, const int window_size)
Vespucci::Math::LocalMinimaWindow.
Definition: accessory.cpp:801
VESPUCCI_EXPORT double CalcPoly(const double x, const arma::vec &coefs)
Vespucci::Math::CalcPoly Calculate the value of a polynomial at particular point. ...
Definition: accessory.cpp:599
VESPUCCI_EXPORT arma::vec EnergyToWavenumber(const arma::vec &x, double wn_factor, double energy_factor)
Vespucci::Math::EnergyToWavenumber.
Definition: accessory.cpp:760
VESPUCCI_EXPORT arma::sp_mat LocalMaximaCWT(arma::mat coefs, arma::uvec scales, arma::uword min_window_size)
Definition: accessory.cpp:780
VESPUCCI_EXPORT arma::uword ClosestIndex(double value, const arma::vec &vector)
Vespucci::Math::ClosestIndex.
Definition: accessory.cpp:932
VESPUCCI_EXPORT arma::uword NextPow(arma::uword number, arma::uword power)
Definition: accessory.cpp:281
VESPUCCI_EXPORT arma::umat GetClosestValues(arma::vec query, arma::vec target, const arma::uword k=5)
Vespucci::Math::GetClosestValues.
Definition: accessory.cpp:576
VESPUCCI_EXPORT arma::vec WavelengthToWavenumber(const arma::vec &x, double wl_factor, double wn_factor)
Vespucci::Math::WavelengthToWavenumber.
Definition: accessory.cpp:716
VESPUCCI_EXPORT double quantile(arma::vec &data, double probs)
Definition: accessory.cpp:503
VESPUCCI_EXPORT arma::cx_vec cx_zeros(arma::uword n)
Vespucci::Math::cx_zeros.
Definition: accessory.cpp:921
VESPUCCI_EXPORT arma::umat to_row_column(arma::uvec indices, arma::uword n_rows, arma::uword n_cols)
Definition: accessory.cpp:488
VESPUCCI_EXPORT arma::vec FrequencyToWavelength(const arma::vec &x, double wl_factor, double freq_factor)
Vespucci::Math::FrequencyToWavelength.
Definition: accessory.cpp:629
VESPUCCI_EXPORT arma::vec WavenumberToFrequency(const arma::vec &x, double freq_factor, double wn_factor)
Vespucci::Math::WavenumberToFrequency.
Definition: accessory.cpp:671