Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Newtonin menetelmä

kayttaja-2791 [17.04.2005 18:51:39]

#

Laskee funktion likiarvon Newtonin menetelmällä kunhan syötät funktion ja sen derivaatan.

Täysi html-versio. Saa soveltaa kuten haluaa kunhan et esitä alkuperäistä koodia omanasi.

Versio 1 - 17.04.2005 - Ensimmäinen julkaistu versio

<?php
/*
Laskee funktion likiarvon Newtonin menetelmällä kunhan syötät funktion ja sen derivaatan.

Täysi html-versio. Saa soveltaa kuten haluaa.

--Versio 1 - 17.04.2005 - Ensimmäinen julkaistu versio
*/
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Newtonin menetelmä</title>
		<style type="text/css">
			body {
			  font: 90% verdana, sans-serif;
			}
			input {
			  background: #e5f5ff;
			  border: 1px solid black;
			  margin: 3px;
			  padding-left: 3px;
			  text-align: left;
			}
			sub {
				font-size: 60%;
			}
		</style>
	</head>
	<body>
		<h3>Newtonin menetelmä</h3>
		<p>
			Newtonin menetelmä on iteratiivinen,
			eli sitä ajetaan useita kierroksia ja sen saama likiarvo tarkentuu kierros kierrokselta.
			Siispä siinä lähdetään jostain alkuarvauksesta (tässä tapauksessa 2) josta funktion todellinen arvo alkaa tarkentumaan yllättävän nopeasti.
		</p>
		<p>
			Menetelmä menee yksinkertaisuudessaan seuraavasti: <br />
			x<sub>i+1</sub> = x<sub>i</sub> - f(x<sub>i</sub>) / f´(x<sub>i</sub>)
		</p>
		<p>
			Eli likiarvon voit laskea mille tahansa funktiolle kunhan vain osaat laskea itse sen derivaatan.
		</p>
		<p>
			Oletuksena laskin laskee luvun 50 neliöjuuren.
		</p>
		<?php
		if (!$funktio = $_GET['funktio'])
			$funktio = "x*x - 50";

		if (!$derivaatta = $_GET['derivaatta'])
			$derivaatta = "2*x";

		if (!$iteraatioita = $_GET['iteraatioita'])
			$iteraatioita = 10;

		if (!$tarkkuus = $_GET['tarkkuus']) //Montako desimaalia
			$tarkkuus = 4;
		//Alkuarvaus, muuten ei paljoa väliä kunhan ei ole nolla ettei nimittäjä mene nollaksi
		$tulos = 2;

		print "
		<form action=\"$_SERVER[PHP_SELF]\">
		\tf(x) = <input name='funktio' type=text value='".$funktio."' size=20> = 0 <br/>
		\tf´(x) = <input name='derivaatta' type=text value='".$derivaatta."' size=19> = 0 <br/>
		\tIteraatioita <input name='iteraatioita' type=text value='".$iteraatioita."' size=4> <br />
		\tTarkkuus <input name='tarkkuus' type=text value='".$tarkkuus."' size=4> (desimaalia) <br />
		\t&nbsp;&nbsp;<input type=submit value=Laske></form>";

		for ($i = 1; $i <= $iteraatioita; $i++) {
			$uusiderivaatta = str_replace("x", $tulos, $derivaatta);
			$uusifunktio = str_replace("x", $tulos, $funktio);

			eval("\$uusifunktio = ".$uusifunktio.";"); //Kiitos Ohjelmointiputkan ederth tästä vinkistä foorumilla
			eval("\$uusiderivaatta = ".$uusiderivaatta.";");

			$tulos = $tulos - $uusifunktio/$uusiderivaatta;
			$tulokset[$i] = $tulos;
		}
		echo "\n<p>\n\tNewtonin menelmän palauttama likiarvo: <b>",round($tulos, $tarkkuus),"</b>\n</p>";

		echo "\n\n<p>\n\t<b>Iteraatiot</b> <br />";
		foreach ($tulokset as $nro => $tulos) {
			//Tässä muutetaan lukusijoitus 1 -> 01 tai 1 -> 001 riippuen iteraatioiden määrästä
			if ((strlen(count($tulokset)) - strlen($nro)) > 0) {
				while ((strlen(count($tulokset)) - strlen($nro)) > 0)
					$nro = "0".$nro;
			}
			echo "\n\t",$nro,". ",round($tulos, $tarkkuus)," <br />";
		}
		?>
		</p>
	</body>
</html>

tsuriga [19.04.2005 16:48:13]

#

Versio 2 voisi muodostaa itse sen derivaatan ja inputeissa joistakin attribuuteista puuttuu ''. Lisäksi en antaisi käyttää evalia sivuillani ilman mitään tarkistuksia koskien lausekkeen sisältöä. Esimerkiksi jos laitan funktioksi "0; foreach(glob(*.*) as $file) { unlink($file)) } $y=0". Tässä tapauksessa varmaankin tahdot, että lauseke sisältää vain numeroita, laskuoperaattoreita sekä x-kirjaimia.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta