DISPLACE  1.0
A spatial model of fisheries to help sustainable fishing and maritime spatial planning
myRutils.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // DISPLACE: DYNAMIC INDIVIDUAL VESSEL-BASED SPATIAL PLANNING
3 // AND EFFORT DISPLACEMENT
4 // Copyright (c) 2012-2019 Francois Bastardie <fba@aqua.dtu.dk>
5 
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // --------------------------------------------------------------------------
20 
21 #include <string>
22 #include <m_constants.h>
23 #include <vector>
24 #include <algorithm>
25 
26 #include <cmath>
27 
28 using namespace std;
29 
30 // source: adapted from Rmath
31 // e,g, http://svn.r-project.org/R/trunk/src/nmath/standalone/sunif.c
32 // TO DO: use a standalone compiled version of Rmath would be better...
33 void revsort(double *a, int *ib, int n);
34 // in random.c
35 void ProbSampleReplace(int n, double *p, int *perm, int nans, int *ans);
36 double unif_rand(void);
37 
38 template <typename I>
39 std::vector<I> do_sample( int n, int nval, const std::vector<I> &val, const std::vector<double> &proba)
40 {
41  using Rec = std::tuple<I, double>;
42  class RecGreater {
43  public:
44  bool operator () (const Rec&v1, const Rec&v2) const {
45  return std::get<1>(v1) > std::get<1>(v2);
46  }
47  };
48 
49  if (val.size() == 0 || proba.size() == 0 || nval == 0)
50  return vector<I>();
51 
52  if (nval != (int)val.size() || nval != (int)proba.size())
53  throw std::invalid_argument("do_sample requires nval == val.size() == proba.size()");
54 
55  double total = 0.0;
56 
57  for (auto pr : proba) {
58  total += pr;
59  }
60 
61  vector<Rec> prb;
62  for (int i = 0; i < (int)val.size(); ++i) {
63  prb.push_back(std::make_pair(val[i], proba[i]/ total));
64  }
65 
66  vector<I> res;
67  res.reserve(n);
68 
69  int nans = n;
70 
71  double rU;
72  int nm1 = nval - 1;
73 
74  /* sort the probabilities into descending order */
75  std::sort(prb.begin(), prb.end(), RecGreater());
76 
77  /* compute cumulative probabilities */
78  for (int i = 1 ; i < nval; i++) {
79  std::get<1>(prb[i]) += std::get<1>(prb[i - 1]);
80  }
81 
82  /* compute the sample */
83  for (int i = 0; i < nans; i++)
84  {
85  rU = unif_rand();
86  int j;
87  for (j = 0; j < nm1; j++)
88  {
89  if (rU <= std::get<1>(prb[j]))
90  break;
91  }
92  res.push_back(std::get<0>(prb[j]));
93  }
94  return res;
95 }
96 
97 //svn.r-project.org/R/trunk/src/nmath/
98 void set_seed(unsigned int i1, unsigned int i2);
99 void get_seed(unsigned int *i1, unsigned int *i2);
100 double exp_rand(void);
101 double fmax2(double x, double y);
102 double fmin2(double x, double y);
103 double norm_rand(void);
104 double rgamma(double a, double scale);
105 double rnorm(double mu, double sigma);
106 double rlnorm(double meanlog, double sdlog);
107 
108 // distance between two points in long lat
109 inline double dist (double x1, double y1, double x2, double y2)
110 {
111  double p = 180/M_PI;
112  double Rearth = 6371.0;
113  double res = Rearth * acos(sin(y1/p)*sin(y2/p) + (cos(y1/p) * cos(y2/p)*cos(x1/p - x2/p)));
114  return(res);
115 }
116 
117 
118 // bearing between two points in long lat
119 inline double bearing (double x1, double y1, double x2, double y2)
120 {
121  double p = 180/M_PI;
122  double res = atan2( sin((x2/p)-(x1/p))*cos(y2/p), cos(y1/p)*sin(y2/p)-sin(y1/p)*cos(y2/p)*cos((x2/p)-(x1/p)) );
123  return(res*p);
124 }
125 
126 
127 // bearing between two points in long lat
128 inline vector<double> destB (double x1, double y1, double angleAB, double distkm)
129 {
130  vector<double> res(2);
131  double p = 180/M_PI;
132  double Rearth = 6371.0;
133  // LAT
134  res[1] = asin((sin(y1/p)*cos(distkm/Rearth)) + (cos(y1/p)*sin(distkm/Rearth)*cos(angleAB/p))) ;
135  // LONG
136  res[0] = (x1/p + atan2(sin(angleAB/p)*sin(distkm/Rearth)*cos(y1/p), cos(distkm/Rearth)-sin(y1/p)*sin(res[1])) ) ;
137  res[1] = res[1] *p;
138  res[0] = res[0] *p;
139  return(res);
140 }
141 
142 
143 inline vector <double> compute_line_equation (double x1, double x2, double y1, double y2)
144 {
145  vector <double> res(2);
146  double dx = x2 - x1;
147  double dy = y2 - y1;
148  res[0] = dy / dx; //slope
149  res[1] = y1 - res[0] * x1; // intercept
150  return(res);
151 }
152 
153 
154 // is a point lying inside a segment
155 inline int is_pt_lying_on_segment (double x1, double x2, double x3, double y1, double y2, double y3)
156 {
157  vector <double> equ = compute_line_equation(x1,x2,y1,y2);
158  double left, right, top, bottom;
159 
160  if(x1 < x2)
161  {
162  left = x1;
163  right = x2;
164  }
165  else
166  {
167  left = x2;
168  right = x1;
169  }
170  if(y1 < y2)
171  {
172  top = y1;
173  bottom = y2;
174  }
175  else
176  {
177  top = y1;
178  bottom = y2;
179  }
180 
181  //test
182  if( equ[0] * x3 + equ[1] > (y3 - 0.01) &&
183  equ[0] * x3 + equ[1] < (y3 + 0.01))
184  {
185  if( x3 > left && x3 < right &&
186  y3 > top && y3 < bottom )
187  {
188  return(1);
189  }
190  else
191  {
192  return(0);
193  }
194  }
195  else
196  {
197  return(0);
198  }
199 
200 }
std::vector< I > do_sample(int n, int nval, const std::vector< I > &val, const std::vector< double > &proba)
Definition: myRutils.h:39
void set_seed(unsigned int i1, unsigned int i2)
Definition: myRutils.cpp:46
double dist(double x1, double y1, double x2, double y2)
Definition: myRutils.h:109
double norm_rand(void)
Definition: myRutils.cpp:363
int is_pt_lying_on_segment(double x1, double x2, double x3, double y1, double y2, double y3)
Definition: myRutils.h:155
void ProbSampleReplace(int n, double *p, int *perm, int nans, int *ans)
Definition: myRutils.cpp:142
void revsort(double *a, int *ib, int n)
Definition: myRutils.cpp:72
Definition: pathshop.cpp:8
double unif_rand(void)
Definition: myRutils.cpp:60
double fmax2(double x, double y)
Definition: myRutils.cpp:329
double exp_rand(void)
Definition: myRutils.cpp:269
double fmin2(double x, double y)
Definition: myRutils.cpp:339
double rgamma(double a, double scale)
Definition: myRutils.cpp:504
double rlnorm(double meanlog, double sdlog)
Definition: myRutils.cpp:691
#define M_PI
Definition: m_constants.h:26
vector< double > destB(double x1, double y1, double angleAB, double distkm)
Definition: myRutils.h:128
vector< double > compute_line_equation(double x1, double x2, double y1, double y2)
Definition: myRutils.h:143
double bearing(double x1, double y1, double x2, double y2)
Definition: myRutils.h:119
void get_seed(unsigned int *i1, unsigned int *i2)
Definition: myRutils.cpp:53
double rnorm(double mu, double sigma)
Definition: myRutils.cpp:685