File: almanac.m

package info (click to toggle)
octave-mapping 1.4.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,132 kB
  • sloc: objc: 1,860; python: 438; cpp: 219; makefile: 87; xml: 37; sh: 4
file content (142 lines) | stat: -rw-r--r-- 5,349 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
## Copyright (C) 2022 Philip Nienhuis
##
## 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 <https://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn {} {@var{retval} =} almanac ()
## @deftypefnx {} {@var{retval} =} almanac (@var{body})
## @deftypefnx {} {@var{retval} =} almanac (@var{body}, @var{param})
## @deftypefnx {} {@var{retval} =} almanac (@var{body}, @var{param}, @var{unit})
## Return basic info about one parameter of a celestial body.
##
## The celestial bodies and parameters that almanac can return are shown when
## invoking almanac without any parameters.
##
## Input parameters:
##
## @itemize
## @item @var{body} - celestial body for which info is requested
## (case-insensitive).
##
## @item @var{param} (optional) - the selected parameter whose value is
## requested.  If 'geoid' or 'ellipsoid' is specified a 1x2 vector comprising
## the semimajor axis and eccentricity of @var{body} is returned.  If 'Earth'
## is selected, a specific geoid name can be specified and the semimajor
## axis and eccentricity of that geoid are returned.
##
## @item @var{unit} (optional) - the unit in which the requested parameter is
## expressed.  Any unit recognized by function 'unitsratio' is accepted.
## @end itemize
##
## almamanc is merely a wrapper around, resp. based on, referenceEllipsoid.
##
## @seealso{referenceEllipsoid,referenceSphere,unitsratio}
## @end deftypefn

function retval = almanac (varargin)

  persistent a geoids;
  outerbodies = {"Sun", "Mercury", "Venus", "Moon", "Mars", "Jupiter", ...
                 "Saturn", "Neptune", "Uranus", "Pluto", "Unit Sphere"};
  unit = "meter";
  if (isempty (a) || isempty (geoids))
    a = referenceEllipsoid (0);
    geoids = setdiff (a(:, 3), [outerbodies {"Earth"}])';
  endif

  if (nargin == 0)
    ## Return info on celestial bodies
    if (nargout == 0)
      printf (["Implemented celestial bodies:\nSun\nMercury\nVenus\n", ...
               "Earth\nMoon\nMars\n\Jupiter\nSaturn\nNeptune\nUranus\n", ...
               "Pluto\nUnit Sphere\n"]);
    else
      retval = [outerbodies(1:3) {"Earth"} outerbodies(4:end)];
    endif

  elseif (nargin > 0 && ! iscellstr (varargin))
    error ("almanac: all input args should be text strings.");

  elseif (nargin == 1)
    ## Return info on parameters of a specific celestial body
    if (strcmpi (varargin{1}, 'earth'))
      printf ("Parameters for Earth:\n   ", varargin{1});
      printf (["radius, geoid, volume, surfacearea, or one of geoids ", ...
               "listed below.\nUnits:\n   degrees (deg), kilometers ", ... 
               "(km), nautical miles (nm), radians (rad) or statute ", ...
               "miles (sm)\nReference bodies:\n   sphere, geoid or actual\n"]);
      idx = find (! ismember (a(:, 3), [outerbodies {"Earth"}]));
      printf ("Available geoids:\n   %s\n", ...
       strjoin (cellfun (@(x) sprintf ("'%s'", x), a(idx, 3), "uni", 0), ", "));
    elseif (ismember (varargin{1}, lower (outerbodies)))
      printf ("Parameters for %s:\n   ", varargin{1});
      printf (["radius, geoid, volume or surfacearea.\nUnits:\n   degrees ", ...
               "(deg), kilometers (km), nauticalmiles (nm), radians (rad) ", ...
               "or statutemiles (sm)\nReference bodies:\n   sphere, geoid ", ... 
               "or actual\n"]);
    else
      error ("almanac: unknown celestial body.");
    end
    if (nargout > 0)
      retval = [];
    endif

  elseif (nargin >= 2)
    ## Return info on a specific celestial body with units
    param = varargin{2};
    if (nargin > 2)
      unit = varargin{3};
    endif
    idx = find (strncmpi (param, geoids, numel (param)));
    if (! isempty (idx))
      b = referenceEllipsoid (geoids{idx(1)}, unit);
      retval = [b.SemimajorAxis, b.Eccentricity];
    else
      b = referenceEllipsoid (varargin{1}, unit);
      switch lower (param)
        case "radius"
          retval = b.MeanRadius;
        case "volume"
          retval = b.Volume;
        case {"surfarea", "surfacearea"}
          retval = b.SurfaceArea;
        case {"geoid", "ellipsoid"}
          retval = [b.SemimajorAxis, b.Eccentricity];
        otherwise
          error ("almanac: unknown parameter requested - %s", param);
      endswitch
    endif

  endif

endfunction


%!test
%! assert (strcmpi (almanac (){1}, "Sun"), true);
%! assert (strcmpi (almanac (){12}, "Unit Sphere"), true);

%!test
%! assert (almanac ("sun", "radius", "sm"), 432285.77700111, 1e-6);

%!test
%! assert (almanac ("earth", "everest", "nm"), [3443.456768421318, 0.0814729809], 1e-9);

%!test
%! assert (almanac  ("jupiter", "ellipsoid", "km"), [71492.0   0.3543164], 1e-7);

%!error <unknown> almanac ("UFO")
%!error <all input args> almanac ("Moon", 12)
%!error <unknown parameter> almanac ("Mars", "flattening")