Averages/Mean angle: Difference between revisions

m
(→‎{{header|jq}}: special handling of x == 0)
m (→‎{{header|Wren}}: Minor tidy)
 
(86 intermediate revisions by 50 users not shown)
Line 1:
[[Category:Geometry]]
{{task}}
 
When calculating the [[wp:Mean of circular quantities|average or mean of an angle]] one has to take into account how angles wrap around so that any angle in degrees plus any integer multiple of 360 degrees is a measure of the same angle.
 
Line 9 ⟶ 11:
# Convert the complex mean to polar coordinates whereupon the phase of the complex mean is the required angular mean.
 
<br>
(Note that, since the mean is the sum divided by the number of numbers, and division by a positive real number does not affect the angle, you can also simply compute the sum for step 2.)
 
You can alternatively use this formula:
 
: Given the angles <math>\alpha_1,\dots,\alpha_n</math> the mean is computed by
 
::<math>\bar{\alpha} = \operatorname{atan2}\left(\frac{1}{n}\cdot\sum_{j=1}^n \sin\alpha_j, \frac{1}{n}\cdot\sum_{j=1}^n \cos\alpha_j\right) </math>
 
;Task
The task is to:
# write a function/method/subroutine/... that given a list of angles in degrees returns their mean angle. (You should use a built-in function if you have one that does this for degrees or radians).
# Use the function to compute the means of these lists of angles (in degrees): [350, 10], [90, 180, 270, 360], [10, 20, 30]; and show your output here.
 
# write a function/method/subroutine/... that given a list of angles in degrees returns their mean angle. <br> (You should use a built-in function if you have one that does this for degrees or radians).
;See Also
# Use the function to compute the means of these lists of angles (in degrees):
* [[Averages/Mean time of day]]
#* &nbsp; [350, 10]
#* &nbsp; [90, 180, 270, 360]
#* &nbsp; [10, 20, 30]
# Show your output here.
 
{{task heading|See also}}
 
{{Related tasks/Statistical measures}}
 
<br><hr>
 
