\( \def\bold#1{\bf #1} \newcommand{\d}{\mathrm{d}} \) BTP: Manual and Source Code Documentation

Power Uphill

bike mass [kg]
body mass [kg]
altitude gain [m]
climb length [km]
gradient [%]
time [s]
speed [km/h]
power [W]
power/mass [W/kg]
climbrate [m/min]

average power on climb stage

BTP  3.0
Routing/ClimbAnalysis/PowerCalculation
MathExt.cpp
1 /*Projektionsformeln und Entfernungen auf Kugelkoordinaten*/
2 
3 #include "MathExt.h"
4 
5 float distance(double lat1, double lon1, double lat2, double lon2){
6  if (lat1 == lat2 && lon1 == lon2) return 0;
7  else{
8  double aacos = cos(lat2/180*M_PI)*cos(lat1/180*M_PI)*
9  (cos((lon2-lon1)/180*M_PI))+sin(lat2/180*M_PI)
10  *sin(lat1/180*M_PI);
11  if(aacos < 1)
12  return (float) acos(aacos)*6371;
13  else
14  return 0.0;
15  }
16 }
17 double** SymMatrixtoTriang(double** m, int dim, short returnlower){
18  int i,j,k;
19  double** tl = CreateMatrix(dim,dim);
20 
21  /*Bestimme untere Dreiecksmatrix*/
22  float sum;
23  for(j = 0; j < dim; j++)
24  for(i = 0; i <=j; i++){
25  sum = 0;
26  for(k = 0;k < i; k++) sum = sum + float(tl[k][j]*tl[k][i]);
27  if(i == j){
28  if(m[i][j]-sum > 0)
29  tl[i][j] = sqrt(m[i][j]-sum);
30  else{
31  /*Sonst Error, weil Matrix nicht mit reellen Zahlen in
32  obere und untere Dreiecksmatrx aufspaltbar*/
33  DeleteMatrix(tl,dim);
34  return NULL;
35  }
36  }
37  else
38  tl[i][j] = (m[i][j]-sum)/tl[i][i];
39  }
40  if (returnlower)
41  return tl;
42  else{
43  TranspondMatrix(tl,dim);
44  return tl;
45  }
46 }
47 double** CreateMatrix(int dimx, int dimy){
48  int i,j;
49  /*Anlegen*/
50  double** t = new double*[dimx];
51  for(i = 0; i < dimx; i++)
52  t[i] = new double[dimy];
53 
54  /*mit Null inititalisieren*/
55  for(i = 0; i < dimx; i++)
56  for(j = 0; j < dimy; j++)
57  t[i][j] = 0;
58 
59  return t;
60 }
61 double** CopyMatrix(double** m, int dimx,int dimy){
62  double** t = CreateMatrix(dimx,dimy);
63  for(int i = 0; i < dimx; i++)
64  for(int j = 0; j < dimy; j++)
65  t[i][j] = m[i][j];
66  return t;
67 }
68 void DeleteMatrix(double** m, int dimx){
69  for(int i= 0; i < dimx; i++)
70  delete(m[i]);
71  delete(m);
72 }
73 void TranspondMatrix(double** m, int dim){
74  double buf;
75  int i,j;
76  for(i = 0; i < dim; i++)
77  for(j = i+1; j < dim; j++){
78  buf = m[i][j];
79  m[i][j] = m[j][i];
80  m[j][i] = buf;
81  }
82 }
83 double** MatrixMatrix(double** m1, int dim1x, int dim1y,
84  double** m2, int dim2x, int dim2y){
85  int i,j,k;
86  double** r = CreateMatrix(dim2x,dim1y);
87 
88  for(int i = 0; i < dim2x; i++)
89  for(int j = 0; j < dim1y; i++)
90  r[i][j] = 0;
91 
92  for(i = 0; i < dim2x; i++)
93  for(j = 0; j < dim1y; i++)
94  for(k = 0; k < dim1x; k++)
95  r[i][j] = r[i][j] + m1[k][j]*m2[i][k];
96 
97  return r;
98 }
99 double* SymLGS(double** A, double* y, int dim){
100  /*Ein LGS ist dann durch das Cholesky-Verfahren loesbar, wenn A positiv
101  definit ist, ansonsten gelingt die Aufspaltung in Dreiecksmatrizen nicht,
102  da komplexe Zahlen auftreten. Die allermeisten natürlichen Probleme
103  formulieren aber apriori LGS, die eine positiv definite A haben*/
104  int i;
105  double sum;
106  short error = 0;
107 
108  double* b = new double[dim];
109  double* x = new double[dim];
110 
111  /*untere Dreiecksmatrix erstellen*/
112  double** tl = SymMatrixtoTriang(A,dim,1);
113  if(tl == NULL) error++;
114 
115  if(!error)
116  /*Falls Hauptdiagonale Nullen hat, ist das LGS nicht loesbar*/
117  for(int j = 0; j < dim; j++)
118  if(tl[j][j] == 0) error++;
119 
120  if(!error){
121  /*Zwischenlösung b erstellen aus unterer Dreiecksmatrix*/
122  for(int j = 0; j < dim; j++){
123  sum = 0;
124  for(i = j-1; i >= 0; i--) sum = sum + b[i]*tl[i][j];
125  b[j] = (y[j]-sum)/tl[j][j];
126  }
127 
128  /*obere Dreiecksmatrix erstellen*/
129  TranspondMatrix(tl,dim);
130  /*Endlösung erstellen*/
131  for(int j = dim-1; j >= 0; j--){
132  sum = 0;
133  for(i = j+1; i < dim; i++) sum = sum + x[i]*tl[i][j];
134  x[j] = (b[j]-sum)/tl[j][j];
135  }
136  }
137 
138 
139  delete b;
140  if(error != 1)
141  DeleteMatrix(tl,dim);
142 
143  /*Wenn das System nicht mit Lösbar war, dann NULL ausgeben*/
144  if(error){
145  delete(x);
146  return NULL;
147  }
148  else
149  return x;
150 
151 }
152 double* FitPolynom(QPointF* p, int pointcount, int grad){
153  int i,j,xi,yi;
154  double* y = new double[grad+1];
155  for(i = 0; i <= grad; i++) y[i] = 0;
156  double** A = CreateMatrix(grad+1,grad+1);
157  double xn;
158 
159  for(i = 0; i < pointcount; i++){
160  /*Koeffizientmatrix befüllen, fuer jeden Punkt in p ...*/
161  xn = 1;
162  for(j = 0; j <= grad*2; j++){
163  xi = qMax(0,grad-j);
164  yi = 2*grad-j-xi;
165  while(xi <= grad && yi >= 0){
166  A[xi][yi] = A[xi][yi] + xn;
167  xi++;
168  yi--;
169  }
170  /*y befüllen*/
171  if(j <= grad) y[grad-j] = y[grad-j] + xn * p[i].y();
172  /*nächste Potenz vorbereiten*/
173  xn = xn*p[i].x();
174  }
175  }
176  /*LGS lösen lassen*/
177  double* x = SymLGS(A,y,grad+1);
178  DeleteMatrix(A,grad+1);
179  delete(y);
180  return x;
181 }
182 double fpln(double x, double* p, int grad){
183  double result = 0;
184  for(int k = 0; k <= grad; k++)
185  result = result + p[k]*pow(x,grad-k);
186 
187  return result;
188 }
189 
190 double upperscale(float f){
191  int i1 = 0;
192  if(f == 1) return 1;
193  if(f < 1){
194  while(pow(double(10), i1) > f) i1--;
195  }
196  else{
197  while(pow(double(10), i1) < f) i1++;
198  i1--;
199  }
200  double v = f/pow(double(10), i1);
201  if(v < 2) return pow(double(10), i1)*2;
202  if(v < 2.5) return pow(double(10), i1)*2.5;
203  if(v < 5) return pow(double(10), i1)*5;
204  else return pow(double(10), i1+1);
205 }
206 double fermi(double x, double max, double T, double x0){
207  if(T == 0)
208  T = 1e-5;
209  return max/(1+exp((x-x0)/T));
210 }
211 double lattomercator(double lat){
212  double sinlat = sin(lat/180.*M_PI);
213  if(lat > 0)
214  return 1./2.*log((1+sinlat)/(1-sinlat))*180./M_PI;
215  else
216  return 1./2.*log((1-sinlat)/(1+sinlat))*180./M_PI;
217 }
218 double mercatortolat(double mlat){
219  double explat = exp(2*mlat/180.*M_PI);
220  return asin((explat-1)/(explat+1))*180./M_PI;
221 }
222