Matlab zu blöd zum rechnen/vergleichen? :D

Neue Frage »

Maddin17 Auf diesen Beitrag antworten »
Matlab zu blöd zum rechnen/vergleichen? :D
Ich habe für eine Arbeit ein Programm geschrieben, das normalerweise bestens funktioniert. Jetzt hab ich gestern ein anderes Beispiel ausrechnen lassen wollen und da ich das Ergebnis vorher bereits kannte, weiss ich, dass das, was Matlab mir anbietet, nicht richtig ist.
Wo das Problem liegt, hab ich mittlerweile eingrenzen können.

Der Vektor u wird untersucht


und bei der Abfrage

if u(2) >= -u(1)
z=1
else
z=-1
end

liefert mir Matlab -1?!
Ich zweifel gerade am meinem Verstand, aber wenn ich mich nicht täusche, ist u(2) = -0.02 >= -(0.02) = -u(1), was zu z=1 führen sollte?!

Kann mir jemand helfen, wo das Problem hier liegt?!
Besten Dank schonmal!
Math1986 Auf diesen Beitrag antworten »
RE: Matlab zu blöd zum rechnen/vergleichen? :D
Liefert hier z=1.
Du musst in der ersten Komponente ein Dezimalpunkt statt eines -kommas setzen.
Cel Auf diesen Beitrag antworten »

Auch Octave spuckt ein z=1 aus.
Maddin17 Auf diesen Beitrag antworten »
RE: Matlab zu blöd zum rechnen/vergleichen? :D
Zitat:
Original von Math1986
Liefert hier z=1.
Du musst in der ersten Komponente ein Dezimalpunkt statt eines -kommas setzen.


ja, hab ich in Matlab auch, hab mich hier nur verschrieben.
Airblader Auf diesen Beitrag antworten »

Da das Programm an sich wie gewünscht funktionieren sollte, können wir dir nur weiterhelfen, wenn du genau den Code lieferst, den du ausführst – inklusive deiner exakten Eingabe von u.

Verwende dazu bitte die code-Tags im Forum.

air
Maddin17 Auf diesen Beitrag antworten »

hm, ich hab mal eben nen Screenshot gemacht, damit ihr nicht denkt, ich sei völlig bescheuert Big Laugh

reicht das so? hab zur Verdeutlichung nochmal u(1) usw ausgeben lassen, damit man sieht, dass die Werte richtig sind.

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function z=cone_MIN_Bsp3(y,u,p)
global qqq
qqq=qqq+1; % zählt #Kegelauswertungen

uu=u
u1=u(1)
u2=u(2)
if u(2) = u(1)
    z=1
else
    z=-1
end


*edit*
Die Menge D hab ich jetzt wie folgt eingegeben:
code:
1:
D=[[0;1],[0.0200;0.9800]]


und das u ergibt sich dann aus der zweiten Spalte abzüglich der ersten Spalte. Also Rundungs/Darstellungsfehler dürften hier keine sein
 
 
Airblader Auf diesen Beitrag antworten »

code:
1:
if u(2) = u(1)


ist eine Zuweisung der Variable, die in if-Statements verboten ist. Du meintest vermutlich den Vergleichsoperator "==".

Edit: Im Screenshot stimmt's allerdings. Moment.

air
Maddin17 Auf diesen Beitrag antworten »

Zitat:
Original von Airblader
code:
1:
if u(2) = u(1)


ist eine Zuweisung der Variable, die in if-Statements verboten ist. Du meintest vermutlich den Vergleichsoperator "==".

Edit: Im Screenshot stimmt's allerdings. Moment.

air


ja sry. Da wollt ich grad ausprobieren, was bei "=" und ">" seperat rauskommt smile
Airblader Auf diesen Beitrag antworten »

Die Ausgabe passt nun aber doch zum Programm. u(2) >= u(1) ist eben nicht wahr. Im Ausgangsbeitrag hast du jedoch

code:
1:
if u(2) >= -u(1)


geschrieben. Soll da nun ein Minus sein oder nicht?

air
Maddin17 Auf diesen Beitrag antworten »

das minus is korrekt, also
u(2) >= -u(1)

ich schreib gleich nochmal alles übersichtlich, sorry fürs Durcheinander hier
Airblader Auf diesen Beitrag antworten »

Wenn das Minus dann auch im Programm steht erscheint bei mir die korrekte Ausgabe.

air
Maddin17 Auf diesen Beitrag antworten »

Also, zuerst hab ich die Menge D explizit eingegeben:

code:
1:
2:
3:
 D=[[0;1],[0.0200;0.9800]]


Der Vektor u berechnet sich dann aus 2. Spalte minus 1. Spalte
also


