summaryrefslogtreecommitdiff
path: root/engine.php
blob: 674353ad174cb7664e8a5aca5a11e82014a99a8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php

function vptable($n) {
	$table = array();

	$v0 = 10;
	$x = 15 * sqrt($n);
	$xCeil = ceil($x);
	//$R = pow((sqrt(5)-1)/2, 3);
	$R = 0.236068;

	for($imp=0;$imp<=$xCeil;$imp++) {
		$vPrec = $v0 + $v0*( (1-pow($R,$imp/$x))/(1-$R) );
		$v = round(100*$vPrec)/100;
		$v = min($v,2*$v0);
		$table[$imp] = $v;
	}
	
	$ddv = dd($table);
	$testViol = testViol($ddv);
	while($testViol) {
		$m = minViol($ddv);
		if($m > 0) {
			$table[$m-1] = $table[$m-1] + 0.01;
			$ddv = dd($table);
		}
		$testViol = testViol($ddv);
	}
	
	return $table;
}

function vptable_discrete($n) {
	$table = array();
	$v0 = 10;

	for($v=$v0+0.5;$v<=2*$v0-0.5;$v++) {
		$i = floor(imap($v,$n));
		$table[floor($v)] = $i;
	}
	
	$i = array(-$table[10]-1);
	foreach($table as $imp) $i[] = $imp;
	$ddi = diff(diff($i));
	$testViol = testViolNegative($ddi);
	while($testViol) {
		$m = minViolNegative($ddi);
		$i[$m+1] = $i[$m+1] - 1;
		$ddi = diff(diff($i));
		$testViol = testViolNegative($ddi);
	}
	for($j=1;$j<=10;$j++) {
		$table[9+$j] = $i[$j];
	}
	
	return $table;
}

// help functions

function imap($v,$n) {
	$v0 = 10;
	$x = 15 * sqrt($n);
	$R = 0.236068;
	$logR = log($R);
	return $x * (log( 1 - (1-$R)*($v/$v0 - 1) )/$logR);
}


function dd($v) {
	$v = diff($v);
	foreach($v as $k=>$e) {
		$v[$k] = round($e*100);
	}
	$v = diff($v);
	array_unshift($v,0,0);
	return $v;
}

function diff($v) {
	$diff = array();
	for($i=0;$i<count($v)-1;$i++) {
		$diff[$i] = $v[$i+1]-$v[$i];
	}
	return $diff;
}

function testViol($v) {
	$sum = 0;
	foreach($v as $e) {
		if($e>0) $sum++;
	}
	return $sum>0;
}
function testViolNegative($v) {
	$sum = 0;
	foreach($v as $k=>$e) {
		if($e<0) $sum++;
	}
	return $sum>0;
}

function minViol($v) {
	foreach($v as $k=>$e) {
		if($e>0) return $k;
	}
	return -1;
}
function minViolNegative($v) {
	foreach($v as $k=>$e) {
		if($e<0) return $k;
	}
	return -1;
}