Alexandria  2.16
Please provide a description of the project.
Cumulative.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2020 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
26 #include <cstdlib> // for size_t
28 #include "XYDataset/XYDataset.h"
29 
30 namespace Euclid {
31 namespace MathUtils {
32 
33 
34  Cumulative::Cumulative ( Cumulative && other):m_x_sampling(std::move(other.m_x_sampling)), m_y_sampling(std::move(other.m_y_sampling)){}
35 
37  m_x_sampling=std::move(other.m_x_sampling);
38  m_y_sampling=std::move(other.m_y_sampling);
39  return *this;
40  }
41 
42  Cumulative::Cumulative ( const Cumulative & other) : m_x_sampling(other.m_x_sampling), m_y_sampling(other.m_y_sampling){}
43 
47  return *this;
48  }
49 
50  Cumulative::Cumulative(std::vector<double>& x_sampling, std::vector<double>& y_sampling): m_x_sampling(x_sampling), m_y_sampling(y_sampling){
51  if (x_sampling.size()!=y_sampling.size()){
52  throw Elements::Exception("Cumulative: X and Y sampling do not have the same length.");
53  }
54  }
55 
56 
57  Cumulative::Cumulative(const XYDataset::XYDataset & sampling): m_x_sampling{}, m_y_sampling{} {
58 
59  auto iter = sampling.begin();
60  while (iter != sampling.end()) {
61  m_x_sampling.push_back((*iter).first);
62  m_y_sampling.push_back((*iter).second);
63  ++iter;
64  }
65  }
66 
67 
68 
72  auto iter = sampling.begin();
73  while (iter != sampling.end()) {
74  xs.push_back((*iter).first);
75  ys.push_back((*iter).second);
76  ++iter;
77  }
78  return Cumulative::fromPdf(xs, ys);
79  }
80 
81 
83  double total = 0.;
84  std::vector<double> cumul{};
85  auto iter_pdf = pdf_sampling.cbegin();
86 
87  while (iter_pdf != pdf_sampling.cend()) {
88  total += *(iter_pdf);
89  cumul.push_back(total);
90  ++iter_pdf;
91  }
92 
93  return Cumulative(x_sampling, cumul);
94  }
95 
96 
98  double total = m_y_sampling.back();
99  std::vector<double> cumul{};
100  auto iter=m_y_sampling.begin();
101  while( iter!=m_y_sampling.end()){
102  cumul.push_back(*iter/total);
103  ++iter ;
104  }
105 
106  m_y_sampling=std::move(cumul);
107  }
108 
109 
110  double Cumulative::findValue(double ratio, TrayPosition position) const{
111  if (ratio>1. || ratio<0.){
112  throw Elements::Exception("Cumulative::findValue : ratio parameter must be in range [0,1]");
113  }
114  double value = m_y_sampling.back()*ratio;
115  auto iter_x = m_x_sampling.cbegin();
116  auto iter_y = m_y_sampling.cbegin();
117  while (iter_y!=m_y_sampling.cend() && (*iter_y)<value){
118  ++iter_x;
119  ++iter_y;
120  }
121  double begin = *iter_x;
122  double tray = *iter_y;
123  while (iter_y!=m_y_sampling.cend() && (*iter_y)==tray){
124  ++iter_x;
125  ++iter_y;
126  }
127 
128  double end = *(--iter_x);
129 
130  double result = 0;
131  switch(position) {
132  case TrayPosition::begin: result = begin; break;
133  case TrayPosition::middle: result = 0.5*(begin + end); break;
134  case TrayPosition::end: result = end; break;
135  }
136 
137  return result;
138  }
139 
140 
142 
143 
144  if (rate>1. || rate<=0.){
145  throw Elements::Exception("Cumulative::findMinInterval : rate parameter must be in range ]0,1]");
146  }
147 
148  rate *= m_y_sampling.back();
149 
150  double first_correction = m_y_sampling.front();
151 
152  auto iter_1_x = m_x_sampling.cbegin();
153  auto iter_2_x = ++(m_x_sampling.cbegin());
154  auto iter_1_y = m_y_sampling.cbegin();
155  auto iter_2_y = ++(m_y_sampling.cbegin());
156  auto min_x = m_x_sampling.cbegin();
157  auto max_x= --(m_x_sampling.cend());
158  while (iter_1_x!= m_x_sampling.cend()){
159  while (iter_2_x!= m_x_sampling.cend() && (*iter_2_y-*iter_1_y + first_correction)<rate){
160  ++iter_2_x;
161  ++iter_2_y;
162  }
163  if (iter_2_x == m_x_sampling.cend()){
164  break;
165  }
166  if ( (*iter_2_x - *iter_1_x) <= (*max_x - *min_x)){
167  max_x = iter_2_x;
168  min_x = iter_1_x;
169  }
170  ++iter_1_x;
171  ++iter_1_y;
172  first_correction=0.;
173  }
174 
175  return std::make_pair(*min_x, *max_x);
176 
177  }
178 
179 
181  if (rate>1. || rate<=0.){
182  throw Elements::Exception("Cumulative::findCenteredInterval : rate parameter must be in range ]0,1]");
183  }
184 
185  double min_rate = 0.5 - rate/2.0;
186  double max_rate = 0.5 + rate/2.0;
187 
188  double min_x = findValue(min_rate, TrayPosition::end);
189  double max_x = findValue(max_rate, TrayPosition::begin);
190 
191  return std::make_pair(min_x, max_x);
192  }
193 
194 } // MathUtils namespace
195 }
196 
197 
TrayPosition
when looking for the position having a given value, one may encounter tray where the value is constan...
Definition: Cumulative.h:51
std::vector< double > m_x_sampling
Definition: Cumulative.h:154
Class for build cumulative from PDF and extract feature out of it.
Definition: Cumulative.h:41
T front(T... args)
const_iterator end() const
Returns a const iterator to the one after last pair dataset.
Definition: XYDataset.cpp:42
static Cumulative fromPdf(std::vector< double > &x_sampling, std::vector< double > &pdf_sampling)
Factory from the sampling of a PDF. The Cumulative vertical samples are build as the sum of the the p...
Definition: Cumulative.cpp:82
STL namespace.
std::vector< double > m_y_sampling
Definition: Cumulative.h:155
T cend(T... args)
Cumulative & operator=(Cumulative &&other)
move assignation operator
Definition: Cumulative.cpp:36
void normalize()
Normalize the Cumulative. After calling this function the last vertical value is 1.0.
Definition: Cumulative.cpp:97
double findValue(double ratio, TrayPosition position=TrayPosition::middle) const
Find the first horizontal sample which vertical value is bigger or equal to the ratio value...
Definition: Cumulative.cpp:110
std::pair< double, double > findMinInterval(double rate) const
Scan the horizontal axis looking for the smallest x-interval for which the vertical interval is at le...
Definition: Cumulative.cpp:141
T make_pair(T... args)
T move(T... args)
T size(T... args)
T cbegin(T... args)
std::pair< double, double > findCenteredInterval(double rate) const
return the horizontal interval starting where the Cumulative has value (1-ratio)/2 and ending where t...
Definition: Cumulative.cpp:180
Cumulative(Cumulative &&other)
move constructor
Definition: Cumulative.cpp:34
This module provides an interface for accessing two dimensional datasets (pairs of (X...
Definition: XYDataset.h:59
T back(T... args)
const_iterator begin() const
Returns a const iterator to the first pair of the dataset.
Definition: XYDataset.cpp:38