Minkowski question-mark function: Difference between revisions
Content added Content deleted
m (→{{header|J}}) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 30: | Line 30: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">-V MAXITER = 151 |
||
F minkowski(x) -> Float |
F minkowski(x) -> Float |
||
Line 119: | Line 119: | ||
print(‘#2.16 #2.16’.format(minkowski(0.5 * (1 + sqrt(5))), 5.0 / 3.0)) |
print(‘#2.16 #2.16’.format(minkowski(0.5 * (1 + sqrt(5))), 5.0 / 3.0)) |
||
print(‘#2.16 #2.16’.format(minkowski_inv(-5.0 / 9.0), (sqrt(13) - 7) / 6)) |
print(‘#2.16 #2.16’.format(minkowski_inv(-5.0 / 9.0), (sqrt(13) - 7) / 6)) |
||
print(‘#2.16 #2.16’.format(minkowski(minkowski_inv(0.718281828)), minkowski_inv(minkowski(0.1213141516171819))))</ |
print(‘#2.16 #2.16’.format(minkowski(minkowski_inv(0.718281828)), minkowski_inv(minkowski(0.1213141516171819))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 130: | Line 130: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
{{works with|Factor|0.99 2020-08-14}} |
{{works with|Factor|0.99 2020-08-14}} |
||
< |
<syntaxhighlight lang="factor">USING: formatting kernel make math math.constants |
||
math.continued-fractions math.functions math.parser |
math.continued-fractions math.functions math.parser |
||
math.statistics sequences sequences.extras splitting.monotonic |
math.statistics sequences sequences.extras splitting.monotonic |
||
Line 165: | Line 165: | ||
phi ? 5 3 /f compare |
phi ? 5 3 /f compare |
||
-5/9 ?⁻¹ 13 sqrt 7 - 6 /f compare |
-5/9 ?⁻¹ 13 sqrt 7 - 6 /f compare |
||
0.718281828 ?⁻¹ ? 0.1213141516171819 ? ?⁻¹ compare</ |
0.718281828 ?⁻¹ ? 0.1213141516171819 ? ?⁻¹ compare</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 175: | Line 175: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">#define MAXITER 151 |
||
function minkowski( x as double ) as double |
function minkowski( x as double ) as double |
||
Line 246: | Line 246: | ||
print minkowski_inv( -5./9 ), (sqr(13)-7)/6 |
print minkowski_inv( -5./9 ), (sqr(13)-7)/6 |
||
print minkowski(minkowski_inv(0.718281828)), minkowski_inv(minkowski(0.1213141516171819)) |
print minkowski(minkowski_inv(0.718281828)), minkowski_inv(minkowski(0.1213141516171819)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> 1.666666666669698 1.666666666666667 |
<pre> 1.666666666669698 1.666666666666667 |
||
Line 254: | Line 254: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
{{trans|FreeBASIC}} |
{{trans|FreeBASIC}} |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 358: | Line 358: | ||
fmt.Printf("%19.16f %19.16f\n", minkowski(minkowskiInv(0.718281828)), |
fmt.Printf("%19.16f %19.16f\n", minkowski(minkowskiInv(0.718281828)), |
||
minkowskiInv(minkowski(0.1213141516171819))) |
minkowskiInv(minkowski(0.1213141516171819))) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 376: | Line 376: | ||
This recursive definition can be implemented as lazy corecursion, i.e. by generating two infinite binary trees: '''mediant'''-based Stern-Brocot tree, containing all rationals, and '''mean'''-based tree with corresponding values of Minkowsky ?-function. There is one-to-one correspondence between these two trees so both {{math|?(x)}} and {{math|?<sup>-1</sup>(x)}} may be implemented as mapping between them. For details see the paper [[https://habr.com/ru/post/591949/]] (in Russian). |
This recursive definition can be implemented as lazy corecursion, i.e. by generating two infinite binary trees: '''mediant'''-based Stern-Brocot tree, containing all rationals, and '''mean'''-based tree with corresponding values of Minkowsky ?-function. There is one-to-one correspondence between these two trees so both {{math|?(x)}} and {{math|?<sup>-1</sup>(x)}} may be implemented as mapping between them. For details see the paper [[https://habr.com/ru/post/591949/]] (in Russian). |
||
< |
<syntaxhighlight lang="haskell">import Data.Tree |
||
import Data.Ratio |
import Data.Ratio |
||
import Data.List |
import Data.List |
||
Line 431: | Line 431: | ||
questionMarkF, invQuestionMarkF :: Double -> Double |
questionMarkF, invQuestionMarkF :: Double -> Double |
||
questionMarkF = sternBrocotF ==> minkowskiF |
questionMarkF = sternBrocotF ==> minkowskiF |
||
invQuestionMarkF = minkowskiF ==> sternBrocotF</ |
invQuestionMarkF = minkowskiF ==> sternBrocotF</syntaxhighlight> |
||
<pre>λ> mapM_ print $ take 4 $ levels farey |
<pre>λ> mapM_ print $ take 4 $ levels farey |
||
Line 469: | Line 469: | ||
Implementation: |
Implementation: |
||
< |
<syntaxhighlight lang="j">ITERCOUNT=: 52 |
||
minkowski=: {{ |
minkowski=: {{ |
||
Line 499: | Line 499: | ||
end. |
end. |
||
(+%)/(<.y),cf |
(+%)/(<.y),cf |
||
}}</ |
}}</syntaxhighlight> |
||
That said, note that this algorithm introduces significant numeric instability for √7 divided by 3: |
That said, note that this algorithm introduces significant numeric instability for √7 divided by 3: |
||
< |
<syntaxhighlight lang="j"> (minkowski@invmink - invmink@minkowski) (p:%%:)3 |
||
1.10713e_6</ |
1.10713e_6</syntaxhighlight> |
||
I see this same instability using the python implementation and appending: |
I see this same instability using the python implementation and appending: |
||
< |
<syntaxhighlight lang="python"> print( |
||
"{:19.16f} {:19.16f}".format( |
"{:19.16f} {:19.16f}".format( |
||
minkowski(minkowski_inv(4.04145188432738056)), |
minkowski(minkowski_inv(4.04145188432738056)), |
||
minkowski_inv(minkowski(4.04145188432738056)), |
minkowski_inv(minkowski(4.04145188432738056)), |
||
) |
) |
||
)</ |
)</syntaxhighlight> |
||
Using an exact fraction for 4.04145188432738056 and bumping the iteration count from 52 up to 200 changes that difference to 1.43622e_12. |
Using an exact fraction for 4.04145188432738056 and bumping the iteration count from 52 up to 200 changes that difference to 1.43622e_12. |
||
Line 519: | Line 519: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{trans|FreeBASIC}} |
{{trans|FreeBASIC}} |
||
< |
<syntaxhighlight lang="julia">function minkowski(x) |
||
p = Int(floor(x)) |
p = Int(floor(x)) |
||
(x > 1 || x < 0) && return p + minkowski(x) |
(x > 1 || x < 0) && return p + minkowski(x) |
||
Line 587: | Line 587: | ||
println(" ", minkowski(minkowski_inv(0.718281828)), " ", |
println(" ", minkowski(minkowski_inv(0.718281828)), " ", |
||
minkowski_inv(minkowski(0.1213141516171819))) |
minkowski_inv(minkowski(0.1213141516171819))) |
||
</ |
</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
1.6666666666696983 1.6666666666666667 |
1.6666666666696983 1.6666666666666667 |
||
Line 595: | Line 595: | ||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">ClearAll[InverseMinkowskiQuestionMark] |
||
InverseMinkowskiQuestionMark[val_] := Module[{x}, (x /. FindRoot[MinkowskiQuestionMark[x] == val, {x, Floor[val], Ceiling[val]}])] |
InverseMinkowskiQuestionMark[val_] := Module[{x}, (x /. FindRoot[MinkowskiQuestionMark[x] == val, {x, Floor[val], Ceiling[val]}])] |
||
MinkowskiQuestionMark[GoldenRatio] |
MinkowskiQuestionMark[GoldenRatio] |
||
InverseMinkowskiQuestionMark[-5/9] // RootApproximant |
InverseMinkowskiQuestionMark[-5/9] // RootApproximant |
||
MinkowskiQuestionMark[InverseMinkowskiQuestionMark[0.1213141516171819]] |
MinkowskiQuestionMark[InverseMinkowskiQuestionMark[0.1213141516171819]] |
||
InverseMinkowskiQuestionMark[MinkowskiQuestionMark[0.1213141516171819]]</ |
InverseMinkowskiQuestionMark[MinkowskiQuestionMark[0.1213141516171819]]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>5/3 |
<pre>5/3 |
||
Line 609: | Line 609: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="nim">import math, strformat |
||
const MaxIter = 151 |
const MaxIter = 151 |
||
Line 695: | Line 695: | ||
echo &"{minkowskiInv(-5/9):19.16f}, {(sqrt(13.0)-7)/6:19.16f}" |
echo &"{minkowskiInv(-5/9):19.16f}, {(sqrt(13.0)-7)/6:19.16f}" |
||
echo &"{minkowski(minkowskiInv(0.718281828)):19.16f}, " & |
echo &"{minkowski(minkowskiInv(0.718281828)):19.16f}, " & |
||
&"{minkowskiInv(minkowski(0.1213141516171819)):19.16f}"</ |
&"{minkowskiInv(minkowski(0.1213141516171819)):19.16f}"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 704: | Line 704: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
use warnings; |
use warnings; |
||
use feature 'say'; |
use feature 'say'; |
||
Line 771: | Line 771: | ||
printf "%19.16f %19.16f\n", minkowski(0.5*(1 + sqrt(5))), 5/3; |
printf "%19.16f %19.16f\n", minkowski(0.5*(1 + sqrt(5))), 5/3; |
||
printf "%19.16f %19.16f\n", minkowskiInv(-5/9), (sqrt(13)-7)/6; |
printf "%19.16f %19.16f\n", minkowskiInv(-5/9), (sqrt(13)-7)/6; |
||
printf "%19.16f %19.16f\n", minkowski(minkowskiInv(0.718281828)), minkowskiInv(minkowski(0.1213141516171819));</ |
printf "%19.16f %19.16f\n", minkowski(minkowskiInv(0.718281828)), minkowskiInv(minkowski(0.1213141516171819));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 1.6666666666696983 1.6666666666666667 |
<pre> 1.6666666666696983 1.6666666666666667 |
||
Line 779: | Line 779: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{trans|FreeBASIC}} |
{{trans|FreeBASIC}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAXITER</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">151</span> |
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAXITER</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">151</span> |
||
Line 849: | Line 849: | ||
<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;">"%20.16f %20.16f\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">minkowski</span><span style="color: #0000FF;">(</span><span style="color: #000000;">minkowski_inv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.718281828</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;">"%20.16f %20.16f\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">minkowski</span><span style="color: #0000FF;">(</span><span style="color: #000000;">minkowski_inv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.718281828</span><span style="color: #0000FF;">)),</span> |
||
<span style="color: #000000;">minkowski_inv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">minkowski</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1213141516171819</span><span style="color: #0000FF;">))})</span> |
<span style="color: #000000;">minkowski_inv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">minkowski</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1213141516171819</span><span style="color: #0000FF;">))})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 859: | Line 859: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="python">import math |
||
MAXITER = 151 |
MAXITER = 151 |
||
Line 972: | Line 972: | ||
) |
) |
||
) |
) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 983: | Line 983: | ||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
{{trans|Go}} |
{{trans|Go}} |
||
<lang |
<syntaxhighlight lang="raku" line># 20201120 Raku programming solution |
||
my \MAXITER = 151; |
my \MAXITER = 151; |
||
Line 1,047: | Line 1,047: | ||
printf "%19.16f %19.16f\n", minkowskiInv(-5/9), (13.sqrt-7)/6; |
printf "%19.16f %19.16f\n", minkowskiInv(-5/9), (13.sqrt-7)/6; |
||
printf "%19.16f %19.16f\n", minkowski(minkowskiInv(0.718281828)), |
printf "%19.16f %19.16f\n", minkowski(minkowskiInv(0.718281828)), |
||
minkowskiInv(minkowski(0.1213141516171819))</ |
minkowskiInv(minkowski(0.1213141516171819))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 1.6666666666696983 1.6666666666666667 |
<pre> 1.6666666666696983 1.6666666666666667 |
||
Line 1,056: | Line 1,056: | ||
{{trans|FreeBASIC}} |
{{trans|FreeBASIC}} |
||
{{trans|Phix}} |
{{trans|Phix}} |
||
< |
<syntaxhighlight lang="rexx">/*REXX program uses the Minkowski question─mark function to convert a continued fraction*/ |
||
numeric digits 40 /*use enough dec. digits for precision.*/ |
numeric digits 40 /*use enough dec. digits for precision.*/ |
||
say fmt( mink( 0.5 * (1+sqrt(5) ) ) ) fmt( 5/3 ) |
say fmt( mink( 0.5 * (1+sqrt(5) ) ) ) fmt( 5/3 ) |
||
Line 1,097: | Line 1,097: | ||
numeric form; m.=9; parse value format(x,2,1,,0) 'E0' with g "E" _ .; g=g *.5'e'_ %2 |
numeric form; m.=9; 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 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</ |
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= when using the internal default inputs:}} |
{{out|output|text= when using the internal default inputs:}} |
||
<pre> |
<pre> |
||
Line 1,108: | Line 1,108: | ||
{{trans|FreeBASIC}} |
{{trans|FreeBASIC}} |
||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
< |
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt |
||
var MAXITER = 151 |
var MAXITER = 151 |
||
Line 1,191: | Line 1,191: | ||
Fmt.print("$17.14f $17.14f", minkowskiInv.call(-5/9), (13.sqrt - 7)/6) |
Fmt.print("$17.14f $17.14f", minkowskiInv.call(-5/9), (13.sqrt - 7)/6) |
||
Fmt.print("$17.14f $17.14f", minkowski.call(minkowskiInv.call(0.718281828)), |
Fmt.print("$17.14f $17.14f", minkowski.call(minkowskiInv.call(0.718281828)), |
||
minkowskiInv.call(minkowski.call(0.1213141516171819)))</ |
minkowskiInv.call(minkowski.call(0.1213141516171819)))</syntaxhighlight> |
||
{{out}} |
{{out}} |