hi,
hier der derzeitige stand des codes:
<?php
function _checkID($name, $pw){
//TODO
return 1;
}
function testmethode($name, $pw, $anzahlSimulationen, $timeline, $prognoseHorizont){
if(doubleval($anzahlSimulationen) != 10000 || doubleval($prognoseHorizont) != 40){//abfrage ob parameter veraendert wurden
return "ErrorParams";
}
else if(_checkID($name,$pw)==1){
$a_line = explode(";",$timeline);
$lastValue = $a_line[count($a_line)-1];
$logDiff = _logDiff($a_line);
$a_line = null;
return _generateZV($anzahlSimulationen, $logDiff, 20); //testaufruf
$arrayWithChains = _generateZV($anzahlSimulationen, $logDiff, 20); //berechnet 20 log wachstumsraten
//error_log("generate zv ". implode(",",$arrayWithChains));
//testaufruf
//return implode(",",$arrayWithChains);
//testaufruf end
$output = ""; // string mit - getrennt, die wiederum die einzelnen werte der simulationen enthalten die mit ; getrennt sind
for($d=1; $d<=100; $d++){//100 durchlaeufe, bzw simulationen
if($d !=1){
$output[$d] += "-";
}
$wert = $lastValue;
for($h=1; $h<=intval($prognoseHorizont);$h++){//durchlaufe horizont
$rand_keys = array_rand($anzahlSimulationen, 1);
$wert = $wert * exp($anzahlSimulationen[$rand_keys[0]]);
$output += strval($wert);
if($h<intval($prognoseHorizont)){
$output += ";";
}
}
}
return output;
}
else {
return "null";
}
}
//----------HILFSFUNKTIONEN--------//
function _logDiff($timeline){
$logDiff = array();
for($i=0; $i<=count($timeline)-2;$i++){
$logDiff[$i] = log(doubleval($timeline[$i+1])) - log(doubleval($timeline[$i]));
}
return $logDiff;
}
function _metropolisHastings($startvalue, $iterations, $x, $horizont){
$spline = _gaussDichte($x);
$chain = array();
$chain[0] = $startvalue;
$ew = _mean($x);
$s = 0;
for($i=0; $i<=count($x)-1;$i++){
$s += pow($x[$i]-$ew ,2);
}
$s = sqrt($s/(count($x)-1));
$horizont = intval($horizont);
$iterations = intval($iterations) - 1;
for($i=0; $i<=$iterations ; $i++){
$proposal = _generateNormZV($ew, $s)[1];
/*error_log("------");
error_log($proposal);
error_log($spline->value($proposal));
error_log( _dichteNorm($chain[$i],$ew,$s));
error_log( $spline->value($chain[$i]));
error_log(_dichteNorm($proposal,$ew,$s));
return ($spline->value($proposal) ." ". _dichteNorm($chain[$i],$ew,$s)." ". $spline->value($chain[$i]) ." ". _dichteNorm($proposal,$ew,$s));*/
$probab = min(1,($spline->value($proposal) * _dichteNorm($chain[$i],$ew,$s) / ($spline->value($chain[$i]) * _dichteNorm($proposal,$ew,$s))));
//error_log("iteration: ". $i . " ew: ".$ew . " s: ". $s);
//error_log("proposal: ". $proposal . " ". _generateNormZV($ew, $s)[1]);
if(_generateNormZV($ew, $s)[1] < $probab)
{
$chain[$i +1] = $proposal;
}
else
{
$chain[$i +1] = $chain[$i];
}
//error_log("count: " . count($iterations));
}
$rand_keys = array_rand($chain, $horizont);
$out = array();
for($i=0; $i<=count($rand_keys)-1; $i++){
$out[$i] = $chain[$rand_keys[$i]];
}
//error_log("end: " . implode(";",$out));
return($out);
}
function _generateNormZV($mueh, $sigma) {
do{
$y1 = mt_rand()/ mt_getrandmax();
$y2 = mt_rand() / mt_getrandmax();
$q = pow(2 * $y1 - 1, 2) + pow(2 * $y2 - 1, 2);
}
while ($q > 1);
$p = sqrt((-2 * log($q)) / $q);
$z1 = (2 * $y1 - 1) * $p;
$z2 = (2 * $y2 - 1) * $p;
$r = array($sigma * $z1 + $mueh, $sigma * $z2 + $mueh);
return $r;
}
function _dichteNorm($zv, $mueh, $sigma){
if($sigma == 0){
return 0;
}
else{
$b = ($zv - $mueh)/$sigma;
return (exp(- 1/2 * ($b * $b)) / ($sigma * sqrt(2 * pi())) );
}
}
function _generateZV($iterationen, $x, $horizont)
{
$r = _metropolisHastings(_mean($x), $iterationen, $x, $horizont);
return $r;
}
function _mean($arr)
{
$summe = array_sum($arr);
$anzahl = count($arr);
$durchschnitt = $summe / $anzahl;
return $durchschnitt;
}
/**
* Schaetzt die Kerndichte von n zufallsvariablen x1,...,xn, mit der Gausskernfunktion und einem optimalen Gaussbantbreitenschaetzer.
* Gibt ein spline objekt zurueck.
*/
function _gaussDichte($x){
$def = array();
$bild = array();
$ew = _mean($x);
$s = 0;
for($i=0; $i<=count($x)-1;$i++){
$s += pow($x[$i]-$ew ,2);
}
$s = sqrt($s/(count($x)-1));
$h = pow((4*pow($s,5))/(3*count($x)) ,1/5);
//berechne bilder der gausskernfunktion
sort($x);
if(count($x) > 100){
$rand_keys = array_rand($x, 100);
for($i=0; $i<=count($rand_keys)-2; $i++){
$def[$i+1] = $x[$rand_keys[$i]];
}
sort($def);
$def[0] = $x[0];
$def[count($def)] = $x[count($x)-1];
}
else{
$def = $x;
}
for($i=0; $i<=count($def)-1; $i++){
$bild[strval($def[$i])] = 0;
for($k=0; $k<=count($def)-1; $k++){
$bild[strval($def[$i])] += exp(-1/2 * pow(($def[$i] - $def[$k])/$h, 2)) / sqrt(2 * pi());
}
$bild[strval($def[$i])] = $bild[strval($def[$i])] / ($h * count($def));
}
//berechne splinefunktion
$spline = new spline();
$spline -> init($def,$bild);
return $spline;
}
//----------HILFSCLASSEN--------//
class spline{
private $def;
private $bild;
private $momente;
/**
* Berechnet die Momente.
*/
public function init($d1, $b1){
$d1 = array_unique($d1);
sort($d1);
$this->def = $d1;
$this->bild = $b1;
//error_log("GERADE GEBAUT def: " . implode(";",$this->def));
//berechnung der momente per thomas algorithmus fuer tridiagonale gleichungssysteme
$d_c = array();
$d_d = array();
$d_c[0] = 0; //c1/b1
$d_d[0] = 1; //d1/b1
for($i=1; $i<=count($d1)-2; $i++){
$ah = $d1[$i] - $d1[$i-1];
$ch = $d1[$i+1] - $d1[$i];
$dh = ($this->bild[strval($d1[$i + 1])] - $this->bild[strval($d1[$i])]) / $ch - ($this->bild[strval($d1[$i])] - $this->bild[strval($d1[$i - 1])]) / $ah;
$bh = 2 * ($ah + $ch);
if($i == count($d1)-1){
$bh = 1;
}
$d_c[$i] = $ch / ($bh - $d_c[$i-1] * $ah);
$d_d[$i] = ($dh - $d_d[$i-1] * $ah) / ($dh - $d_c[$i-1] * $ah);
}
$this->momente = array();
$this->momente[count($d_d)-1] = $d_d[count($d_d)-1];
for($i=count($d_d)-2; $i>=0; $i--){
$this->momente[$i] = $d_d[$i] - $d_c[$i] * $this->momente[$i+1];
}
}
/**
* Ermittelt fuer jedes x dass im Definitionsbereich [x1,xn] liegt das Bild f(x).
*/
public function value($x){
$index = $this->_index($x);
/*error_log("---------------------");
error_log("index: " . $index);
error_log("def: " . count($this->def));
error_log("-> " . $this->def[$index] . " " . $this->def[$index +1]);
error_log("bild: " . count($this->bild));
error_log("momente: " . count($this->momente));
error_log("bild[def[index]]: " . $this->bild[strval($this->def[$index ])] . " " . $this->bild[strval($this->def[$index + 1])]);*/
$h = $this->def[$index + 1] - $this->def[$index];
$a = $this->bild[strval($this->def[$index])];
$b = ($this->bild[strval($this->def[$index + 1])] - $this->bild[strval($this->def[$index])]) / $h - ( $h * ($this->momente[$index + 1] + 2 * $this->momente[$index]) ) / 6;
$c = $this->momente[$index] / 2;
//error_log("h ".$h);
//error_log("index: " . $index . " count ". count($this->momente) . " momente: " . implode(";",$this->momente));
$d = ($this->momente[$index + 1] - $this->momente[$index]) / (6 * $h);
//error_log("hier " . ( $a + $b * ($x - $this->def[$index]) + $c * pow($x-$this->def[$index],2) + $d * pow($x-$this->def[$index],3) ));
//error_log("pow: " . $x . " " . $this->def[$index]);
//error_log("ergebniss: " . ( $a + $b * ($x - $this->def[$index]) + $c * pow($x-$this->def[$index],2) + $d * pow($x-$this->def[$index],3) ));
return ( $a + $b * ($x - $this->def[$index]) + $c * pow($x-$this->def[$index],2) + $d * pow($x-$this->def[$index],3) );
}
/**
* Berechnet den Index i mit x \in [xi,xi+1].
*/
private function _index($x){
for($k=0; $k<=count($this->def)-3; $k++){//muesste -2 sein
if($this->def[$k] <= $x && $x <= $this->def[$k+1]){
return $k;
}
}
}
}
?>
der aufruf erfolgt per testmethode("root", "pw", "10000", "1;2;3;2;1;3", "40")
ich habs soweit korrigiert, dass ich den letzten fehler in $spline->value($chain[$i]) vermute, also in meiner spline klasse.
könnt ihr mir helfen den fehler zu finden?
errorlogs der form: [15-Jun-2015 23:23:21 Europe/Paris] PHP Warning: Cannot modify header information - headers already sent by (output started at C:\wamp\www\ws\test.php:315) in C:....
versteh ich auch nicht mehr