Add all the A tasks
This commit is contained in:
parent
2dd7375f96
commit
051504d65b
1608 changed files with 18584 additions and 0 deletions
23
Task/Averages-Mean-angle/0DESCRIPTION
Normal file
23
Task/Averages-Mean-angle/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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.
|
||||
|
||||
If one wanted an average direction of the wind over two readings where the first reading was of 350 degrees and the second was of 10 degrees then the average of the numbers is 180 degrees, whereas if you can note that 350 degrees is equivalent to -10 degrees and so you have two readings at 10 degrees either side of zero degrees leading to a more fitting mean angle of zero degrees.
|
||||
|
||||
To calculate the mean angle of several angles:
|
||||
# Assume all angles are on the unit circle and convert them to complex numbers expressed in real and imaginary form.
|
||||
# Compute the mean of the complex numbers.
|
||||
# Convert the complex mean to polar coordinates whereupon the phase of the complex mean is the required angular mean.
|
||||
|
||||
(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>
|
||||
|
||||
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.
|
||||
|
||||
;See Also
|
||||
* [[Averages/Mean time of day]]
|
||||
34
Task/Averages-Mean-angle/Ada/averages-mean-angle.ada
Normal file
34
Task/Averages-Mean-angle/Ada/averages-mean-angle.ada
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
with Ada.Text_IO, Ada.Numerics.Generic_Elementary_Functions;
|
||||
|
||||
procedure Mean_Angles is
|
||||
|
||||
type X_Real is digits 4; -- or more digits for improved precision
|
||||
subtype Real is X_Real range 0.0 .. 360.0; -- the range of interest
|
||||
type Angles is array(Positive range <>) of Real;
|
||||
|
||||
procedure Put(R: Real) is
|
||||
package IO is new Ada.Text_IO.Float_IO(Real);
|
||||
begin
|
||||
IO.Put(R, Fore => 3, Aft => 2, Exp => 0);
|
||||
end Put;
|
||||
|
||||
function Mean_Angle(A: Angles) return Real is
|
||||
Sin_Sum, Cos_Sum: X_Real := 0.0; -- X_Real since sums might exceed 360.0
|
||||
package Math is new Ada.Numerics.Generic_Elementary_Functions(Real);
|
||||
use Math;
|
||||
begin
|
||||
for I in A'Range loop
|
||||
Sin_Sum := Sin_Sum + Sin(A(I), Cycle => 360.0);
|
||||
Cos_Sum := Cos_Sum + Cos(A(I), Cycle => 360.0);
|
||||
end loop;
|
||||
return Arctan(Sin_Sum / X_Real(A'Length), Cos_Sum / X_Real(A'Length),
|
||||
Cycle => 360.0);
|
||||
-- may raise Ada.Numerics.Argument_Error if inputs are
|
||||
-- numerically instable, e.g., when Cos_Sum is 0.0
|
||||
end Mean_Angle;
|
||||
|
||||
begin
|
||||
Put(Mean_Angle((10.0, 20.0, 30.0))); Ada.Text_IO.New_Line; -- 20.00
|
||||
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;
|
||||
30
Task/Averages-Mean-angle/C/averages-mean-angle.c
Normal file
30
Task/Averages-Mean-angle/C/averages-mean-angle.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include<math.h>
|
||||
#include<stdio.h>
|
||||
|
||||
double
|
||||
meanAngle (double *angles, int size)
|
||||
{
|
||||
double y_part = 0, x_part = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
x_part += cos (angles[i] * M_PI / 180);
|
||||
y_part += sin (angles[i] * M_PI / 180);
|
||||
}
|
||||
|
||||
return atan2 (y_part / size, x_part / size) * 180 / M_PI;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
double angleSet1[] = { 350, 10 };
|
||||
double angleSet2[] = { 90, 180, 270, 360};
|
||||
double angleSet3[] = { 10, 20, 30};
|
||||
|
||||
printf ("\nMean Angle for 1st set : %lf degrees", meanAngle (angleSet1, 2));
|
||||
printf ("\nMean Angle for 2nd set : %lf degrees", meanAngle (angleSet2, 4));
|
||||
printf ("\nMean Angle for 3rd set : %lf degrees\n", meanAngle (angleSet3, 3));
|
||||
return 0;
|
||||
}
|
||||
22
Task/Averages-Mean-angle/Go/averages-mean-angle.go
Normal file
22
Task/Averages-Mean-angle/Go/averages-mean-angle.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/cmplx"
|
||||
)
|
||||
|
||||
func deg2rad(d float64) float64 { return d * math.Pi / 180 }
|
||||
func rad2deg(r float64) float64 { return r * 180 / math.Pi }
|
||||
|
||||
func mean_angle(deg []float64) float64 {
|
||||
sum := 0i
|
||||
for _, x := range deg { sum += cmplx.Rect(1, deg2rad(x)) }
|
||||
return rad2deg(cmplx.Phase(sum))
|
||||
}
|
||||
|
||||
func main() {
|
||||
for _, angles := range [][]float64 {{350, 10}, {90, 180, 270, 360}, {10, 20, 30}} {
|
||||
fmt.Printf("The mean angle of %v is: %f degrees\n", angles, mean_angle(angles))
|
||||
}
|
||||
}
|
||||
6
Task/Averages-Mean-angle/Haskell/averages-mean-angle.hs
Normal file
6
Task/Averages-Mean-angle/Haskell/averages-mean-angle.hs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import Data.Complex (cis, phase)
|
||||
|
||||
meanAngle = (/ pi) . (* 180) . phase . sum . map (cis . (/ 180) . (* pi))
|
||||
|
||||
main = mapM_ (\angles -> putStrLn $ "The mean angle of " ++ show angles ++ " is: " ++ show (meanAngle angles) ++ " degrees")
|
||||
[[350, 10], [90, 180, 270, 360], [10, 20, 30]]
|
||||
14
Task/Averages-Mean-angle/PicoLisp/averages-mean-angle.l
Normal file
14
Task/Averages-Mean-angle/PicoLisp/averages-mean-angle.l
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
(load "@lib/math.l")
|
||||
|
||||
(de meanAngle (Lst)
|
||||
(*/
|
||||
(atan2
|
||||
(sum '((A) (sin (*/ A pi 180.0))) Lst)
|
||||
(sum '((A) (cos (*/ A pi 180.0))) Lst) )
|
||||
180.0 pi ) )
|
||||
|
||||
(for L '((350.0 10.0) (90.0 180.0 270.0 360.0) (10.0 20.0 30.0))
|
||||
(prinl
|
||||
"The mean angle of ["
|
||||
(glue ", " (mapcar round L '(0 .)))
|
||||
"] is: " (round (meanAngle L))) )
|
||||
12
Task/Averages-Mean-angle/Python/averages-mean-angle.py
Normal file
12
Task/Averages-Mean-angle/Python/averages-mean-angle.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
>>> from cmath import rect, phase
|
||||
>>> from math import radians, degrees
|
||||
>>> def mean_angle(deg):
|
||||
... return degrees(phase(sum(rect(1, radians(d)) for d in deg)/len(deg)))
|
||||
...
|
||||
>>> for angles in [[350, 10], [90, 180, 270, 360], [10, 20, 30]]:
|
||||
... print('The mean angle of', angles, 'is:', round(mean_angle(angles), 12), 'degrees')
|
||||
...
|
||||
The mean angle of [350, 10] is: -0.0 degrees
|
||||
The mean angle of [90, 180, 270, 360] is: -90.0 degrees
|
||||
The mean angle of [10, 20, 30] is: 20.0 degrees
|
||||
>>>
|
||||
57
Task/Averages-Mean-angle/REXX/averages-mean-angle.rexx
Normal file
57
Task/Averages-Mean-angle/REXX/averages-mean-angle.rexx
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*REXX program to compute the mean angle (angles expressed in degrees).*/
|
||||
numeric digits 50 /*use fifty digits of precision. */
|
||||
showDigs=10 /* ... but only show ten digits. */
|
||||
#=350 10 ; say showit(#, meanAngleD(#))
|
||||
#=90 180 270 360 ; say showit(#, meanAngleD(#))
|
||||
#=10 20 30 ; say showit(#, meanAngleD(#))
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────MEANANGD subroutine─────────────────*/
|
||||
meanAngleD: procedure; arg x; _sin=0; _cos=0
|
||||
numeric digits $d()+$d()%4
|
||||
n=words(x); do j=1 for n
|
||||
xr = d2r(d2d(word(x,j)))
|
||||
_sin = _sin + sin(xr)
|
||||
_cos = _cos + cos(xr)
|
||||
end /*j*/
|
||||
return r2d(atan2(_sin/n, _cos/n))
|
||||
/*═════════════════════════════general 1-line subs══════════════════════*/
|
||||
/*The 1-line subs were broken up into multiple lines for easier reading.*/
|
||||
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)//(2*pi())
|
||||
p: return word(arg(1),1)
|
||||
$d: return p(arg(1) digits())
|
||||
$fuzz: return min(arg(1),max(1,$d()-arg(2)))
|
||||
showit: procedure expose showDigs; numeric digits showDigs; arg a,ma
|
||||
return left('angles='a,30) 'mean angle=' format(ma,,showDigs,0)/1
|
||||
acos: procedure; arg x; if x<-1 | x>1 then call $81r -1,1,x,"ACOS"
|
||||
return .5*pi() - asin(x) /* $81r subroutine not included here.*/
|
||||
atan: if abs(arg(1))=1 then return pi()*.25*sign(arg(1))
|
||||
return asin(arg(1) / sqrt(1+arg(1)**2))
|
||||
asin: procedure; arg x; if x<-1 | x>1 then call $81r -1,1,x,"ASIN"
|
||||
s=x*x; if abs(x)>=.7 then return sign(x)*acos(sqrt(1-s),'-ASIN')
|
||||
z=x; o=x; p=z; do j=2 by 2; o=o*s*(j-1)/j; z=z+o/(j+1)
|
||||
if z=p then leave; p=z; end; return z
|
||||
atan2: procedure; arg y,x; pi=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(y/x)));otherwise z=s*atan(y/x);end; return z
|
||||
cos: procedure; arg x; x=r2r(x); a=abs(x); numeric fuzz $fuzz(5,3)
|
||||
if a=0 then return 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=2*pi()/3 then return -.5; return .sincos(1,1,-1)
|
||||
sin: procedure; arg x; x=r2r(x); numeric fuzz $fuzz(5,3)
|
||||
if x=pi()*.5 then return 1; if x==pi()*1.5 then return -1
|
||||
if abs(x)=pi() | x=0 then return 0; return .sincos(x,x,1)
|
||||
.sincos: parse arg z,_,i; x=x*x; p=z; do k=2 by 2; _=-_*x/(k*(k+i)); z=z+_
|
||||
if z=p then leave; p=z; end; return z
|
||||
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits()
|
||||
numeric digits 11; g=.sqrtGuess(); do j=0 while p>9;m.j=p; p=p%2+1
|
||||
end; do k=j+5 to 0 by -1; if m.k>11 then numeric digits m.k
|
||||
g=.5*(g+x/g); end; numeric digits d; return g/1
|
||||
.sqrtGuess: if x<0 then call er 02,x p($.ff 'SQRT') "negative"
|
||||
/*The above IF statement was left here to show checking for x<0.*/
|
||||
numeric form; m.=11; p=d+d%4+2
|
||||
parse value format(x,2,1,,0) 'E0' with g 'E' _ .;return g*.5'E'_%2
|
||||
pi: return ,
|
||||
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148
|
||||
15
Task/Averages-Mean-angle/Racket/averages-mean-angle.rkt
Normal file
15
Task/Averages-Mean-angle/Racket/averages-mean-angle.rkt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#lang racket
|
||||
|
||||
(define (mean-angle αs)
|
||||
(radians->degrees
|
||||
(mean-angle/radians
|
||||
(map degrees->radians αs))))
|
||||
|
||||
(define (mean-angle/radians αs)
|
||||
(define n (length αs))
|
||||
(atan (* (/ 1 n) (for/sum ([α_j αs]) (sin α_j)))
|
||||
(* (/ 1 n) (for/sum ([α_j αs]) (cos α_j)))))
|
||||
|
||||
(mean-angle '(350 0 10))
|
||||
(mean-angle '(90 180 270 360))
|
||||
(mean-angle '(10 20 30))
|
||||
17
Task/Averages-Mean-angle/Ruby/averages-mean-angle.rb
Normal file
17
Task/Averages-Mean-angle/Ruby/averages-mean-angle.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
require 'complex'
|
||||
|
||||
def deg2rad(d)
|
||||
d * Math::PI / 180
|
||||
end
|
||||
|
||||
def rad2deg(r)
|
||||
r * 180 / Math::PI
|
||||
end
|
||||
|
||||
def mean_angle(deg)
|
||||
rad2deg((deg.inject(0) {|z, d| z + Complex.polar(1, deg2rad(d))} / deg.length).arg)
|
||||
end
|
||||
|
||||
[[350, 10], [90, 180, 270, 360], [10, 20, 30]].each {|angles|
|
||||
puts "The mean angle of %p is: %f degrees" % [angles, mean_angle(angles)]
|
||||
}
|
||||
10
Task/Averages-Mean-angle/Tcl/averages-mean-angle-1.tcl
Normal file
10
Task/Averages-Mean-angle/Tcl/averages-mean-angle-1.tcl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
proc meanAngle {angles} {
|
||||
set toRadians [expr {atan2(0,-1) / 180}]
|
||||
set sumSin [set sumCos 0.0]
|
||||
foreach a $angles {
|
||||
set sumSin [expr {$sumSin + sin($a * $toRadians)}]
|
||||
set sumCos [expr {$sumCos + cos($a * $toRadians)}]
|
||||
}
|
||||
# Don't need to divide by counts; atan2() cancels that out
|
||||
return [expr {atan2($sumSin, $sumCos) / $toRadians}]
|
||||
}
|
||||
9
Task/Averages-Mean-angle/Tcl/averages-mean-angle-2.tcl
Normal file
9
Task/Averages-Mean-angle/Tcl/averages-mean-angle-2.tcl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# A little pretty-printer
|
||||
proc printMeanAngle {angles} {
|
||||
puts [format "mean angle of \[%s\] = %.2f" \
|
||||
[join $angles ", "] [meanAngle $angles]]
|
||||
}
|
||||
|
||||
printMeanAngle {350 10}
|
||||
printMeanAngle {90 180 270 360}
|
||||
printMeanAngle {10 20 30}
|
||||
Loading…
Add table
Add a link
Reference in a new issue