Commit 82ea64f1 authored by Olivier Mullier's avatar Olivier Mullier
Browse files

ajout des fichiers source

parent d186d731
cmake_minimum_required(VERSION 2.6)
project(integrale)
#Directory of executables
set(EXECUTABLE_OUTPUT_PATH bin)
set(CMAKE_CXX_FLAGS "-Wall -O2 -frounding-math ")#-pg -fprofile-arcs -ftest-coverage
# include_directories(/usr/local/include_test/)
#
# link_directories(~/ibex/lib)
include_directories(/usr/local/include/ibex)
# include_directories(/usr/include/graphviz)
# link_directories(/usr/local/lib)
link_directories(/usr/local/lib)
#Source file list generation
file(
GLOB_RECURSE
source_files
src/*
)
#Executable declaration
add_executable(
integrale
${source_files}
)
#Libraries to add for specified target
target_link_libraries(
integrale ibex prim z m stdc++
)
#include "integrale.h"
integrale::integrale(ibex::Interval inf, ibex::Interval sup, ibex::Function* f, ibex::Variable* var) : _inf_bound(inf), _sup_bound(sup), _f(f)
{
_zeros_inf = nullptr;
_zeros_sup = nullptr;
}
std::list<zero> * integrale::construct_zeros_intern(const ibex::Interval & inf_bound)
{
#ifdef __DEBUG__
__SHOW_FCT_NAME__
#endif
//ATTENTION pas de preuve d'unicité
std::list<zero> * res = new std::list<zero>();
ibex::CtcNewton newton(*_f);
ibex::CtcFwdBwd fb (*_f);
ibex::RoundRobin bisector(0);
ibex::CellStack buff;
ibex::CtcCompo comp( fb, newton);
ibex::CtcFixPoint fix(comp, 1e-7);
ibex::Solver s(fix, bisector, buff);
ibex::IntervalVector inf(1);
inf[0] = inf_bound;
std::vector<ibex::IntervalVector> sols = s.solve(inf);
unsigned int i;
for (i = 0; i < sols.size(); i++){
//ATTENTION detection foireuse de la pente dans la cas ou [f(temp)] contient 0
ibex::IntervalVector temp(sols[i].diam());
if (i < sols.size() - 1){
for (int j = 0; j < sols[i].size(); j++){
temp[j] = (sols[i][j] + sols[i+1][j]) / 2.;
}
} else {
for (int j = 0; j < sols[i].size(); j++){
temp[j] = (sols[i][j] + inf_bound.ub()) / 2.;
}
}
if( (_f->eval_vector(temp)[0].ub() < 0.) ){
res->push_back(zero(sols[i][0], -1));
} else {
res->push_back(zero(sols[i][0], 1));
}
}
return res;
}
unsigned int integrale::construct_zeros_inf()
{
_zeros_inf = construct_zeros_intern(_inf_bound);
_zeros_inf->sort();
return _zeros_inf->size();
}
unsigned int integrale::construct_zeros_sup()
{
_zeros_sup = construct_zeros_intern(_sup_bound);
return _zeros_sup->size();
}
ibex::Interval integrale::compute_integral(const double& inf_bound, const double& sup_bound)
{
ibex::Interval res(0.0);
double current = inf_bound;
ibex::IntervalVector current_vec(1);
while (current < sup_bound){
current_vec[0] = ibex::Interval(current, current + __EPS__);
res += _f->eval_vector(current_vec)[0] *__EPS__;
current += __EPS__;
}
return res;
}
unsigned int integrale::construct_zeros()
{
return construct_zeros_inf() + construct_zeros_sup();
}
integrale_sol integrale::compute_integral(const zero& inf, const zero& sup)
{
ibex::Interval res_int = compute_integral(inf.get_x().lb(), sup.get_x().ub());
return integrale_sol(inf, sup, res_int);
}
std::pair<integrale_sol, integrale_sol> integrale::compute_integral_inf(const ibex::Interval& range)
{
std::list<integrale_sol> res_tmp;
if (!_zeros_inf){
construct_zeros_inf();
}
std::list<zero>::iterator it = _zeros_inf->begin();
zero bound_inf(ibex::Interval(range.lb()), 0);
integrale_sol integ0 = compute_integral(bound_inf, *(it));
res_tmp.push_back(integ0);
while (it != _zeros_inf->end()){
if (*it != _zeros_inf->back()){
std::list<zero>::iterator it_first = it;
it++;
std::list<zero>::iterator it_second = it;
integrale_sol integ = compute_integral(*it_first, *it_second);
for(auto elem : res_tmp){
elem+=integ;
}
res_tmp.push_back(integ);
} else {
zero bound(ibex::Interval(range.ub()), 0);
integrale_sol integ = compute_integral(*it, bound);
for(auto elem : res_tmp){
elem+=integ;
}
it++;
res_tmp.push_back(integ);
}
}
if (res_tmp.size() == 0){
cout << "Erreur, il devrait y avoir au moins une solution" << endl;
exit(EXIT_FAILURE);
}
integrale_sol min = *(res_tmp.begin());
integrale_sol max = *(res_tmp.begin());
for (auto elem : res_tmp){
if (elem.get_res_integrale().lb() < min.get_res_integrale().lb()){
min = elem;
}
if (elem.get_res_integrale().ub() > max.get_res_integrale().ub()){
max = elem;
}
}
return pair<integrale_sol, integrale_sol>(min, max);
}
std::pair<integrale_sol, integrale_sol> integrale::compute_integral_sup(const ibex::Interval& range)
{
std::list<integrale_sol> res_temp;
if (!_zeros_sup){
construct_zeros_sup();
}
std::list<zero>::iterator it = _zeros_sup->begin();
zero bound_sup(ibex::Interval(range.ub()), 0);
std::cout << "inf bound: " << *it << endl;
std::cout << "sup bound: " << bound_sup << endl;
integrale_sol integ0 = compute_integral((*it), bound_sup);
res_temp.push_back(integ0);
while (it != _zeros_sup->end()){
if (*it != _zeros_sup->back()){
std::list<zero>::iterator it_second = it;
it++;
std::list<zero>::iterator it_first = it;
// std::cout << "inf bound: " << *it_first << endl;
// std::cout << "sup bound: " << *it_second << endl;
integrale_sol integ = compute_integral(*it_first, *it_second);
for(auto elem : res_temp){
// cout << "elem : " << elem << endl;
// cout << "integ : " << integ << endl;
elem+=integ;
// cout << "new elem : " << elem << endl;
}
res_temp.push_back(integ);
} else {
zero bound(ibex::Interval(range.lb()), 0);
// std::cout << "inf bound: " << bound << endl;
// std::cout << "sup bound: " << *it << endl;
integrale_sol integ = compute_integral(bound, *it);
for(auto elem : res_temp){
// cout << "elem : " << elem << endl;
// cout << "integ : " << integ << endl;
elem+=integ;
// cout << "new elem : " << elem << endl;
}
it++;
res_temp.push_back(integ);
}
}
if (res_temp.size() == 0){
cout << "Erreur, il devrait y avoir au moins une solution" << endl;
exit(EXIT_FAILURE);
}
integrale_sol min = *(res_temp.begin());
integrale_sol max = *(res_temp.begin());
for (auto elem : res_temp){
cout << "\tcandidate : " << elem << endl;
if (elem.get_res_integrale().lb() < min.get_res_integrale().lb()){
min = elem;
}
if (elem.get_res_integrale().ub() > max.get_res_integrale().ub()){
max = elem;
}
}
return pair<integrale_sol, integrale_sol>(min, max);
}
//========================================================================
std::ostream& operator<<(std::ostream& os, const integrale& inte)
{
os << "Integral from " << inte.get_inf_bound() << " to " << inte.get_sup_bound() << " of "
<< *inte.get_f();
return os;
}
#ifndef _INTEGRALE_
#define _INTEGRALE_
#include <ibex.h>
#include <vector>
#include "zero.h"
#include "integrale_sol.h"
// #define __DEBUG__
#define __PREC__ (1e-3)
#define __EPS__ (1e-1)
#define __SHOW_FCT_NAME__ {std::cout << __func__ << std::endl;}
class integrale{
private:
ibex::Interval _inf_bound;
ibex::Interval _sup_bound;
ibex::Function * _f;
ibex::Variable * _x_var;
std::list<zero> * _zeros_inf;
std::list<zero> * _zeros_sup;
std::list<zero> * construct_zeros_intern(const ibex::Interval & inf_bound);
public:
//CONSTRUCTORS
integrale(ibex::Interval inf, ibex::Interval sup, ibex::Function * f, ibex::Variable * var);
//GETTERS
inline ibex::Interval get_inf_bound() const {return _inf_bound;};
inline ibex::Interval get_sup_bound() const {return _sup_bound;};
inline ibex::Function * get_f() const {return _f;};
inline ibex::Variable * get_x_var() const {return _x_var;};
inline std::list<zero> * get_zeros_inf(){return _zeros_inf;};
inline std::list<zero> * get_zeros_sup(){return _zeros_sup;};
unsigned int construct_zeros_inf();
unsigned int construct_zeros_sup();
unsigned int construct_zeros();
integrale_sol compute_integral(const zero & inf, const zero & sup);
std::list<ibex::Interval> compute_integral(const double & inf_bound, const ibex::Interval & sup_bound);
ibex::Interval compute_integral(const double & inf_bound, const double & sup_bound);
std::pair<integrale_sol, integrale_sol> compute_integral_inf(const ibex::Interval & range);
std::pair<integrale_sol, integrale_sol> compute_integral_sup(const ibex::Interval & range);
};
std::ostream& operator<<(std::ostream& os, const integrale& inte);
#endif //_INTEGRALE_
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2019 <copyright holder> <email>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "integrale_sol.h"
integrale_sol::integrale_sol(const zero& inf, const zero& sup, const ibex::Interval& res) : _res_integrale(res)
{
_inf = new zero(inf);
_sup = new zero(sup);
_min_candidate = false;
_max_candidate = false;
if (res.ub() < 0.){
_min_candidate = true;
}
if (res.lb() > 0.){
_max_candidate = true;
}
}
integrale_sol & integrale_sol::operator+=(const integrale_sol &rhs){
*this = *this + rhs;
return *this;
}
integrale_sol operator+(const integrale_sol& lhs, const integrale_sol& rhs)
{
if (lhs.get_sup_bound()->get_x().lb() == rhs.get_sup_bound()->get_x().lb()){
cout << "ici" << endl;
return integrale_sol(*lhs.get_inf_bound(), *rhs.get_sup_bound(), (lhs.get_res_integrale() + rhs.get_res_integrale()));
} else {
cout << "la" << endl;
return integrale_sol(*rhs.get_inf_bound(), *lhs.get_sup_bound(), (lhs.get_res_integrale() + rhs.get_res_integrale()));
}
}
std::ostream & operator<<(std::ostream& os, const integrale_sol& inte)
{
os << "Integral from (" << *(inte.get_inf_bound()) << ") to (" << *inte.get_sup_bound() << ") : " << inte.get_res_integrale();
return os;
}
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2019 <copyright holder> <email>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INTEGRALE_SOL_H
#define INTEGRALE_SOL_H
#include "zero.h"
/**
* @todo write docs
*/
class integrale_sol
{
private:
zero * _inf;
zero * _sup;
ibex::Interval _res_integrale;
bool _min_candidate;
bool _max_candidate;
public:
integrale_sol(const zero & inf, const zero & sup, const ibex::Interval & res);
inline zero * get_inf_bound() const {return _inf;};
inline zero * get_sup_bound() const {return _sup;};
inline ibex::Interval get_res_integrale() const {return _res_integrale;};
inline bool is_min_candidate(){return _min_candidate;};
inline bool is_max_candidate(){return _max_candidate;};
void set_min_candidate(bool min){_min_candidate = min;};
void set_max_candidate(bool max){_max_candidate = max;};
integrale_sol & operator+=(const integrale_sol &rhs);
};
integrale_sol operator+(const integrale_sol &, const integrale_sol &);
std::ostream& operator<<(std::ostream& os, const integrale_sol& inte_sol);
#endif // INTEGRALE_SOL_H
#include <ibex.h>
#include "integrale.h"
using namespace std;
void example(){
cout << setprecision(15);
ibex::Variable x(1);
ibex::Function f(x, ibex::sin(x));
ibex::Interval inf(0., 5.5);
ibex::Interval sup(10, 15.);
integrale example(inf, sup, &f, &x);
cout << example << endl;
example.construct_zeros();
// pair<integrale_sol, integrale_sol> res = example.compute_integral_inf(inf);
// cout << "minimum: " << res.first << endl;
// cout << "maximum: " << res.second << endl;
// for (auto elem : *(example.get_zeros_inf())){
// cout << elem << endl;
// }
cout << "======================================================" << endl;
pair<integrale_sol, integrale_sol> res2 = example.compute_integral_sup(sup);
cout << "minimum: " << res2.first << endl;
cout << "maximum: " << res2.second << endl;
for (auto elem : *(example.get_zeros_sup())){
cout << elem << endl;
}
}
int main(/*int argc, char * argv[]*/){
example();
return EXIT_SUCCESS;
}
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2019 <copyright holder> <email>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "zero.h"
ostream& operator<<(ostream& os, const zero& z)
{
if (z.is_non_zero())
os << "boundary: " << z.get_x();
else {
os << "Zero of the function: " << z.get_x() << ", derivative is ";
if (z.is_neg())
os << " negative";
else
os << " positive";
}
return os;
}
/*
* <one line to give the library's name and an idea of what it does.>
* Copyright (C) 2019 <copyright holder> <email>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ZERO_H
#define ZERO_H
#include <ibex.h>
/**
* @todo write docs
*/
class zero
{
private:
ibex::Interval _x;
int _slope;
public:
zero(const zero &z) : _x(z.get_x()), _slope(z.get_slope()){};
zero(ibex::Interval x, int slope) : _x(x), _slope(slope) {};
inline ibex::Interval get_x() const {return _x;};
inline int get_slope() const {return _slope;};
inline bool is_neg() const {return _slope < 0;};
inline bool is_pos() const {return _slope > 0;};
inline bool is_non_zero() const {return _slope == 0;};
};
inline bool operator< (const zero& lhs, const zero& rhs){ return lhs.get_x().mid() < rhs.get_x().mid(); }
inline bool operator> (const zero& lhs, const zero& rhs){ return rhs < lhs; }
inline bool operator<=(const zero& lhs, const zero& rhs){ return !(lhs > rhs); }
inline bool operator>=(const zero& lhs, const zero& rhs){ return !(lhs < rhs); }
inline bool operator==(const zero& lhs, const zero& rhs){ return lhs.get_x() == rhs.get_x(); }
inline bool operator!=(const zero& lhs, const zero& rhs){ return !(lhs == rhs); }
ostream& operator<<(ostream& os, const zero& z);
#endif // ZERO_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment