2012-03-26 2 views
0

私は、pi、phi、2、3などの平方根のような不合理な数値の近似分数を得るために使用した不器用なPHPコードを持っています。私はMatLabで使用できる数式を取得し、両方のデータテーブルを取得し、近似の小数点数に基づいてプロットを描きたいと思います。たぶん誰か、すでにこのことからつかむことができますが、私はケースを補完するためにPHPコードを提供します:MatLabの非合理的な数値から近似の小数を生成する方法は?

$n = phi(); # irrational number (imaginary/complex number?) 
$x = 500; # how many numbers to check 
$max = 50; # how many instances to show 
$precision = 0.0001; 

# check every i against every j and make a comparison how near their values are to each other 
for ($i=1; $i<$x; $i++) { 
    for ($j=1; $j<$x; $j++) { 
     # compared value is stored on array. very distant numbers needs to be discarded ($precision) or array gets easily too big, limit 64k 
     if (($d = abs(($n - ($i/$j)))) && $d > $precision) continue; 
     $c[] = array($i, $j, $d); 
    } 
} 

# sort comparison chart by third index (2) 
array_qsort($c, 2); 

# print max best values from the sorted comparison chart 
$count = count($c); 
echo "closest fraction numbers for $n from $count calculated values are:<br />\n<br />\n"; 
$r = 0; 
foreach ($c as $abc) { 
    $r++; 
    $d = $abc[0]/$abc[1]; 
    echo $abc[0] . '/' . $abc[1] . ' = ' . $d . ' (' . round($abc[2]*(1/$precision), 10) . ')' . "<br />\n"; 
    if ($r > $max) break; 
} 

答えて

1

より効率的なアルゴリズムがここにありますがいずれかです。

function [a, b, c] = approxfrac(r, precision) 
a = floor(r); 
r = r - a; 
if r==0, 
    b=0; 
    c=1; 
    return 
end 
p1 = 0; q1 = 1; 
p2 = 1; q2 = 1; 
b = p1+p2; 
c = q1+q2; 
while abs(r-b/c) > precision, 
    if r>b/c, 
     p1 = b; q1 = c; 
    else 
     p2 = b; q2 = c; 
    end 
    b = p1+p2; 
    c = q1+q2; 
end 
end 
+0

素晴らしい! 'd =(a * c)+ b;)'私は '[a、b、c、d] = approxfrac(pi、0.01);' - >を呼び出すと、 '3、1、7、22'ここで、fractionは' 22/7'または '3 1/7'です。 私は部分解決策として、私はまだ私のようなnベストソリューションの配列を取得したいので、 PHPコード。精度をシフトするだけでこの機能を使用できますか? – MarkokraM

+1

その後、whileループのbとcの値をすべて配列に追加し、それらの配列をbとcに返すことで、すべてのbとcの値を追跡することができます。各反復において、b/c比は、以前の反復よりも所望の数(r-a)に近く、したがって、それらは既にソートされている。 –

関連する問題