Bonkers
19.03.2010, 19:33
Hey,
Ich musste im Zuge eines anderen Skriptes das Newton-Verfahren Anwenden, um die Nullstellen einer Funktion zu errechnen.
Hab das ganze jetzt mal in ein eigenständiges Skript gepackt.
Das Newton-Verfahren nimmt man (glaube Ich), in der 11. Klasse durch.
Der erste Sprung über die X-Achse wird automatisch berechnet, um die benötigten Schritte stark einzuschränken!
Auch wenn ihr das Skript an sich nicht braucht freue ich mich über jede Kritik.
Usage:
Das erste Argument gibt die Anzahl an Schritten an. 0 ist default.
Wenn ihr 0 angebt, dann stoppt das Skript automatisch wenn die Nullstelle gefunden wurde! Deshalb ist 0 absolut zu empfehlen.
Die Funktion und die Ableitung sind fest im Code verankert, können aber in den 2 Subs beliebig verändert werden. Achtet darauf dass " ** " einem " ^ " entspricht ;)
Im Skript ist
return $x**3+2*$x-1; also
f(x) = x^3+2*x-1
So, hier das Skript. Viel Spaß!
our $start = -50; #
our $count = 100; # Range to test for switch on x-axis
our $buffer;
sub f { # Your f(x). ** = ^
my $x = shift;
return $x**3+2*$x-1;
}
sub abl { # Derivation of f(x). ** = ^
my $x = shift;
return 3*$x**2+2;
}
print "\n".("\t"x3)."### Newton's method by Bonkers ### \n\n";
print "\n\tSearching for switch on x-axis (From ".$start." to ".$count.")...\n\n";
sub isPos { # Is the value positive?
my $cc = shift;
#if ($cc > 0) { return 1 } else { return 0 };
return $cc > 0;
}
sub output { # To format Output
my $work = shift;
if (length($work) > 9) { return substr($work, 0,10); } else { return $work.(" "x(10-length($work))) }
}
for (my $i = $start; $i < ($start+$count); $i++) {
$buffer = f($i);
my $sec = f($i+1);
if (isPos($buffer) != isPos($sec)) {$buffer = $i - 1; $i = ($start+$count); }
}
print "\tDone. Selected Value to start with: xn = ".$buffer."\n\n";
our $maximum = $ARGV[0];
if ($maximum != 0) { if ($maximum == "") { $maximum = 100; }}
print "\tMaximum steps, taken from first Argument (Default is 0) : ".$maximum."\n\tUse 0 for Auto-Stop.\n\n\nPress Enter to start. "; <STDIN>;
print "\n\n\t ".("_"x62)."\n\t| Xn | f(xn) | f'(xn) | 1-xn |"."\n\t|".("-"x62)."\n";
print "\t| ".output($buffer)." | ".output(f($buffer))." | ".output(abl($buffer))." | ".output(1-(f($buffer)/abl($buffer)))." | \n";
for (my $counter = -1; $counter < $maximum;) {
$buffer = 1-(f($buffer)/abl($buffer));
print "\t| ".output($buffer)." | ".output(f($buffer))." | ".output(abl($buffer))." | ".output(1-(f($buffer)/abl($buffer)))." | \n";
if ($maximum != 0) { $counter++; } else { if ($buffer eq (1-(f($buffer)/abl($buffer)))) { $maximum = 1; $counter = 1;} }
}
print "\t-".("-"x62).("\n"x3)."\t\t Done :)\n\n";
Beispiel-Output:
[root@archBox Desktop]# perl math.pl 20
### Newton's method by Bonkers ###
Searching for switch on x-axis (From -50 to 100)...
Done. Selected Value to start with: xn = -1
Maximum steps, taken from first Argument (Default is 100) : 20
Press Enter to start.
__________________________________________________ ____________
| Xn | f(xn) | f'(xn) | 1-xn |
|--------------------------------------------------------------
| -1 | -4 | 5 | 1.8 |
| 1.8 | 8.432 | 11.72 | 1.8 |
| 0.28054607 | -0.4168271 | 2.23611830 | 0.28054607 |
| 1.18640657 | 3.04275227 | 6.22268171 | 1.18640657 |
| 0.51102235 | 0.15549504 | 2.78343152 | 0.51102235 |
| 0.94413548 | 1.72986563 | 4.67417546 | 0.94413548 |
| 0.62990999 | 0.50975982 | 3.19035979 | 0.62990999 |
| 0.84021870 | 1.27360447 | 4.11790240 | 0.84021870 |
| 0.69071523 | 0.71096210 | 3.43126261 | 0.69071523 |
| 0.79279869 | 1.08389495 | 3.88558929 | 0.79279869 |
| 0.72104747 | 0.81697434 | 3.55972836 | 0.72104747 |
| 0.77049531 | 0.99840520 | 3.78098908 | 0.77049531 |
| 0.73594073 | 0.87047341 | 3.62482628 | 0.73594073 |
| 0.75985789 | 0.95844559 | 3.73215206 | 0.75985789 |
| 0.74319224 | 0.89687536 | 3.65700413 | 0.74319224 |
| 0.75475134 | 0.93944647 | 3.70894875 | 0.75475134 |
| 0.74670815 | 0.90976067 | 3.67271921 | 0.74670815 |
| 0.75229234 | 0.93033984 | 3.69783130 | 0.75229234 |
| 0.74840933 | 0.91601509 | 3.68034958 | 0.74840933 |
| 0.75110649 | 0.92595796 | 3.69248290 | 0.75110649 |
| 0.74923161 | 0.91904292 | 3.68404405 | 0.74923161 |
---------------------------------------------------------------
Done :)
Ich muss wohl noch eine Funktion zum Runden einbauen, aber nur wenn jemand Verwendung für das Skript hat.
Changelog:
19.3.2010:
- Added 0 as Maximum to activate automatic stopping, when the point has been found. You can now use 'perl math.pl 0'.
Ich musste im Zuge eines anderen Skriptes das Newton-Verfahren Anwenden, um die Nullstellen einer Funktion zu errechnen.
Hab das ganze jetzt mal in ein eigenständiges Skript gepackt.
Das Newton-Verfahren nimmt man (glaube Ich), in der 11. Klasse durch.
Der erste Sprung über die X-Achse wird automatisch berechnet, um die benötigten Schritte stark einzuschränken!
Auch wenn ihr das Skript an sich nicht braucht freue ich mich über jede Kritik.
Usage:
Das erste Argument gibt die Anzahl an Schritten an. 0 ist default.
Wenn ihr 0 angebt, dann stoppt das Skript automatisch wenn die Nullstelle gefunden wurde! Deshalb ist 0 absolut zu empfehlen.
Die Funktion und die Ableitung sind fest im Code verankert, können aber in den 2 Subs beliebig verändert werden. Achtet darauf dass " ** " einem " ^ " entspricht ;)
Im Skript ist
return $x**3+2*$x-1; also
f(x) = x^3+2*x-1
So, hier das Skript. Viel Spaß!
our $start = -50; #
our $count = 100; # Range to test for switch on x-axis
our $buffer;
sub f { # Your f(x). ** = ^
my $x = shift;
return $x**3+2*$x-1;
}
sub abl { # Derivation of f(x). ** = ^
my $x = shift;
return 3*$x**2+2;
}
print "\n".("\t"x3)."### Newton's method by Bonkers ### \n\n";
print "\n\tSearching for switch on x-axis (From ".$start." to ".$count.")...\n\n";
sub isPos { # Is the value positive?
my $cc = shift;
#if ($cc > 0) { return 1 } else { return 0 };
return $cc > 0;
}
sub output { # To format Output
my $work = shift;
if (length($work) > 9) { return substr($work, 0,10); } else { return $work.(" "x(10-length($work))) }
}
for (my $i = $start; $i < ($start+$count); $i++) {
$buffer = f($i);
my $sec = f($i+1);
if (isPos($buffer) != isPos($sec)) {$buffer = $i - 1; $i = ($start+$count); }
}
print "\tDone. Selected Value to start with: xn = ".$buffer."\n\n";
our $maximum = $ARGV[0];
if ($maximum != 0) { if ($maximum == "") { $maximum = 100; }}
print "\tMaximum steps, taken from first Argument (Default is 0) : ".$maximum."\n\tUse 0 for Auto-Stop.\n\n\nPress Enter to start. "; <STDIN>;
print "\n\n\t ".("_"x62)."\n\t| Xn | f(xn) | f'(xn) | 1-xn |"."\n\t|".("-"x62)."\n";
print "\t| ".output($buffer)." | ".output(f($buffer))." | ".output(abl($buffer))." | ".output(1-(f($buffer)/abl($buffer)))." | \n";
for (my $counter = -1; $counter < $maximum;) {
$buffer = 1-(f($buffer)/abl($buffer));
print "\t| ".output($buffer)." | ".output(f($buffer))." | ".output(abl($buffer))." | ".output(1-(f($buffer)/abl($buffer)))." | \n";
if ($maximum != 0) { $counter++; } else { if ($buffer eq (1-(f($buffer)/abl($buffer)))) { $maximum = 1; $counter = 1;} }
}
print "\t-".("-"x62).("\n"x3)."\t\t Done :)\n\n";
Beispiel-Output:
[root@archBox Desktop]# perl math.pl 20
### Newton's method by Bonkers ###
Searching for switch on x-axis (From -50 to 100)...
Done. Selected Value to start with: xn = -1
Maximum steps, taken from first Argument (Default is 100) : 20
Press Enter to start.
__________________________________________________ ____________
| Xn | f(xn) | f'(xn) | 1-xn |
|--------------------------------------------------------------
| -1 | -4 | 5 | 1.8 |
| 1.8 | 8.432 | 11.72 | 1.8 |
| 0.28054607 | -0.4168271 | 2.23611830 | 0.28054607 |
| 1.18640657 | 3.04275227 | 6.22268171 | 1.18640657 |
| 0.51102235 | 0.15549504 | 2.78343152 | 0.51102235 |
| 0.94413548 | 1.72986563 | 4.67417546 | 0.94413548 |
| 0.62990999 | 0.50975982 | 3.19035979 | 0.62990999 |
| 0.84021870 | 1.27360447 | 4.11790240 | 0.84021870 |
| 0.69071523 | 0.71096210 | 3.43126261 | 0.69071523 |
| 0.79279869 | 1.08389495 | 3.88558929 | 0.79279869 |
| 0.72104747 | 0.81697434 | 3.55972836 | 0.72104747 |
| 0.77049531 | 0.99840520 | 3.78098908 | 0.77049531 |
| 0.73594073 | 0.87047341 | 3.62482628 | 0.73594073 |
| 0.75985789 | 0.95844559 | 3.73215206 | 0.75985789 |
| 0.74319224 | 0.89687536 | 3.65700413 | 0.74319224 |
| 0.75475134 | 0.93944647 | 3.70894875 | 0.75475134 |
| 0.74670815 | 0.90976067 | 3.67271921 | 0.74670815 |
| 0.75229234 | 0.93033984 | 3.69783130 | 0.75229234 |
| 0.74840933 | 0.91601509 | 3.68034958 | 0.74840933 |
| 0.75110649 | 0.92595796 | 3.69248290 | 0.75110649 |
| 0.74923161 | 0.91904292 | 3.68404405 | 0.74923161 |
---------------------------------------------------------------
Done :)
Ich muss wohl noch eine Funktion zum Runden einbauen, aber nur wenn jemand Verwendung für das Skript hat.
Changelog:
19.3.2010:
- Added 0 as Maximum to activate automatic stopping, when the point has been found. You can now use 'perl math.pl 0'.