Jetzt lautet der Matlab-Code:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function z=cone_MIN_Bsp3(y,u,p)
global qqq
qqq=qqq+1; % zählt #Kegelauswertungen

uu=u
u1=u(1)
u2=u(2)
minusu1=-u(1)
if u(2) >= -u(1)
    z=1
else
    z=-1
end


und Matlab liefert mir wie gesagt

was ja eigentlich nicht sein kann, da

und damit auch >=

Meine Matlab-Ergebnisse hab ich auch nochmal angehängt ...
Airblader Auf diesen Beitrag antworten »

Da scheint es zu leichten Rechenungenauigkeiten zu kommen. Tipp u mal direkt ein durch

code:
1:
u = [0.02; -0.02];


und schaue, ob es dann richtig ist. Bei mir taucht der Fehler dann nicht mehr auf. In diesem Sinne schafft

code:
1:
if u(2)+u(1) >= -eps


Abhilfe. Allerdings bin ich auch irritiert, dass es bereits hier zu solchen Rechenungenauigkeiten kommt. verwirrt

air
Maddin17 Auf diesen Beitrag antworten »

wenn ich u explizit eingebe, wie dus mir gesagt hast, kommt das richtige (z=1) raus ...

Matlab "verrechnet" sich dann bei der Berechnung von u oder wie ist der Fehler zu verstehen?

Danke für die schnelle und erfolgreiche Hilfe smile ich hät da jetzt locker noch ne Woche mit verbracht Big Laugh
Airblader Auf diesen Beitrag antworten »

Du kannst den Unterschied sehen, wenn du dir einfach

code:
1:
u(1) + u(2)


ausgeben lässt. Bei der direkten Eingabe von u ist das glatt Null, bei der Bildung von u über die Spaltendifferenz von D ist es eben nur ein sehr kleiner Wert (kleiner als eps).

An sich ist das ein numerisch typischer Effekt. Ich bin aber verblüfft, dasss der bereits bei dieser simplen Differenzbildung auftritt.

air
Maddin17 Auf diesen Beitrag antworten »

stimmt, da kommt tatsächlich nicht 0 heraus Big Laugh

na gut, dann geb ich mich an dieser Stelle zufrieden ... mit den "-eps" kommt dann auch das richtige Ergebnis raus smile

Danke ein letztes mal smile
Calvin Auf diesen Beitrag antworten »

Zitat:
Original von Airblader
Ich bin aber verblüfft, dasss der bereits bei dieser simplen Differenzbildung auftritt.


Das liegt vermutlich daran, dass eine der beteiligten Zahlen im IEEE754-Format eine periodische Darstellung hat. Damit kommt es zu Rundungsfehlern.

Das macht den Vergleich von Komma-Zahlen auf Gleichheit so schwierig. Man ist auf den "Trick" mit dem epsilon quasi angewiesen.
Airblader Auf diesen Beitrag antworten »

Dass es zu solchen Fehlern kommt ist mir ja klar. Aber sollte nicht wenigstens so etwas simples wie 0.98 - 1 auch exakt berechnet werden können? verwirrt

Da Matlab alle Zahlen als Doubles speichert, müsste ich ja auch bei Vergleichen wie

code:
1:
if size(X, 1) - 1 == size(Y, 1)


befürchten, dass sie schiefgehen?

air
chrizke Auf diesen Beitrag antworten »

Bei diesem Beispiel nehme ich an, dass intern integers verwendet werden.
Calvin Auf diesen Beitrag antworten »

Zitat:
Original von Airblader
Aber sollte nicht wenigstens so etwas simples wie 0.98 - 1 auch exakt berechnet werden können? ?


Nicht alles, was für den Mensch simpel ist, ist es auch für den Computer. Schaue dir mal die Seite http://www.h-schmidt.net/FloatApplet/IEEE754de.html an. Da ist beschrieben, dass schon die "simple" Zahl 0,1 von einem Computer nicht exakt gespeichert werden kann.

Ist übrigens kein Matlab-Problem. In Java kommt auch nicht der erwartete Wert raus.

code:
1:
2:
3:
4:
5:
6:
7:
8:
public class Beispiel {
	public static void main(String[] args) {
		double d1 = 0.98;
		double d2 = 1;
		System.out.println(d1 - d2); // -0.020000000000000018
	}
}
Airblader Auf diesen Beitrag antworten »

Zitat:
Original von chrizke
Bei diesem Beispiel nehme ich an, dass intern integers verwendet werden.


Matlab speichert alle Werte ausnahmslos als Doubles. Das ist jedenfalls ihre eigene Angabe.

@ Calvin

Vielen Dank. Da muss man ja glatt noch weit besser aufpassen, als ich dachte.

air
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »