Oh, you beat me to it. I was just about to say that using a Degree type and 
dispatching on it would be a lot more Julian. In fact, I had this great 
idea on how to use the degree sign to construct degrees:

module DegreeModule

export Degree, DegreeSign, °

immutable Degree{T<:Number} <:Number
    d::T
end

immutable DegreeSign
    filler::Bool
end

const ° = DegreeSign(true)

*(num::Number, s::DegreeSign) = Degree(num)

Base.sin(d::Degree) = sinpi(d.d/180)

end



Then it would Just Work™:

using DegreeModule

Degree(125)       # ==> Degree{Int64}(125)

130°              # ==> Degree{Int64}(130)

sin(180°)         # ==> 0.0

I'm not familiar enough with Julia to know if that is the best way to 
construct the degree sign functionality, but I thought it was kinda 
elegant. 


On Wednesday, February 5, 2014 12:18:38 PM UTC+2, Simon Byrne wrote:
>
> As I understand it, the original reason for the degree functions was for 
> matlab compatibility, but they were later modified (and pi-multiple 
> functions sinpi/cospi introduced) so as to be more accurate outside the the 
> interval [-pi/2,pi/2], as Ivar points out. Note that we haven't improved on 
> the naive approach on values within this interval, e.g. 
>
> julia> sind(30)
>
> 0.49999999999999994
> Matlab gets this wrong as well, but lies about it:
>
> >> sind(30)
>
> ans =
>
>     0.5000
>
> >> sind(30)-0.5
>
> ans =
>
>   -5.5511e-17
>
> As to their use, I don't know about the degree functions, but the 
> sinpi/cospi functions are actually used internally in a couple of places, 
> in the definition of sinc and a couple of the bessel functions.
>
> However that doesn't mean the interface couldn't be improved. One possible 
> approach I've been thinking about is defining "degree" and "pi-multiple" 
> types
>
> immutable Degree <: Real
>   deg::Float64
> end
>
> immutable PiMultiple <: Real
>   mult::Float64
> end
>
> In this way we could leverage multiple dispatch: i.e. sind(x) becomes 
> sin(Degree(x)) and sinpi(x) becomes sin(PiMultiple(x)). Of course, since 
> julia doesn't (yet) provide a way to dispatch on return types, there's not 
> an easy way to define the corresponding inverse functions, but this is 
> typically less of an issue in terms of numerical error due to the 
> constrained output range (the exception being atan2, where something like 
> this could be very 
> useful<https://github.com/JuliaLang/julia/issues/3246#issuecomment-18691772>
> .
>
> Simon
>
> On Wednesday, 5 February 2014 08:42:59 UTC, Ivar Nesje wrote:
>>
>> Hans W Borchers: Your definition is not equivalent.
>>
>> julia> sin(pi) 
>> 1.2246467991473532e-16 
>>
>> julia> sind(180) 
>> 0.0
>>
>> julia> sinpi(1) 
>> 0
>>
>> julia> sin(big(pi)) 
>> 1.096917440979352076742130626395698021050758236508687951179005716992142688513354e-77
>>  
>> with 256 bits of precision
>>
>> The answer for sin(pi) is somewhat correct, because float(pi) is not the 
>> π you know from mathematics. It is the closest representable *IEEE 754* 
>> floating 
>> point number.
>>
>> Ivar
>>
>> kl. 09:31:42 UTC+1 onsdag 5. februar 2014 skrev Hans W Borchers følgende:
>>>
>>> You could easily add these two lines of function definitions to your 
>>> code.
>>>
>>>     sind(x) = sin(degrees2radians(x))
>>>     cosd(x) = cos(degrees2radians(x))
>>>
>>> and your haversine function stands as is, not littered with conversions.
>>>
>>>
>>> On Tuesday, February 4, 2014 6:55:13 PM UTC+1, Jacob Quinn wrote:
>>>>
>>>> As someone who doesn't have to work with the functions very often or 
>>>> deal with degrees/radians conversions, I actually have found it convenient 
>>>> to have the sind functions. It saves me time from having to remember what 
>>>> the conversion is or make my code uglier littered with degrees2radians() 
>>>> conversions, for example, in the following haversine distance calc.
>>>>
>>>> haversine(lat1,lon1,lat2,lon2) = 12745.6 * 
>>>> asin(sqrt(sind((lat2-lat1)/2)^2 + cosd(lat1) * cosd(lat2) * sind((lon2 - 
>>>> lon1)/2)^2))
>>>>
>>>>

Reply via email to