=={{header|11l}}==
{{trans|C#}}
<syntaxhighlight lang="11l">F mean_angle(angles)
V x = sum(angles.map(a -> cos(radians(a)))) / angles.len
V y = sum(angles.map(a -> sin(radians(a)))) / angles.len
R degrees(atan2(y, x))
 
print(mean_angle([350, 10]))
print(mean_angle([90, 180, 270, 360]))
print(mean_angle([10, 20, 30]))</syntaxhighlight>
{{out}}
<pre>
-1.61481e-15
-90
20
</pre>
 
=={{header|Ada}}==
An implementation based on the formula using the "Arctan" (atan2) function, thus avoiding complex numbers:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Numerics.Generic_Elementary_Functions;
 
procedure Mean_Angles is
Line 59 ⟶ 87:
Put(Mean_Angle((10.0, 350.0))); Ada.Text_IO.New_Line; -- 0.00
Put(Mean_Angle((90.0, 180.0, 270.0, 360.0))); -- Ada.Numerics.Argument_Error!
end Mean_Angles;</langsyntaxhighlight>
{{out}}
<pre> 20.00
Line 65 ⟶ 93:
 
raised ADA.NUMERICS.ARGUMENT_ERROR : a-ngelfu.adb:427 instantiated at mean_angles.adb:17</pre>
 
=={{header|Aime}}==
<syntaxhighlight lang="aime">real
mean(list l)
{
integer i;
real x, y;
 
x = y = 0;
 
i = 0;
while (i < l_length(l)) {
x += Gcos(l[i]);
y += Gsin(l[i]);
i += 1;
}
 
return Gatan2(y / l_length(l), x / l_length(l));
}
 
integer
main(void)
{
o_form("mean of 1st set: /d6/\n", mean(l_effect(350, 10)));
o_form("mean of 2nd set: /d6/\n", mean(l_effect(90, 180, 270, 360)));
o_form("mean of 3rd set: /d6/\n", mean(l_effect(10, 20, 30)));
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>mean of 1st set: -.000000
mean of 2nd set: -90
mean of 3rd set: 19.999999</pre>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68|Revision 1}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.8.3 algol68g-2.8.3].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
{{trans|C|Note: This specimen retains the original [[#C|C]] coding style}}
'''File: Averages_Mean_angle.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
 
PROC mean angle = ([]#LONG# REAL angles)#LONG# REAL:
(
INT size = UPB angles - LWB angles + 1;
#LONG# REAL y part := 0, x part := 0;
FOR i FROM LWB angles TO UPB angles DO
x part +:= #long# cos (angles[i] * #long# pi / 180);
y part +:= #long# sin (angles[i] * #long# pi / 180)
OD;
#long# arc tan2 (y part / size, x part / size) * 180 / #long# pi
);
main:
(
[]#LONG# REAL angle set 1 = ( 350, 10 );
[]#LONG# REAL angle set 2 = ( 90, 180, 270, 360);
[]#LONG# REAL angle set 3 = ( 10, 20, 30);
FORMAT summary fmt=$"Mean angle for "g" set :"-zd.ddddd" degrees"l$;
printf ((summary fmt,"1st", mean angle (angle set 1)));
printf ((summary fmt,"2nd", mean angle (angle set 2)));
printf ((summary fmt,"3rd", mean angle (angle set 3)))
)</syntaxhighlight>{{out}}
<pre>
Mean angle for 1st set : -0.00000 degrees
Mean angle for 2nd set :-90.00000 degrees
Mean angle for 3rd set : 20.00000 degrees
</pre>
 
=={{header|AutoHotkey}}==
{{works with|AutoHotkey 1.1}}
<langsyntaxhighlight AutoHotkeylang="autohotkey">Angles := [[350, 10], [90, 180, 270, 360], [10, 20, 30]]
MsgBox, % MeanAngle(Angles[1]) "`n"
. MeanAngle(Angles[2]) "`n"
Line 84 ⟶ 182:
atan2(x, y) {
return dllcall("msvcrt\atan2", "Double",y, "Double",x, "CDECL Double")
}</langsyntaxhighlight>
'''Output:'''
<pre>-0.000000
Line 91 ⟶ 189:
 
=={{header|AWK}}==
<langsyntaxhighlight AWKlang="awk">#!/usr/bin/awk -f
{
PI = atan2(0,-1);
Line 103 ⟶ 201:
if (p<0) p += 360;
print p;
}</langsyntaxhighlight>
<pre> echo 350 10 | ./mean_angle.awk
360
Line 113 ⟶ 211:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> *FLOAT 64
DIM angles(3)
angles() = 350,10
Line 132 ⟶ 230:
DEF FNatan2(y,x) : ON ERROR LOCAL = SGN(y)*PI/2
IF x>0 THEN = ATN(y/x) ELSE IF y>0 THEN = ATN(y/x)+PI ELSE = ATN(y/x)-PI</langsyntaxhighlight>
{{out}}
<pre>
Line 141 ⟶ 239:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include<math.h>
#include<stdio.h>
 
Line 170 ⟶ 268:
printf ("\nMean Angle for 3rd set : %lf degrees\n", meanAngle (angleSet3, 3));
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>Mean Angle for 1st set : -0.000000 degrees
Mean Angle for 2nd set : -90.000000 degrees
Mean Angle for 3rd set : 20.000000 degrees</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
using System.Linq;
using static System.Math;
class Program
{
static double MeanAngle(double[] angles)
{
var x = angles.Sum(a => Cos(a * PI / 180)) / angles.Length;
var y = angles.Sum(a => Sin(a * PI / 180)) / angles.Length;
return Atan2(y, x) * 180 / PI;
}
static void Main()
{
Action<double[]> printMean = x => Console.WriteLine("{0:0.###}", MeanAngle(x));
printMean(new double[] { 350, 10 });
printMean(new double[] { 90, 180, 270, 360 });
printMean(new double[] { 10, 20, 30 });
}
}</syntaxhighlight>
{{out}}
<pre>0
-90
20</pre>
 
=={{header|C++}}==
{{trans|C#}}
<syntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
#include <vector>
 
#define _USE_MATH_DEFINES
#include <math.h>
 
template<typename C>
double meanAngle(const C& c) {
auto it = std::cbegin(c);
auto end = std::cend(c);
 
double x = 0.0;
double y = 0.0;
double len = 0.0;
while (it != end) {
x += cos(*it * M_PI / 180);
y += sin(*it * M_PI / 180);
len++;
 
it = std::next(it);
}
 
return atan2(y, x) * 180 / M_PI;
}
 
void printMean(std::initializer_list<double> init) {
std::cout << std::fixed << std::setprecision(3) << meanAngle(init) << '\n';
}
 
int main() {
printMean({ 350, 10 });
printMean({ 90, 180, 270, 360 });
printMean({ 10, 20, 30 });
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>-0.000
-90.000
20.000</pre>
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(defn mean-fn
[k coll]
(let [n (count coll)
trig (get {:sin #(Math/sin %) :cos #(Math/cos %)} k)]
(* (/ 1 n) (reduce + (map trig coll)))))
 
(defn mean-angle
[degrees]
(let [radians (map #(Math/toRadians %) degrees)
a (mean-fn :sin radians)
b (mean-fn :cos radians)]
(Math/toDegrees (Math/atan2 a b))))</syntaxhighlight>
Example:
<syntaxhighlight lang="clojure">(mean-angle [350 10])
;=> -1.614809932057922E-15
 
(mean-angle [90 180 270 360])
;=> -90.0
 
(mean-angle [10 20 30])
;=> 19.999999999999996</syntaxhighlight>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun average (list)
(/ (reduce #'+ list) (length list)))
 
Line 184 ⟶ 374:
 
(defun degrees (angle)
(* 180 (/ 1180 pi) angle))
 
(defun mean-angle (angles)
Line 193 ⟶ 383:
 
(loop for angles in '((350 10) (90 180 270 360) (10 20 30))
do (format t "~&The mean angle of ~a is ~$°." angles (mean-angle angles)))</lang>
 
;; or using complex numbers (cis and phase)
 
(defun mean-angle-2 (angles)
(degrees (phase (reduce #'+ angles :key (lambda (deg) (cis (radians deg)))))))
</syntaxhighlight>
{{out}}
<pre>The mean angle of (350 10) is -0.00°.
Line 200 ⟶ 396:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.complex;
import std.math: PI;
 
Line 215 ⟶ 411:
writefln("The mean angle of %s is: %.2f degrees",
angles, angles.meanAngle);
}</langsyntaxhighlight>
{{out}}
<pre>The mean angle of [350, 10] is: -0.00 degrees
The mean angle of [90, 180, 270, 360] is: 90.00 degrees
The mean angle of [10, 20, 30] is: 20.00 degrees</pre>
=={{header|Delphi}}==
See [[#Pascal]].
=={{header|EasyLang}}==
{{trans|C}}
<syntaxhighlight lang=easylang>
func mean ang[] .
for ang in ang[]
x += cos ang
y += sin ang
.
return atan2 (y / len ang[]) (x / len ang[])
.
print mean [ 350 10 ]
print mean [ 90 180 270 360 ]
print mean [ 10 20 30 ]
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<syntaxhighlight lang="scheme">
(define-syntax-rule (deg->radian deg) (* deg 1/180 PI))
(define-syntax-rule (radian->deg rad) (* 180 (/ PI) rad))
 
(define (mean-angles angles)
(radian->deg
(angle
(for/sum ((a angles)) (make-polar 1 (deg->radian a))))))
 
(mean-angles '( 350 10))
→ -0
(mean-angles '[90 180 270 360])
→ -90
(mean-angles '[10 20 30])
→ 20
</syntaxhighlight>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">
defmodule MeanAngle do
def mean_angle(angles) do
rad_angles = Enum.map(angles, &deg_to_rad/1)
sines = rad_angles |> Enum.map(&:math.sin/1) |> Enum.sum
cosines = rad_angles |> Enum.map(&:math.cos/1) |> Enum.sum
 
rad_to_deg(:math.atan2(sines, cosines))
end
 
defp deg_to_rad(a) do
(:math.pi/180) * a
end
 
defp rad_to_deg(a) do
(180/:math.pi) * a
end
end
 
IO.inspect MeanAngle.mean_angle([10, 350])
IO.inspect MeanAngle.mean_angle([90, 180, 270, 360])
IO.inspect MeanAngle.mean_angle([10, 20, 30])
</syntaxhighlight>
{{out}}
<pre>
-1.614809932057922e-15
-90.0
19.999999999999996
</pre>
 
=={{header|Erlang}}==
The function from_degrees/1 is used to solve [[Averages/Mean_time_of_day]]. Please keep backwards compatibility when editing. Or update the other module, too.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( mean_angle ).
-export( [from_degrees/1, task/0] ).
Line 243 ⟶ 504:
 
radians( Degrees ) -> Degrees * math:pi() / 180.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 253 ⟶ 514:
 
=={{header|Euler Math Toolbox}}==
<langsyntaxhighlight EulerMathToolboxlang="eulermathtoolbox">>function meanangle (a) ...
$ z=sum(exp(rad(a)*I));
$ if z~=0 then error("Not meaningful");
Line 268 ⟶ 529:
if z~=0 then error("Not meaningful");
>meanangle([10,20,30])
20</langsyntaxhighlight>
 
 
=={{header|Euphoria}}==
{{works with|OpenEuphoria}}
<syntaxhighlight lang="euphoria">
<lang Euphoria>
include std/console.e
include std/mathcons.e
Line 300 ⟶ 560:
 
if getc(0) then end if
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 306 ⟶ 566:
Mean Angle for set 2: -90.00000
Mean Angle for set 3: 20.00000
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">open System
open System.Numerics
 
let deg2rad d = d * Math.PI / 180.
let rad2deg r = r * 180. / Math.PI
 
[<EntryPoint>]
let main argv =
let makeComplex = fun r -> Complex.FromPolarCoordinates(1., r)
argv
|> Seq.map (Double.Parse >> deg2rad >> makeComplex)
|> Seq.fold (fun x y -> Complex.Add(x,y)) Complex.Zero
|> fun c -> c.Phase |> rad2deg
|> printfn "Mean angle for [%s]: %g°" (String.Join("; ",argv))
0</syntaxhighlight>
{{out}}
<pre>>RosettaCode 350 10
Mean angle for [350; 10]: -2.74518e-14°
 
>RosettaCode 10 20 30
Mean angle for [10; 20; 30]: 20°
 
>RosettaCode 90 180 270 360
Mean angle for [90; 180; 270; 360]: -90°
</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: formatting kernel math math.functions math.libm math.trig
sequences ;
 
: mean-angle ( seq -- x )
[ deg>rad ] map [ [ sin ] map-sum ] [ [ cos ] map-sum ]
[ length ] tri recip [ * ] curry bi@ fatan2 rad>deg ;
 
: show ( seq -- )
dup mean-angle "The mean angle of %u is: %f°\n" printf ;
 
{ { 350 10 } { 90 180 270 360 } { 10 20 30 } } [ show ] each</syntaxhighlight>
{{out}}
<pre>
The mean angle of { 350 10 } is: -0.000000°
The mean angle of { 90 180 270 360 } is: -90.000000°
The mean angle of { 10 20 30 } is: 20.000000°
</pre>
 
=={{header|Fortran}}==
Please find the example output along with the build instructions in the comments at the start of the FORTRAN 2008 source. Compiler: gfortran from the GNU compiler collection. Command interpreter: bash.
<syntaxhighlight lang="fortran">
<lang FORTRAN>
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Mon Jun 3 18:07:59
Line 347 ⟶ 653:
end do
end program average_angles
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
' FB 1.05.0 Win64
 
Const PI As Double = 3.1415926535897932
 
Function MeanAngle(angles() As Double) As Double
Dim As Integer length = Ubound(angles) - Lbound(angles) + 1
Dim As Double sinSum = 0.0
Dim As Double cosSum = 0.0
For i As Integer = LBound(angles) To UBound(angles)
sinSum += Sin(angles(i) * PI / 180.0)
cosSum += Cos(angles(i) * PI / 180.0)
Next
Return Atan2(sinSum / length, cosSum / length) * 180.0 / PI
End Function
 
Dim As Double angles1(1 To 2) = {350, 10}
Dim As Double angles2(1 To 4) = {90, 180, 270, 360}
Dim As Double angles3(1 To 3) = {10, 20, 30}
 
Print Using "Mean for angles 1 is : ####.## degrees"; MeanAngle(angles1())
Print Using "Mean for angles 2 is : ####.## degrees"; MeanAngle(angles2())
Print Using "Mean for angles 3 is : ####.## degrees"; MeanAngle(angles3())
Print
Print "Press any key to quit the program"
Sleep
</syntaxhighlight>
 
{{out}}
<pre>
Mean for angles 1 is : -0.00 degrees
Mean for angles 2 is : -90.00 degrees
Mean for angles 3 is : 20.00 degrees
</pre>
 
=={{header|Go}}==
===Complex===
<langsyntaxhighlight lang="go">package main
 
import (
Line 378 ⟶ 720:
fmt.Printf("The mean angle of %v is: %f degrees\n", angles, mean_angle(angles))
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 388 ⟶ 730:
A mean_angle function that could be substituted above. Functions deg2rad and rad2deg are not used here but there is no runtime advantage either way to using them or not. Inlining should result in eqivalent code being generated. Also the Go Atan2 library function has no limits on the arguments so there is no need to divide by the number of elements.
 
<langsyntaxhighlight lang="go">func mean_angle(deg []float64) float64 {
var ss, sc float64
for _, x := range deg {
Line 396 ⟶ 738:
}
return math.Atan2(ss, sc) * 180 / math.Pi
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">import static java.lang.Math.*
def meanAngle = {
atan2( it.sum { sin(it * PI / 180) } / it.size(), it.sum { cos(it * PI / 180) } / it.size()) * 180 / PI
}</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="groovy">def verifyAngle = { angles ->
def ma = meanAngle(angles)
printf("Mean Angle for $angles: %5.2f%n", ma)
Line 411 ⟶ 753:
assert verifyAngle([350, 10]) == -0
assert verifyAngle([90, 180, 270, 360]) == -90
assert verifyAngle([10, 20, 30]) == 20</langsyntaxhighlight>
{{out}}
<pre>Mean Angle for [350, 10]: -0.00
Line 418 ⟶ 760:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.Complex (cis, phase)
 
meanAngle
:: RealFloat c
=> [c] -> c
meanAngle = (/ pi) . (* 180) . phase . sum . map (cis . (/ 180) . (* pi))
 
main :: IO ()
main = mapM_ (\angles -> putStrLn $ "The mean angle of " ++ show angles ++ " is: " ++ show (meanAngle angles) ++ " degrees")
main =
[[350, 10], [90, 180, 270, 360], [10, 20, 30]]
mapM_
</lang>
(\angles ->
putStrLn $
"The mean angle of " ++
show angles ++ " is: " ++ show (meanAngle angles) ++ " degrees")
[[350, 10], [90, 180, 270, 360], [10, 20, 30]]</syntaxhighlight>
{{out}}
<pre>
Line 435 ⟶ 785:
Alternative Solution: This solution gives an insight about using factoring, many small functions like Forth and using function composition.
 
<langsyntaxhighlight lang="haskell">
 
-- file: trigdeg.fs
Line 454 ⟶ 804:
 
-- End of trigdeg.fs --------
</syntaxhighlight>
</lang>
 
{{out}}
Line 477 ⟶ 827:
=={{header|Icon}} and {{header|Unicon}}==
 
<langsyntaxhighlight lang="unicon">procedure main(A)
write("Mean angle is ",meanAngle(A))
end
Line 485 ⟶ 835:
every (sumCosines := 0.0) +:= cos(dtor(!A))
return rtod(atan(sumSines/*A,sumCosines/*A))
end</langsyntaxhighlight>
 
Sample runs:
Line 495 ⟶ 845:
->ama 10 20 30
Mean angle is 20.0
</pre>
 
=={{header|IDL}}==
<syntaxhighlight lang="idl">function mean_angle, phi
z = total(exp(complex(0,phi*!dtor)))
return, atan(imaginary(z),real_part(z))*!radeg
end</syntaxhighlight>
 
{{out}}
<pre>IDL> print, mean_angle([350, 10])
-7.80250e-06
IDL> print, mean_angle([90, 180, 270, 360])
90.0000
IDL> print, mean_angle([10, 20, 30])
20.0000
</pre>
 
=={{header|J}}==
<langsyntaxhighlight Jlang="j">avgAngleD=: 360|(_1 { [: (**|)&.+.@(+/ % #)&.(*.inv) 1,.])&.(1r180p1&*)</langsyntaxhighlight>
This verb can be represented as simpler component verbs, for example:
<langsyntaxhighlight Jlang="j">rfd=: 1r180p1&* NB. convert angle to radians from degrees
toComplex=: *.inv NB. maps integer pairs as length, complex angle (in radians)
mean=: +/ % # NB. calculate arithmetic mean
roundComplex=: (* * |)&.+. NB. discard an extraneous least significant bit of precision from a complex value whose magnitude is in the vicinity of 1
avgAngleR=: _1 { [: roundComplex@mean&.toComplex 1 ,. ] NB. calculate average angle in radians
avgAngleD=: 360|avgAngleR&.rfd</lang> NB. calculate average angle in degrees</syntaxhighlight>
Example use:
<langsyntaxhighlight Jlang="j"> avgAngleD 10 350
0
avgAngleD 90 180 270 360 NB. result not meaningful
0
avgAngleD 10 20 30
20</lang>
avgAngleD 20 350
5
avgAngleD 10 340
355</syntaxhighlight>
 
Notes:
Line 527 ⟶ 896:
 
<code>verb&.(1r180p1&*)</code> converts its argument from degrees to radians, uses the verb in the radian domain, then converts the result of that argument back to degrees.
 
<code>360|verb</code> ensures that the result is not negative and is also less than 360
 
=={{header|Java}}==
{{trans|NetRexx}}
{{works with|Java|7+}}
<langsyntaxhighlight lang="java5">import java.util.ArrayListArrays;
import java.util.Arrays;
import java.util.List;
 
public class RAvgMeanAngleAverageMeanAngle {
 
public static void main(String[] args) {
private static final List<List<Double>> samples;
printAverageAngle(350.0, 10.0);
printAverageAngle(90.0, 180.0, 270.0, 360.0);
printAverageAngle(10.0, 20.0, 30.0);
printAverageAngle(370.0);
printAverageAngle(180.0);
}
 
private static void printAverageAngle(double... sample) {
static {
double meanAngle = getMeanAngle(sample);
samples = new ArrayList<>();
System.out.printf("The mean angle of %s is %s%n", Arrays.toString(sample), meanAngle);
samples.add(Arrays.asList(350.0, 10.0));
samples.add(Arrays.asList(90.0, 180.0, 270.0, 360.0));
samples.add(Arrays.asList(10.0, 20.0, 30.0));
samples.add(Arrays.asList(370.0));
samples.add(Arrays.asList(180.0));
}
 
public RAvgMeanAngle() {
 
return;
}
 
public double getMeanAngle(List<Double> sample) {
 
double x_component = 0.0;
double y_component = 0.0;
double avg_d, avg_r;
 
for (double angle_d : sample) {
double angle_r;
angle_r = Math.toRadians(angle_d);
x_component += Math.cos(angle_r);
y_component += Math.sin(angle_r);
}
x_component /= sample.size();
y_component /= sample.size();
avg_r = Math.atan2(y_component, x_component);
avg_d = Math.toDegrees(avg_r);
 
public static double getMeanAngle(double... anglesDeg) {
return avg_d;
double x = 0.0;
}
double y = 0.0;
 
for (double angleD : anglesDeg) {
public static void main(String[] args) {
double angleR = Math.toRadians(angleD);
 
x += Math.cos(angleR);
runSample(args);
y += Math.sin(angleR);
 
return; }
double avgR = Math.atan2(y / anglesDeg.length, x / anglesDeg.length);
}
return Math.toDegrees(avgR);
 
public static void runSample(String[] args) {
 
RAvgMeanAngle main = new RAvgMeanAngle();
for (List<Double> sample : samples) {
double meanAngle = main.getMeanAngle(sample);
System.out.printf("The mean angle of %s is:%n%12.6f%n%n", sample, meanAngle);
}
}</syntaxhighlight>
 
return;
}
}</lang>
{{out}}
<pre>The mean angle of [350.0, 10.0] is: -1.614809932057922E-15
The mean angle of [90.0, 180.0, 270.0, 360.0] is -90.0
-0.000000
The mean angle of [10.0, 20.0, 30.0] is 19.999999999999996
 
The mean angle of [90370.0,] 180.0,is 2709.0, 360.0] is:999999999999977
The mean angle of [180.0] is 180.0</pre>
-90.000000
 
The mean angle of [10.0, 20.0, 30.0] is:
20.000000
 
The mean angle of [370.0] is:
10.000000
 
The mean angle of [180.0] is:
180.000000</pre>
 
=={{header|JavaScript}}==
===atan2===
<langsyntaxhighlight lang="javascript">function sum(a) {
var s = 0;
for (var i in= 0; i < a.length; i++) s += a[i];
return s;
}
 
function degToRad(a) {
return Math.PI / 180 * a;
}
 
function meanAngleDeg(a) {
return 180 / Math.PI * Math.atan2(sum(a.map(degToRad).map(Math.sin))/a.length,sum(a.map(degToRad).map(Math.cos))/a.length);
sum(a.map(degToRad).map(Math.sin)) / a.length,
sum(a.map(degToRad).map(Math.cos)) / a.length
);
}
 
var a = [350, 10], b = [90, 180, 270, 360], c = [10, 20, 30];
console.log(meanAngleDeg(a));
console.log(meanAngleDeg(b));
console.log(meanAngleDeg(c));</langsyntaxhighlight>
{{out}}
<pre>-1.614809932057922e-15
Line 639 ⟶ 974:
 
'''Generic Infrastructure'''
<langsyntaxhighlight lang="jq">def pi: 4 * (1|atan);
 
def deg2rad: . * pi / 180;
Line 657 ⟶ 992:
def abs: if . < 0 then - . else . end;
def summation(f): map(f) | add;</langsyntaxhighlight>
 
'''Mean Angle'''
<langsyntaxhighlight lang="jq"># input: degrees
def mean_angle:
def round:
Line 674 ⟶ 1,009:
| .[1]
| rad2deg
| round;</langsyntaxhighlight>
'''Examples'''
<langsyntaxhighlight lang="jq">([350, 10], [90, 180, 270, 360], [10, 20, 30])
| "The mean angle of \(.) is: \(mean_angle)"</langsyntaxhighlight>
 
{{out}}
<langsyntaxhighlight lang="sh">jq -r -n -f Mean_angle.jq
The mean angle of [350,10] is: 0
The mean angle of [90,180,270,360] is: null
The mean angle of [10,20,30] is: 20</langsyntaxhighlight>
 
=={{header|Julia}}==
Julia has built-in functions <code>sind</code> and <code>cosd</code> to compute the sine and cosine of angles specified in degrees accurately (avoiding the roundoff errors incurred in conversion to radians), and a built-in function to convert radians to degrees (or vice versa). Using these:
<syntaxhighlight lang="julia">using Statistics
<lang julia>meandegrees(degrees) = radians2degrees(atan2(mean(sind(degrees)), mean(cosd(degrees))))</lang>
meandegrees(degrees) = rad2deg(atan(mean(sind.(degrees)), mean(cosd.(degrees))))</syntaxhighlight>
The output is:
<langsyntaxhighlight lang="julia">julia> meandegrees([350, 10])
0.0
 
Line 696 ⟶ 1,032:
 
julia> meandegrees([10, 20, 30]])
19.999999999999996</langsyntaxhighlight>
(Note that the mean of 90°, 180°, 270°, and 360° gives zero because of the lack of roundoff errors in the <code>sind</code> function, since the standard-library <code>atan2(0,0)</code> value is zero. Many of the other languages report an average of 90° or –90° in this case due to rounding errors.)
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.0.5-2
 
fun meanAngle(angles: DoubleArray): Double {
val sinSum = angles.sumByDouble { Math.sin(it * Math.PI / 180.0) }
val cosSum = angles.sumByDouble { Math.cos(it * Math.PI / 180.0) }
return Math.atan2(sinSum / angles.size, cosSum / angles.size) * 180.0 / Math.PI
}
 
fun main(args: Array<String>) {
val angles1 = doubleArrayOf(350.0, 10.0)
val angles2 = doubleArrayOf(90.0, 180.0, 270.0, 360.0)
val angles3 = doubleArrayOf(10.0, 20.0, 30.0)
val fmt = "%.2f degrees" // format results to 2 decimal places
println("Mean for angles 1 is ${fmt.format(meanAngle(angles1))}")
println("Mean for angles 2 is ${fmt.format(meanAngle(angles2))}")
println("Mean for angles 3 is ${fmt.format(meanAngle(angles3))}")
}</syntaxhighlight>
 
{{out}}
<pre>
Mean for angles 1 is -0.00 degrees
Mean for angles 2 is -90.00 degrees
Mean for angles 3 is 20.00 degrees
</pre>
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">global Pi
Pi =3.1415926535
 
Line 741 ⟶ 1,103:
if y =0 and x =0 then notice "undefined": end
atan2 =at
end function</langsyntaxhighlight>
{{out}}
<pre>
Line 748 ⟶ 1,110:
Mean Angle( "10,20,30") = 20.0 degrees.
</pre>
 
=={{header|Logo}}==
<langsyntaxhighlight lang="logo">to mean_angle :angles
local "avgsin
make "avgsin quotient apply "sum map "sin :angles count :angles
Line 762 ⟶ 1,125:
 
bye
</syntaxhighlight>
</lang>
 
{{Out}}
Line 768 ⟶ 1,131:
The average of ( 90 180 270 360 ) is 0
The average of ( 10 20 30 ) is 20</pre>
 
=={{header|Lua}}==
{{trans|Tcl}}
{{works with|Lua|5.1}}
<syntaxhighlight lang="lua">function meanAngle (angleList)
local sumSin, sumCos = 0, 0
for i, angle in pairs(angleList) do
sumSin = sumSin + math.sin(math.rad(angle))
sumCos = sumCos + math.cos(math.rad(angle))
end
local result = math.deg(math.atan2(sumSin, sumCos))
return string.format("%.2f", result)
end
 
print(meanAngle({350, 10}))
print(meanAngle({90, 180, 270, 360}))
print(meanAngle({10, 20, 30}))</syntaxhighlight>
{{out}}
<pre>
-0.00
-90.00
20.00
</pre>
 
=={{header|Maple}}==
The following procedure takes a list of numeric degrees (with attached units) such as
<langsyntaxhighlight Maplelang="maple">> [ 350, 10 ] *~ Unit(arcdeg);
[350 [arcdeg], 10 [arcdeg]]</langsyntaxhighlight>
as input. (We could use "degree" instead of "arcdeg", since "degree" is taken, by default, to mean angle measure, but it seems best to avoid the ambiguity.)
<langsyntaxhighlight Maplelang="maple">MeanAngle := proc( L )
uses Units:-Standard; # for unit-awareness
local u;
evalf( convert( argument( add( u, u = exp~( I *~ L ) ) ), 'units', 'radian', 'degree' ) )
end proc:</langsyntaxhighlight>
Applying this to the given data sets, we obtain:
<langsyntaxhighlight Maplelang="maple">> MeanAngle( [ 350, 10 ] *~ Unit(arcdeg) );
0.
 
Line 787 ⟶ 1,173:
 
> MeanAngle( [ 10, 20, 30 ] *~ Unit(arcdeg) );
20.00000000</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">meanAngle[data_List] := N@Arg[Mean[Exp[I data Degree]]]/Degree</langsyntaxhighlight>
{{out}}
<pre>meanAngle /@ {{350, 10}, {90, 180, 270, 360}, {10, 20, 30}}
Line 796 ⟶ 1,182:
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight MATLABlang="matlab">function u = mean_angle(phi)
u = angle(mean(exp(i*pi*phi/180)))*180/pi;
end</langsyntaxhighlight>
<pre> mean_angle([350, 10])
ans = -2.7452e-14
Line 805 ⟶ 1,191:
mean_angle([10, 20, 30])
ans = 20.000
</pre>
 
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">
atan2 = function(y, x)
return 2 * atan((sqrt(x^2 + y^2) - x) / y)
end function
 
deg2rad = function(x); return x * pi / 180; end function
rad2deg = function(x); return x * 180 / pi; end function
 
meanAngle = function(angles)
xsum = 0; ysum = 0
for angle in angles
xsum += cos(deg2rad(angle))
ysum += sin(deg2rad(angle))
end for
return rad2deg(atan2(ysum / angles.len, xsum / angles.len))
end function
 
manyAngledOnes = [[350, 10], [90, 180, 270, 360], [10, 20, 30]]
 
for angles in manyAngledOnes
mean = meanAngle(angles)
print ["Mean of", angles, "is", mean].join(" ")
end for
</syntaxhighlight>
{{out}}
<pre>
Mean of [350, 10] is 0
Mean of [90, 180, 270, 360] is -90
Mean of [10, 20, 30] is 20.0
</pre>
 
=={{header|NetRexx}}==
{{trans|C}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary
numeric digits 80
Line 842 ⟶ 1,260:
end angles
return
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 862 ⟶ 1,280:
 
=={{header|Nim}}==
{{works with|Nim|0.20.0+}}
<lang nim>import math, complex
<syntaxhighlight lang="nim">import math, complex
 
proc rect(r, phi): Complex = (r * cos(phi), sin(phi))
proc phasemeanAngle(cdeg: openArray[float]): float = arctan2(c.im, c.re)
var c: Complex[float]
 
proc radians(x): float = (x * Pi) / 180.0
proc degrees(x): float = (x * 180.0) / Pi
 
proc meanAngle(deg): float =
var c: Complex
for d in deg:
c += rect(1.0, radiansdegToRad(d))
degreesradToDeg(phase(c / float(deg.len)))
 
echo "The 1st mean angle is: ", meanAngle([350.0, 10.0]), " degrees"
echo "The 2nd mean angle is: ", meanAngle([90.0, 180.0, 270.0, 360.0]), " degrees"
echo "The 3rd mean angle is: ", meanAngle([10.0, 20.0, 30.0]), " degrees"</langsyntaxhighlight>
Output:
<pre>The 1st mean angle is: -21.745176884498468e614809932057922e-1415 degrees
The 2nd mean angle is: -90.0 degrees
The 3rd mean angle is: 20.0 degrees</pre>
 
=={{header|Oberon-2}}==
{{works with|oo2c}}
<syntaxhighlight lang="oberon2">
MODULE MeanAngle;
IMPORT
M := LRealMath,
Out;
CONST
toRads = M.pi / 180;
toDegs = 180 / M.pi;
VAR
grades: ARRAY 64 OF LONGREAL;
 
PROCEDURE Mean(g: ARRAY OF LONGREAL): LONGREAL;
VAR
i: INTEGER;
sumSin, sumCos: LONGREAL;
BEGIN
i := 0;sumSin := 0.0;sumCos := 0.0;
WHILE g[i] # 0.0 DO
sumSin := sumSin + M.sin(g[i] * toRads);
sumCos := sumCos + M.cos(g[i] * toRads);
INC(i)
END;
RETURN M.arctan2(sumSin / i,sumCos / i);
END Mean;
 
BEGIN
grades[0] := 350.0;grades[1] := 10.0;
Out.LongRealFix(Mean(grades) * toDegs,15,9);Out.Ln;
grades[0] := 90.0;grades[1] := 180.0;grades[2] := 270.0;grades[3] := 360.0;
Out.LongRealFix(Mean(grades) * toDegs,15,9);Out.Ln;
grades[0] := 10.0;grades[1] := 20.0;grades[2] := 30.0;grades[3] := 0.0;
Out.LongRealFix(Mean(grades) * toDegs,15,9);Out.Ln;
END MeanAngle.
</syntaxhighlight>
{{out}}
<pre>
-0.000000000
-90.000000000
20.000000000
</pre>
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let pi = 3.14159_26535_89793_23846_2643
 
let deg2rad d =
Line 909 ⟶ 1,365:
test [90.0; 180.0; 270.0; 360.0];
test [10.0; 20.0; 30.0];
;;</langsyntaxhighlight>
or using the <code>Complex</code> module:
<langsyntaxhighlight lang="ocaml">open Complex
 
let mean_angle angles =
Line 917 ⟶ 1,373:
List.fold_left (fun sum a -> add sum (polar 1.0 (deg2rad a))) zero angles
in
rad2deg (arg sum)</langsyntaxhighlight>
{{out}}
<pre>
Line 927 ⟶ 1,383:
=={{header|ooRexx}}==
{{trans|REXX}}
<langsyntaxhighlight lang="oorexx">/*REXX program computes the mean angle (angles expressed in degrees). */
numeric digits 50 /*use fifty digits of precision, */
showDig=10 /*··· but only display 10 digits.*/
Line 950 ⟶ 1,406:
return left('angles='a,30) 'mean angle=' format(mA,,showDig,0)/1
 
::requires rxMath library;</langsyntaxhighlight>
{{out}}
<pre>angles=350 10 mean angle= 0
angles=90 180 270 360 mean angle= 0
angles=10 20 30 mean angle= 20</pre>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">meanAngle(v)=atan(sum(i=1,#v,sin(v[i]))/sum(i=1,#v,cos(v[i])))%(2*Pi)
meanDegrees(v)=meanAngle(v*Pi/180)*180/Pi
apply(meanDegrees,[[350, 10], [90, 180, 270, 360], [10, 20, 30]])</langsyntaxhighlight>
{{out}}
<pre>[360.000000, 296.565051, 20.0000000]</pre>
 
=={{header|Pascal}}==
uses library math for sincos, a function of FPU80x87, atan2 and DegToRad.
Tested with free pascal.
Try to catch very small cos values and set to 0.0 degrees " Error : Not meaningful" as http://rosettacode.org/wiki/Averages/Mean_angle#Euler_Math_Toolbox complains.
<langsyntaxhighlight lang="pascal">program MeanAngle;
{$IFDEF DELPHI}
{$APPTYPE CONSOLE}
Line 1,036 ⟶ 1,493:
 
setlength(a,0);
end.</langsyntaxhighlight>
;output:
<pre>
Line 1,044 ⟶ 1,501:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">sub Pi () { 3.1415926535897932384626433832795028842 }
 
sub meanangle {
Line 1,060 ⟶ 1,517:
 
print "The mean angle of [@$_] is: ", meandegrees(@$_), " degrees\n"
for ([350,10], [90,180,270,360], [10,20,30]);</langsyntaxhighlight>
{{out}}
<pre>
Line 1,068 ⟶ 1,525:
</pre>
 
=={{header|Perl 6Phix}}==
Copied from [[Averages/Mean_angle#Euphoria|Euphoria]], and slightly improved
This solution refuses to return an answer when the angles cancel out to a tiny magnitude.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>sub deg2rad { $^d * pi / 180 }
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sub rad2deg { $^r * 180 / pi }
<span style="color: #008080;">function</span> <span style="color: #000000;">MeanAngle</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">angles</span><span style="color: #0000FF;">)</span>
sub phase ($c) {
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
my ($mag,$ang) = $c.polar;
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">angles</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return NaN if $mag < 1e-16;
<span style="color: #004080;">atom</span> <span style="color: #000000;">ai_rad</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">angles</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]*</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">/</span><span style="color: #000000;">180</span>
$ang;
<span style="color: #000000;">x</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">cos</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ai_rad</span><span style="color: #0000FF;">)</span>
}
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">sin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ai_rad</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
sub meanAngle { rad2deg phase [+] map { cis deg2rad $_ }, @^angles }
<span style="color: #008080;">if</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">1e-16</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008000;">"not meaningful"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%g"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">round</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">atan2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">180</span><span style="color: #0000FF;">/</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1e10</span><span style="color: #0000FF;">))</span>
say meanAngle($_).fmt("%.2f\tis the mean angle of "), $_ for
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
[350, 10],
[90, 180, 270, 360],
<span style="color: #008080;">constant</span> <span style="color: #000000;">AngleLists</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">350</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">90</span><span style="color: #0000FF;">,</span><span style="color: #000000;">180</span><span style="color: #0000FF;">,</span><span style="color: #000000;">270</span><span style="color: #0000FF;">,</span><span style="color: #000000;">360</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">180</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">180</span><span style="color: #0000FF;">}}</span>
[10, 20, 30];</lang>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">AngleLists</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ai</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">AngleLists</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%16V: Mean Angle is %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ai</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MeanAngle</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ai</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
<pre>-0.00 is the mean angle of 350 10
{350,10}: Mean Angle is 0
NaN is the mean angle of 90 180 270 360
{90,180,270,360}: Mean Angle is not meaningful
20.00 is the mean angle of 10 20 30</pre>
{10,20,30}: Mean Angle is 20
{180}: Mean Angle is 180
{0,180}: Mean Angle is not meaningful
</pre>
 
=={{header|PHP}}==
{{trans|C}}
<langsyntaxhighlight lang="php"><?php
$samples = array(
'1st' => array(350, 10),
Line 1,113 ⟶ 1,579:
return rad2deg(atan2($y_part, $x_part));
}
?></langsyntaxhighlight>
{{out}}
<pre>Mean angle for 1st sample: -1.6148099320579E-15 degrees.
Line 1,120 ⟶ 1,586:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/math.l")
 
(de meanAngle (Lst)
Line 1,133 ⟶ 1,599:
"The mean angle of ["
(glue ", " (mapcar round L '(0 .)))
"] is: " (round (meanAngle L))) )</langsyntaxhighlight>
{{out}}
<pre>The mean angle of [350, 10] is: 0.000
Line 1,140 ⟶ 1,606:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">averages: procedure options (main); /* 31 August 2012 */
declare b1(2) fixed initial (350, 10);
declare b2(4) fixed initial (90, 180, 270, 360);
Line 1,157 ⟶ 1,623:
end mean;
 
end averages;</langsyntaxhighlight>
Results (the final one brings up an error in inverse tangent):
<pre>
Line 1,166 ⟶ 1,632:
At offset +000009CC in procedure with entry AVERAGES
</pre>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function Get-MeanAngle ([double[]]$Angles)
{
$x = ($Angles | ForEach-Object {[Math]::Cos($_ * [Math]::PI / 180)} | Measure-Object -Average).Average
$y = ($Angles | ForEach-Object {[Math]::Sin($_ * [Math]::PI / 180)} | Measure-Object -Average).Average
 
[Math]::Atan2($y, $x) * 180 / [Math]::PI
}
</syntaxhighlight>
 
<syntaxhighlight lang="powershell">
@(350, 10), @(90, 180, 270, 360), @(10, 20, 30) | ForEach-Object {Get-MeanAngle $_}
</syntaxhighlight>
 
{{Out}}
<pre>
-2.74517688449847E-14
-90
20
</pre>
 
=={{header|Processing}}==
<syntaxhighlight lang="processing">void setup() {
println(meanAngle(350, 10));
println(meanAngle(90, 180, 270, 360));
println(meanAngle(10, 20, 30));
}
 
float meanAngle(float... angles) {
float sum1 = 0, sum2 = 0;
for (int i = 0; i < angles.length; i++) {
sum1 += sin(radians(angles[i])) / angles.length;
sum2 += cos(radians(angles[i])) / angles.length;
}
return degrees(atan2(sum1, sum2));
}</syntaxhighlight>
{{out}}
<pre>-7.8025005E-6
90.0
20.0</pre>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">NewList angle.d()
 
Macro AE(x)
AddElement(angle()) : angle()=x
EndMacro
 
Procedure.d atan3(y.d,x.d)
If x<=0.0 : ProcedureReturn Sign(y)*#PI/2 : EndIf
If x>0.0 : ProcedureReturn ATan(y/x) : EndIf
If y>0.0 : ProcedureReturn ATan(y/x)+#PI : EndIf
ProcedureReturn ATan(y/x)-#PI
EndProcedure
 
Procedure.d mAngle(List angle.d())
Define.d sumS,sumC
ForEach angle()
sumS+Sin(Radian(angle())) : sumC+Cos(Radian(angle()))
Next
ProcedureReturn Degree(atan3(sumS,sumC))
EndProcedure
 
AE(350.0) : AE(10.0)
Debug StrD(mAngle(angle()),6) : ClearList(angle())
 
AE(90.0) : AE(180.0) : AE(270.0) : AE(360.0)
Debug StrD(mAngle(angle()),6) : ClearList(angle())
 
AE(10.0) : AE(20.0) : AE(30.0)
Debug StrD(mAngle(angle()),6) : ClearList(angle())
</syntaxhighlight>
{{out}}
<pre>-0.000000
-90.000000
20.000000</pre>
 
=={{header|Python}}==
{{works with|Python|2.6+}}
<langsyntaxhighlight lang="python">>>> from cmath import rect, phase
>>> from math import radians, degrees
>>> def mean_angle(deg):
Line 1,180 ⟶ 1,724:
The mean angle of [90, 180, 270, 360] is: -90.0 degrees
The mean angle of [10, 20, 30] is: 20.0 degrees
>>> </langsyntaxhighlight>
 
=={{header|R}}==
<syntaxhighlight lang="r">
deg2rad <- function(x) {
x * pi/180
}
 
rad2deg <- function(x) {
x * 180/pi
}
 
deg2vec <- function(x) {
c(sin(deg2rad(x)), cos(deg2rad(x)))
}
 
vec2deg <- function(x) {
res <- rad2deg(atan2(x[1], x[2]))
if (res < 0) {
360 + res
} else {
res
}
}
 
mean_vec <- function(x) {
y <- lapply(x, deg2vec)
Reduce(`+`, y)/length(y)
}
 
mean_deg <- function(x) {
vec2deg(mean_vec(x))
}
 
mean_deg(c(350, 10))
mean_deg(c(90, 180, 270, 360))
mean_deg(c(10, 20, 30))
</syntaxhighlight>
{{out}}
<pre>
360
270
20
</pre>
 
=={{header|Racket}}==
The formula given above can be straightforwardly transcribed into a program:
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,200 ⟶ 1,787:
(mean-angle '(90 180 270 360))
(mean-angle '(10 20 30))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,207 ⟶ 1,794:
19.999999999999996
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2015.12}}
This solution refuses to return an answer when the angles cancel out to a tiny magnitude.
<syntaxhighlight lang="raku" line># Of course, you can still use pi and 180.
sub deg2rad { $^d * tau / 360 }
sub rad2deg { $^r * 360 / tau }
 
sub phase ($c) {
my ($mag,$ang) = $c.polar;
return NaN if $mag < 1e-16;
$ang;
}
 
sub meanAngle { rad2deg phase [+] map { cis deg2rad $_ }, @^angles }
 
say meanAngle($_).fmt("%.2f\tis the mean angle of "), $_ for
[350, 10],
[90, 180, 270, 360],
[10, 20, 30];</syntaxhighlight>
{{out}}
<pre>-0.00 is the mean angle of 350 10
NaN is the mean angle of 90 180 270 360
20.00 is the mean angle of 10 20 30</pre>
 
=={{header|REXX}}==
This REXX version uses an &nbsp; '''ATAN2''' &nbsp; solution.
 
The REXX language doesn't have most of the higher mathematical functions (like '''sqrt'''), and
(like '''sqrt'''), and
none of the trigonometric functions, so all of them have to be included as RYO ('''R'''oll-'''Y'''our-'''O'''wn).
none of the trigonometric
<br>functions, &nbsp; so all of them have to be included as
RYO &nbsp; ('''R'''oll-'''Y'''our-'''O'''wn).
<pre>
Note that the second set of angles: 90 180 270 360
 
is the same as: 90 180 -90 0
and: -270 -180 -90 -360
 
Note that the second set of angles:
::::* 90 180 270 360
is the same as:
::::* 90 180 -90 0
::::* -270 -180 -90 -360
and other combinations.
</pre>
All the trigonometric functions use normalization &nbsp; (converting the
angle to a unit circle) &nbsp; before computation, &nbsp; and most
<br>of them use shortcuts for some exact values, &nbsp; so there is a minimum of
errors due to rounding for &nbsp; ''near values'' &nbsp; for some
<br>common values.
 
The consequence is the trig functions may return exact values such
All the trigonometric functions use normalization before computation, and most of them use shortcuts for some exact values, so there is a minimum of ''near values'' for some common values. &nbsp; The consequence of this is the trig functions may return exact values such as '''0''' (zero) for '''sin(-2π)''' instead of '''-8.154E-61'''. &nbsp;
as &nbsp; '''0''' &nbsp; (zero) &nbsp; for &nbsp; '''sin(-2<big><big><math>\pi</math></big></big>)''' &nbsp; instead
of &nbsp; '''-8.154E-61'''.
 
This very small difference (almost inconsequential) makes a significant difference when that value is used for a parameter for the '''ATAN2''' function; &nbsp; in particular, the sign of the value. &nbsp;
when that value is used for a parameter
<br>for the &nbsp; '''ATAN2''' &nbsp; function; &nbsp; in
particular, the &nbsp; ''sign'' &nbsp; of the value.
 
There isn't much difference between :
:::* &nbsp; ''' -8.154E154e-61''' &nbsp; and and
:::* &nbsp; ''' +8.154E154e-61'''
in magnitude, but the &nbsp; '''ATAN2''' &nbsp; function treats those two numbers
in magnitude, but the '''ATAN2''' function treats those two numbers much differently as the angle is in different quadrants, thereby yielding a different value. &nbsp; Usually this just results in an angle of &nbsp; '''-90º''' &nbsp; instead of &nbsp; '''+270º''' &nbsp; (both angles are equivalent).
very differently as the angle will be in different quadrants,
<br><br>Also note that the REXX subroutines are largely not commented as they provide a support structure that's normally present in other languages as BIFs &nbsp; ('''B'''uilt-'''I'''n-'''F'''unctions); &nbsp; to add comments and expand the REXX statements into single lines would detract from the main program.
<br>thereby yielding a different value.
<lang rexx>/*REXX program computes the mean angle (angles expressed in degrees). */
 
numeric digits 50 /*use fifty digits of precision, */
Usually this just results in an angle of &nbsp; '''-90º''' &nbsp; instead
showDig=10 /*··· but only display 10 digits.*/
of &nbsp; '''+270º''' &nbsp; (both angles are equivalent).
# = 350 10 ; say showit(#, meanAngleD(#) )
 
# = 90 180 270 360 ; say showit(#, meanAngleD(#) )
Also note that the REXX subroutines are largely not commented as they provide a
# = 10 20 30 ; say showit(#, meanAngleD(#) )
support structure that's normally present
exit /*stick a fork in it, we're done.*/
<br>in other computer programming languages as
/*──────────────────────────────────MEANANGD subroutine─────────────────*/
BIFs &nbsp; ('''B'''uilt-'''I'''n-'''F'''unctions); &nbsp; to add comments and expand the
meanAngleD: procedure; parse arg x; numeric digits digits()+digits()%4
REXX statements
_sin=0; _cos=0; n=words(x); do j=1 for n; !=d2r(word(x,j))
<br>into single lines would increase the program's bulk and detract from the main program.
_sin = _sin + sin(!)
<syntaxhighlight lang="rexx">/*REXX program computes the mean angle for a group of angles (expressed in degrees). */
_cos = _cos + cos(!)
call pi end /*jdefine the value of pi to some accuracy.*/
numeric digits length(pi) - 1; /*use PI width decimal digits of precision,*/
return r2d(atan2(_sin/n, _cos/n))
showDig= 10 /*only display ten decimal digits. */
/*─────────────────────────────one─line subroutines──────────────────────────────────────────*/
#= 350 10 ; say show(#, meanAngleD(#)) /*display mean angle (in degrees), 1st case.*/
#= 90 180 270 360 ; say show(#, meanAngleD(#)) /* " " " " " 2nd " */
#= 10 20 30 ; say show(#, meanAngleD(#)) /* " " " " " 3rd " */
exit /*stick a fork in it, we're all done with it*/
/*───────────────────────────────────────────────────────────────────────────────────────────*/
.sinCos: arg z,_,i; x=x*x; do k=2 by 2 until p=z; p=z; _=-_*x/(k*(k+i)); z=z+_; end; return z
$fuzz: return min(arg(1), max(1, digits() - arg(2) ) )
acosAcos: procedure; parse arg x; return pi() * .5 - asinAsin(x)
atanAtan: parse arg x; if abs(x)=1 then return pi()*.25 * sign(x); return asinAsin(x/sqrt(1 + x*x))
d2d: return arg(1) // 360
d2r: return r2r(d2d(arg(1)) / 180 * pi() )
r2d: return d2d((r2r(arg(1)) / pi()) * 180)
r2r: return arg(1) // (pi() * 2)
p: return word(arg(1), 1)
pi: pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862;return pi
/*───────────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────ASIN subroutine────────────────────*/
asinAsin: procedure; parse arg x 1 z 1 o 1 p; xx a= abs(x); aa= a *x a
if xxa>=.51 then returncall AsinErr sign(x) /*argument acos(sqrt(1-xx))X is out of range.*/
if a do j>= sqrt(2) * by.5 2 then until p=z;return sign(x) p=z; o=o*xx* acos(j-1)/j; z=z+o/sqrt(j+1 - aa);, end'-ASIN')
return zdo j=2 by 2 until p=z; p= z; o= o * aa * (j-1) / j; z= z +o /* [↑](j+1); compute until no noise.*/end
return z /* [↑] compute until no noise*/
/*───────────────────────────────────ATAN2 subroutine───────────────────*/
/*───────────────────────────────────────────────────────────────────────────────────────────*/
atan2: procedure; parse arg y,x; call pi; s=sign(y)
Atan2: procedure; parse arg y,x; call pi; s= sign(y)
select
when x=0 then z= s * pi * .5
when x<0 then if y=0 then z= pi; else z= s * (pi - abs(atan Atan(y/x) ) )
otherwise z= s * atanAtan(y / x)
end /*select*/; return z
/*───────────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────COS subroutine─────────────────────*/
cos: procedure; parse arg x; x= r2r(x); numeric fuzz $fuzz(56, 3)
a= abs(x); if a=0 then return 1; 1; if a=pi then return -1
if a=pi*.5 | a= pi*1.5 then return 0; if a=pi/3 then return .5
if a= pi*2/3 then return -.5; return .sinCos(1, 1, -1)
/*───────────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────SHOWIT subroutine──────────────────*/
showitmeanAngleD: procedure; expose showDigparse arg x; numeric digits showDig;digits() + parsedigits() arg% a,mA4
n= words(x); _sin= 0; _cos= 0
return left('angles='a,30) 'mean angle=' format(mA,,showDig,0)/1
do j=1 for n; != d2r( word(x, j)); _sin= _sin + sin(!); _cos= _cos + cos(!)
/*───────────────────────────────────COS subroutine─────────────────────*/
sin: procedure; parse arg x; x=r2r(x); end numeric fuzz $fuzz(5, 3)/*j*/
if x=pi*.5 then return 1; r2d( Atan2( _sin/n, if x==pi*1.5 then return_cos/n) -1)
/*───────────────────────────────────────────────────────────────────────────────────────────*/
if abs(x)=pi | x=0 then return 0; return .sinCos(x, x, +1)
show: parse arg a,mA; _= format(ma, , showDig, 0) / 1
/*───────────────────────────────────SQRT subroutine────────────────────*/
return left('angles='a, 30) "mean angle=" right(_, max(4, length(_) ) )
sqrt: procedure; parse arg x,i; if x=0 then return 0; d=digits(); m.=11
/*───────────────────────────────────────────────────────────────────────────────────────────*/
if x<0 then i='i'; numeric digits 11; numeric form; p=d+d%4+2
sin: procedure; parse arg x; parse value formatx= r2r(x,2,1,,0); 'E0' with g 'E' _ .; numeric g=g*.fuzz $fuzz(5'E'_%2, 3)
if x=pi * .5 do j=0 while then p>9return 1; m.j=p; p=p%2+1; if x==pi * end1.5 then /*j*/return -1
if abs(x)=pi | x=0 then return do0; k=j+5 to 0 by -1; if m.k>11 return then.sinCos(x, numericx, digits m.k+1)
/*───────────────────────────────────────────────────────────────────────────────────────────*/
g=.5*(g+x/g); end /*k*/; numeric digits d; return g/1</lang>
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); m.=9; numeric form; h= d+6
''output''' when using the default input:
numeric digits; parse value format(x,2,1,,0) 'E0' with g "E" _ .; g= g * .5'e'_ % 2
do j=0 while h>9; m.j= h; h= h % 2 + 1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g= (g + x/g) * .5; end /*k*/
return g</syntaxhighlight>
{{out|output|text=&nbsp; when using the default internal inputs:}}
<pre>
angles=350 10 mean angle= 0
angles=90 180 270 360 mean angle= 0 -90
angles=10 20 30 mean angle= 20
</pre>
Note that with the increase in decimal digit precision, the 2<sup>nd</sup> mean angle changed dramatically from an earlier result. <br><br>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Averages/Mean angle
 
load "stdlib.ring"
decimals(6)
pi = 3.1415926535897
angles = [350,10]
see meanangle(angles, len(angles)) + nl
angles = [90,180,270,360]
see meanangle(angles, len(angles)) + nl
angles = [10,20,30]
see meanangle(angles, len(angles)) + nl
func meanangle(angles, n)
sumsin = 0
sumcos = 0
for i = 1 to n
sumsin = sumsin + sin(angles[i]*pi/180)
sumcos = sumcos + cos(angles[i]*pi/180)
next
return 180/pi*atan3(sumsin, sumcos)
func atan3(y,x)
if x <= 0
return sign(y)*pi/2
ok
if x>0
return atan(y/x)
else
if y>0
return atan(y/x)+pi
else
return atan(y/x)-pi
ok
ok
</syntaxhighlight>
Output:
<pre>
-0.000000
-90
20.000000
</pre>
 
=={{header|RPL}}==
≪ DEG → angles
≪ 0 1 angles SIZE '''FOR''' j
1 angles j GET R→C P→R + '''NEXT'''
angles SIZE / ARG
≫ ≫ ''''MEANG'''' STO
{{in}}
<pre>
{ 350 10 } MEANG
{ 90 180 270 360 } MEANG
{ 10 20 30 } MEANG
</pre>
{{out}}
<pre>
3: 0
2: -90
1: 20
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'complex' # Superfluous in Ruby >= 2.0; complex is added to core.
 
def deg2rad(d)
Line 1,310 ⟶ 2,010:
[[350, 10], [90, 180, 270, 360], [10, 20, 30]].each {|angles|
puts "The mean angle of %p is: %f degrees" % [angles, mean_angle(angles)]
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,317 ⟶ 2,017:
The mean angle of [10, 20, 30] is: 20.000000 degrees
</pre>
 
=={{header|Rust}}==
 
<syntaxhighlight lang="rust">
use std::f64;
// the macro is from
// http://stackoverflow.com/questions/30856285/assert-eq-with-floating-
// point-numbers-and-delta
fn mean_angle(angles: &[f64]) -> f64 {
let length: f64 = angles.len() as f64;
let cos_mean: f64 = angles.iter().fold(0.0, |sum, i| sum + i.to_radians().cos()) / length;
let sin_mean: f64 = angles.iter().fold(0.0, |sum, i| sum + i.to_radians().sin()) / length;
(sin_mean).atan2(cos_mean).to_degrees()
}
 
fn main() {
let angles1 = [350.0_f64, 10.0];
let angles2 = [90.0_f64, 180.0, 270.0, 360.0];
let angles3 = [10.0_f64, 20.0, 30.0];
println!("Mean Angle for {:?} is {:.5} degrees",
&angles1,
mean_angle(&angles1));
println!("Mean Angle for {:?} is {:.5} degrees",
&angles2,
mean_angle(&angles2));
println!("Mean Angle for {:?} is {:.5} degrees",
&angles3,
mean_angle(&angles3));
}
 
macro_rules! assert_diff{
($x: expr,$y : expr, $diff :expr)=>{
if ( $x - $y ).abs() > $diff {
panic!("floating point difference is to big {}", $x - $y );
}
}
}
 
#[test]
fn calculate() {
let angles1 = [350.0_f64, 10.0];
let angles2 = [90.0_f64, 180.0, 270.0, 360.0];
let angles3 = [10.0_f64, 20.0, 30.0];
assert_diff!(0.0, mean_angle(&angles1), 0.001);
assert_diff!(-90.0, mean_angle(&angles2), 0.001);
assert_diff!(20.0, mean_angle(&angles3), 0.001);
}
</syntaxhighlight>
 
=={{header|Scala}}==
{{libheader|Scala}}<langsyntaxhighlight Scalalang="scala">trait MeanAnglesComputation {
import scala.math.{Pi, atan2, cos, sin}
 
Line 1,337 ⟶ 2,085:
assert(meanAngle(List(10, 20, 30)).round == 20, "Unexpected result with 10, 20, 30")
println("Successfully completed without errors.")
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
 
{{trans|Common Lisp}}
 
<syntaxhighlight lang="scheme">
(import (srfi 1 lists)) ;; use 'fold' from library
 
(define (average l)
(/ (fold + 0 l) (length l)))
 
(define pi 3.14159265358979323846264338327950288419716939937510582097)
 
(define (radians a)
(* pi 1/180 a))
 
(define (degrees a)
(* 180 (/ 1 pi) a))
 
(define (mean-angle angles)
(let* ((angles (map radians angles))
(cosines (map cos angles))
(sines (map sin angles)))
(degrees (atan (average sines) (average cosines)))))
 
(for-each (lambda (angles)
(display "The mean angle of ") (display angles)
(display " is ") (display (mean-angle angles)) (newline))
'((350 10) (90 180 270 360) (10 20 30)))
</syntaxhighlight>
 
<pre>
The mean angle of (350 10) is -1.614809932057922E-15
The mean angle of (90 180 270 360) is -90.0
The mean angle of (10 20 30) is 19.999999999999996
</pre>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
include "math.s7i";
Line 1,369 ⟶ 2,153:
writeln(meanAngle([] (90.0, 180.0, 270.0, 360.0)) digits 4);
writeln(meanAngle([] (10.0, 20.0, 30.0)) digits 4);
end func;</langsyntaxhighlight>{{out}}
0.0000
90.0000
Line 1,375 ⟶ 2,159:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func mean_angle(angles) {
Math.atan2(
Math.avg(angles.map { Math.deg2rad.sin(_ * Math.PI / 180) }.sum / angles.len.),
Math.avg(angles.map { Math.deg2rad.cos(_ * Math.PI / 180) }.sum / angles.len.),
) *-> 180 / Math.PI;rad2deg
}
 
[[350,10], [90,180,270,360], [10,20,30]].each { |angles|
say "The mean angle of #{angles.dump} is: #{ '%.2f' % mean_angle(angles)} degrees";
}</langsyntaxhighlight>
{{out}}
<pre>
The mean angle of [350, 10] is: 0.00 degrees
The mean angle of [90, 180, 270, 360] is: -2290.9600 degrees
The mean angle of [10, 20, 30] is: 20.00 degrees
</pre>
 
=={{header|Stata}}==
<syntaxhighlight lang="stata">mata
function meanangle(a) {
return(arg(sum(exp(C(0,a)))))
}
 
deg=pi()/180
 
meanangle((350,10)*deg)/deg
-1.61481e-15
meanangle((90,180,270,360)*deg)/deg
0
meanangle((10,20,30)*deg)/deg
20
end</syntaxhighlight>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
@inlinable public func d2r<T: FloatingPoint>(_ f: T) -> T { f * .pi / 180 }
@inlinable public func r2d<T: FloatingPoint>(_ f: T) -> T { f * 180 / .pi }
 
public func meanOfAngles(_ angles: [Double]) -> Double {
let cInv = 1 / Double(angles.count)
let (s, c) =
angles.lazy
.map(d2r)
.map({ (sin($0), cos($0)) })
.reduce(into: (0.0, 0.0), { $0.0 += $1.0; $0.1 += $1.1 })
 
return r2d(atan2(cInv * s, cInv * c))
}
 
let fmt = { String(format: "%lf", $0) }
 
print("Mean of angles (350, 10) => \(fmt(meanOfAngles([350, 10])))")
print("Mean of angles (90, 180, 270, 360) => \(fmt(meanOfAngles([90, 180, 270, 360])))")
print("Mean of angles (10, 20, 30) => \(fmt(meanOfAngles([10, 20, 30])))")</syntaxhighlight>
 
{{out}}
 
<pre>Mean of angles (350, 10) => -0.000000
Mean of angles (90, 180, 270, 360) => -90.000000
Mean of angles (10, 20, 30) => 20.000000</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc meanAngle {angles} {
set toRadians [expr {atan2(0,-1) / 180}]
set sumSin [set sumCos 0.0]
Line 1,402 ⟶ 2,232:
# Don't need to divide by counts; atan2() cancels that out
return [expr {atan2($sumSin, $sumCos) / $toRadians}]
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl"># A little pretty-printer
proc printMeanAngle {angles} {
puts [format "mean angle of \[%s\] = %.2f" \
Line 1,412 ⟶ 2,242:
printMeanAngle {350 10}
printMeanAngle {90 180 270 360}
printMeanAngle {10 20 30}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,418 ⟶ 2,248:
mean angle of [90, 180, 270, 360] = -90.00
mean angle of [10, 20, 30] = 20.00
</pre>
 
=={{header|Vala}}==
<syntaxhighlight lang="vala">double meanAngle(double[] angles) {
double y_part = 0.0;
double x_part = 0.0;
for (int i = 0; i < angles.length; i++) {
x_part += Math.cos(angles[i] * Math.PI / 180.0);
y_part += Math.sin(angles[i] * Math.PI / 180.0);
}
 
return Math.atan2(y_part / angles.length, x_part / angles.length) * 180 / Math.PI;
}
 
void main() {
double[] angleSet1 = {350.0, 10.0};
double[] angleSet2 = {90.0, 180.0, 270.0, 360.0};
double[] angleSet3 = {10.0, 20.0, 30.0};
 
print("\nMean Angle for 1st set : %lf degrees", meanAngle(angleSet1));
print("\nMean Angle for 2nd set : %lf degrees", meanAngle(angleSet2));
print("\nMean Angle for 3rd set : %lf degrees\n", meanAngle(angleSet3));
}</syntaxhighlight>
 
{{out}}
<pre>
Mean Angle for 1st set : -0.000000 degrees
Mean Angle for 2nd set : -90.000000 degrees
Mean Angle for 3rd set : 20.000000 degrees
</pre>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">Option Base 1
Private Function mean_angle(angles As Variant) As Double
Dim sins() As Double, coss() As Double
ReDim sins(UBound(angles))
ReDim coss(UBound(angles))
For i = LBound(angles) To UBound(angles)
sins(i) = Sin(WorksheetFunction.Radians(angles(i)))
coss(i) = Cos(WorksheetFunction.Radians(angles(i)))
Next i
mean_angle = WorksheetFunction.Degrees( _
WorksheetFunction.Atan2( _
WorksheetFunction.sum(coss), _
WorksheetFunction.sum(sins)))
End Function
Public Sub main()
Debug.Print Format(mean_angle([{350,10}]), "##0")
Debug.Print Format(mean_angle([{90, 180, 270, 360}]), "##0")
Debug.Print Format(mean_angle([{10, 20, 30}]), "##0")
End Sub</syntaxhighlight>{{out}}
<pre>0
-90
20</pre>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Math
 
Module Module1
 
Function MeanAngle(angles As Double()) As Double
Dim x = angles.Sum(Function(a) Cos(a * PI / 180)) / angles.Length
Dim y = angles.Sum(Function(a) Sin(a * PI / 180)) / angles.Length
Return Atan2(y, x) * 180 / PI
End Function
 
Sub Main()
Dim printMean = Sub(x As Double()) Console.WriteLine("{0:0.###}", MeanAngle(x))
printMean({350, 10})
printMean({90, 180, 270, 360})
printMean({10, 20, 30})
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>0
-90
20</pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">import math
fn mean_angle(deg []f64) f64 {
mut ss, mut sc := f64(0), f64(0)
for x in deg {
s, c := math.sincos(x * math.pi / 180)
ss += s
sc += c
}
return math.atan2(ss, sc) * 180 / math.pi
}
fn main() {
for angles in [
[f64(350), 10],
[f64(90), 180, 270, 360],
[f64(10), 20, 30],
] {
println("The mean angle of $angles is: ${mean_angle(angles)} degrees")
}
}</syntaxhighlight>
 
{{out}}
<pre>
The mean angle of [350, 10] is: -2.6644363878955713e-14 degrees
The mean angle of [90, 180, 270, 360] is: -90 degrees
The mean angle of [10, 20, 30] is: 19.999999999999996 degree
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var meanAngle = Fn.new { |angles|
var n = angles.count
var sinSum = 0
var cosSum = 0
for (angle in angles) {
sinSum = sinSum + (angle * Num.pi / 180).sin
cosSum = cosSum + (angle * Num.pi / 180).cos
}
return (sinSum/n).atan(cosSum/n) * 180 / Num.pi
}
 
var angles1 = [350, 10]
var angles2 = [90, 180, 270, 360]
var angles3 = [10, 20, 30]
 
var i = 1
for (angles in [angles1, angles2, angles3]) {
System.print("Mean for angles %(i) is : %(Fmt.f(6, meanAngle.call(angles), 2))")
i = i + 1
}</syntaxhighlight>
 
{{out}}
<pre>
Mean for angles 1 is : -0.00
Mean for angles 2 is : -90.00
Mean for angles 3 is : 20.00
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes;
 
def Pi = 3.14159265358979323846;
Line 1,442 ⟶ 2,414:
RlOut(0, MeanAng([4, 90, 180, 270, 360])); CrLf(0);
RlOut(0, MeanAng([3, 10, 20, 30])); CrLf(0);
]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,453 ⟶ 2,425:
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn meanA(a1,a2,etc){
as:=vm.arglist.apply(Tpump(List,"toFloat","toRad"));
n:=as.len();
(as.apply("sin").sum(0.0)/n)
.atan2(as.apply("cos").sum(0.0)/n)
.toDeg()
}</langsyntaxhighlight>
{{out}}
<pre>
9,485

edits