geod.mac 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan.
  3. Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program.
  4. Use, modification and distribution is subject to the Boost Software License,
  5. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. This file is converted from GeographicLib, https://geographiclib.sourceforge.io
  8. GeographicLib is originally written by Charles Karney.
  9. Author: Charles Karney (2008-2017)
  10. Last updated version of GeographicLib: 1.49
  11. Original copyright notice:
  12. Copyright (c) Charles Karney (2009-2015) <charles@karney.com> and
  13. licensed under the MIT/X11 License. For more information, see
  14. https://geographiclib.sourceforge.io
  15. Compute the series expansions for the ellipsoidal geodesic problem.
  16. References:
  17. Charles F. F. Karney,
  18. Algorithms for geodesics, J. Geodesy 87, 43-55 (2013),
  19. https://doi.org/10.1007/s00190-012-0578-z
  20. Addenda: https://geographiclib.sourceforge.io/geod-addenda.html
  21. The code below contains minor modifications to conform with
  22. Boost Geometry style guidelines.
  23. To run the code, start Maxima and enter
  24. load("geod.mac")$
  25. */
  26. taylordepth:5$
  27. ataylor(expr,var,ord):=expand(ratdisrep(taylor(expr,var,0,ord)))$
  28. jtaylor(expr,var1,var2,ord):=block([zz],expand(subst([zz=1],
  29. ratdisrep(taylor(subst([var1=zz*var1,var2=zz*var2],expr),zz,0,ord)))))$
  30. computeI1(maxpow):=block([sintegrand,sintegrandexp,s,sigma,tau1,k2,eps],
  31. sintegrand:sqrt(1+k2*sin(sigma)^2),
  32. sintegrandexp:ataylor(
  33. (1-eps)*subst([k2=4*eps/(1-eps)^2],sintegrand),
  34. eps,maxpow),
  35. s:trigreduce(integrate(sintegrandexp,sigma)),
  36. s:s-subst(sigma=0,s),
  37. A1:expand(subst(sigma=2*%pi,s)/(2*%pi)),
  38. tau1:ataylor(s/A1,eps,maxpow),
  39. for i:1 thru maxpow do C1[i]:coeff(tau1,sin(2*i*sigma)),
  40. if expand(tau1-sigma-sum(C1[i]*sin(2*i*sigma),i,1,maxpow)) # 0
  41. then error("left over terms in B1"),
  42. A1:A1/(1-eps),
  43. 'done)$
  44. codeA1(maxpow):=block([tab2:" ",tab3:" "],
  45. print("// The scale factor A1-1 = mean value of (d/dsigma)I1 - 1
  46. static inline CT evaluate_series_A1(CT eps) {
  47. CT eps2 = math::sqr(eps);
  48. CT t;
  49. switch (SeriesOrder/2) {"),
  50. for n:0 thru entier(maxpow/2) do block([
  51. q:horner(ataylor(subst([eps=sqrt(eps2)],A1*(1-eps)-1),eps2,n)),
  52. linel:1200],
  53. print(concat(tab2,"case ",string(n),":")),
  54. print(concat(tab3,"t = ",string(q),";")),
  55. print(concat(tab3,"break;"))),
  56. print(" }
  57. return (t + eps) / (1 - eps);
  58. }"),
  59. 'done)$
  60. computeI2(maxpow):=block([sintegrand,sintegrandexp,s,sigma,tau1,k2,eps],
  61. sintegrand:1/sqrt(1+k2*sin(sigma)^2),
  62. sintegrandexp:ataylor(
  63. (1+eps)*subst([k2=4*eps/(1-eps)^2],sintegrand),
  64. eps,maxpow),
  65. s:trigreduce(integrate(sintegrandexp,sigma)),
  66. s:s-subst(sigma=0,s),
  67. A2:expand(subst(sigma=2*%pi,s)/(2*%pi)),
  68. tau1:ataylor(s/A2,eps,maxpow),
  69. for i:1 thru maxpow do C2[i]:coeff(tau1,sin(2*i*sigma)),
  70. if expand(tau1-sigma-sum(C2[i]*sin(2*i*sigma),i,1,maxpow)) # 0
  71. then error("left over terms in B2"),
  72. A2:A2/(1+eps),
  73. 'done)$
  74. codeA2(maxpow):=block([tab2:" ",tab3:" "],
  75. print("// The scale factor A2-1 = mean value of (d/dsigma)I2 - 1
  76. CT evaluate_series_A2(CT const& eps)
  77. {
  78. CT const eps2 = math::sqr(eps);
  79. CT t;
  80. switch (SeriesOrder/2) {"),
  81. for n:0 thru entier(maxpow/2) do block([
  82. q:horner(ataylor(subst([eps=sqrt(eps2)],A2*(1+eps)-1),eps2,n)),
  83. linel:1200],
  84. print(concat(tab2,"case ",string(n),":")),
  85. print(concat(tab3,"t = ",string(q),";")),
  86. print(concat(tab3,"break;"))),
  87. print(" }
  88. return (t - eps) / (1 + eps);
  89. }"),
  90. 'done)$
  91. computeI3(maxpow):=block([int,intexp,dlam,eta,del,eps,nu,f,z,n],
  92. maxpow:maxpow-1,
  93. int:subst([k2=4*eps/(1-eps)^2],
  94. (2-f)/(1+(1-f)*sqrt(1+k2*sin(sigma)^2))),
  95. int:subst([f=2*n/(1+n)],int),
  96. intexp:jtaylor(int,n,eps,maxpow),
  97. dlam:trigreduce(integrate(intexp,sigma)),
  98. dlam:dlam-subst(sigma=0,dlam),
  99. A3:expand(subst(sigma=2*%pi,dlam)/(2*%pi)),
  100. eta:jtaylor(dlam/A3,n,eps,maxpow),
  101. A3:jtaylor(A3,n,eps,maxpow),
  102. for i:1 thru maxpow do C3[i]:coeff(eta,sin(2*i*sigma)),
  103. if expand(eta-sigma-sum(C3[i]*sin(2*i*sigma),i,1,maxpow)) # 0
  104. then error("left over terms in B3"),
  105. 'done)$
  106. codeA3(maxpow):=block([tab2:" ",tab3:" "],
  107. print("// The scale factor A3 = mean value of (d/dsigma)I3
  108. static inline void evaluate_series_A3(CT const& n, CT c[])
  109. {
  110. switch (SeriesOrder) {"),
  111. for nn:0 thru maxpow do block(
  112. [q:if nn=0 then 0 else
  113. jtaylor(subst([n=n],A3),n,eps,nn-1),
  114. linel:1200],
  115. print(concat(tab2,"case ",string(nn),":")),
  116. for i : 0 thru nn-1 do
  117. print(concat(tab3,"c[",i,"] = ",
  118. string(horner(coeff(q,eps,i))),";")),
  119. print(concat(tab3,"break;"))),
  120. print(" }
  121. }"),
  122. 'done)$
  123. codeC1(maxpow):=block([tab2:" ",tab3:" "],
  124. print("// The coefficients C1[l] in the Fourier expansion of B1
  125. static inline evaluate_coeffs_C1(CT eps, CT c[]) {
  126. CT eps2 = math::sqr(eps);
  127. CT d = eps;
  128. switch (SeriesOrder) {"),
  129. for n:0 thru maxpow do (
  130. print(concat(tab2,"case ",string(n),":")),
  131. for m:1 thru n do block([q:d*horner(
  132. subst([eps=sqrt(eps2)],ataylor(C1[m],eps,n)/eps^m)),
  133. linel:1200],
  134. if m>1 then print(concat(tab3,"d *= eps;")),
  135. print(concat(tab3,"c[",string(m),"] = ",string(q),";"))),
  136. print(concat(tab3,"break;"))),
  137. print(" }
  138. }"),
  139. 'done)$
  140. revertI1(maxpow):=block([tau,eps,tauacc:1,sigacc:0],
  141. for n:1 thru maxpow do (
  142. tauacc:trigreduce(ataylor(
  143. -sum(C1[j]*sin(2*j*tau),j,1,maxpow-n+1)*tauacc/n,
  144. eps,maxpow)),
  145. sigacc:sigacc+expand(diff(tauacc,tau,n-1))),
  146. for i:1 thru maxpow do C1p[i]:coeff(sigacc,sin(2*i*tau)),
  147. if expand(sigacc-sum(C1p[i]*sin(2*i*tau),i,1,maxpow)) # 0
  148. then error("left over terms in B1p"),
  149. 'done)$
  150. codeC1p(maxpow):=block([tab2:" ",tab3:" "],
  151. print("// The coefficients C1p[l] in the Fourier expansion of B1p
  152. static inline evaluate_coeffs_C1p(CT eps, CT c[])
  153. {
  154. CT const eps2 = math::sqr(eps);
  155. CT d = eps;
  156. switch (SeriesOrder) {"),
  157. for n:0 thru maxpow do (
  158. print(concat(tab2,"case ",string(n),":")),
  159. for m:1 thru n do block([q:d*horner(
  160. subst([eps=sqrt(eps2)],ataylor(C1p[m],eps,n)/eps^m)),
  161. linel:1200],
  162. if m>1 then print(concat(tab3,"d *= eps;")),
  163. print(concat(tab3,"c[",string(m),"] = ",string(q),";"))),
  164. print(concat(tab3,"break;"))),
  165. print(" }
  166. }"),
  167. 'done)$
  168. codeC2(maxpow):=block([tab2:" ",tab3:" "],
  169. print("// The coefficients C2[l] in the Fourier expansion of B2
  170. static inline void evaluate_coeffs_C2(CT const& eps, CT c[])
  171. {
  172. CT const eps2 = math::sqr(eps);
  173. CT d = eps;
  174. switch (SeriesOrder) {"),
  175. for n:0 thru maxpow do (
  176. print(concat(tab2,"case ",string(n),":")),
  177. for m:1 thru n do block([q:d*horner(
  178. subst([eps=sqrt(eps2)],ataylor(C2[m],eps,n)/eps^m)),
  179. linel:1200],
  180. if m>1 then print(concat(tab3,"d *= eps;")),
  181. print(concat(tab3,"c[",string(m),"] = ",string(q),";"))),
  182. print(concat(tab3,"break;"))),
  183. print(" }
  184. }"),
  185. 'done)$
  186. codeC3(maxpow):=block([tab2:" ",tab3:" "],
  187. print("// The coefficients C3[l] in the Fourier expansion of B3
  188. static inline void evaluate_coeffs_C3(CT const& n, CT c[])
  189. {
  190. const CT n2 = math::sqr(n);
  191. switch (SeriesOrder) {"),
  192. for nn:0 thru maxpow do block([c],
  193. print(concat(tab2,"case ",string(nn),":")),
  194. c:0,
  195. for m:1 thru nn-1 do block(
  196. [q:if nn = 0 then 0 else
  197. jtaylor(subst([n=n],C3[m]),_n,eps,nn-1),
  198. linel:1200],
  199. for j:m thru nn-1 do (
  200. print(concat(tab3,"c[",c,"] = ",
  201. string(horner(coeff(q,eps,j))),";")),
  202. c:c+1)
  203. ),
  204. print(concat(tab3,"break;"))),
  205. print(" }
  206. }"),
  207. 'done)$
  208. maxpow:8$
  209. computeI1(maxpow)$
  210. computeI2(maxpow)$
  211. computeI3(maxpow)$
  212. revertI1(maxpow)$
  213. codeA1(maxpow)$
  214. codeA2(maxpow)$
  215. codeA3(maxpow)$
  216. codeC1(maxpow)$
  217. codeC2(maxpow)$
  218. codeC3(maxpow)$
  219. codeC1p(maxpow)$