2016-06-18 33 views
1

Ich tue dies:Finding Kreuzung zwischen zwei Funktionen mit Matlab oder Scilab

>> plot(x,y1,x,y2); 
>> x=0:0.001:5; 
>> y1=sin(x)+cos(1+x.^2)-1; 
>> y2 = ((1/2).*x)-1; 
>> find (y1==y2) 

Und diese bekommen:

ans = 

    Empty matrix: 1-by-0 

Als Antwort und es einfach macht mich verrückt! Ich weiß nicht, warum Matlab und Scilab mir nicht die Antwort auf die Schnittmengen geben. Ich habe versucht, die Intervalle kleiner zu machen wie x = 0:0.0001:5; aber es hat nichts geändert. Wie kann ich mir die Kreuzungswerte zurückgeben?

Vielen Dank.

+0

Oh, vergaß hinzuzufügen, dass diese beiden Funktionen drei Schnittpunkte im ausgewählten Intervall haben. –

+0

Ich habe eine Antwort hinzugefügt, um zu zeigen, wie ein numerisches Problem wie dieses behandelt werden sollte. –

Antwort

1

Sie müssen bedenken, dass Matlab numerische Lösungen für Probleme zu finden, verwendet wird. Sie stellen einen diskreten Satz von Eingabepunkten x=0:0.001:5; zur Verfügung und bitten ihn, die diskreten Ausgabepunkte y1[x] und y2[x] zu berechnen. Dies bedeutet, dass y1 und y2 nicht kontinuierlich sind und sich nicht notwendigerweise schneiden, wie es ihre fortlaufenden Gegenstücke tun. Ich habe Matlab nicht, also habe ich Ihren Code nicht ausgeführt, aber Ihre diskreten Funktionen werden höchstwahrscheinlich nicht interterieren. Das heißt, es gibt kein Paar Punkte a = y1[x_i] und b = y2[x_i] wo a = b. Stattdessen möchten Sie wahrscheinlich nach Punkten suchen, bei denen y2-y1 auf einer Seite von Null an einem bestimmten Eingang und auf der anderen Seite von Null für den nächsten Eingang ist. Dies würde bedeuten, dass sich die kontinuierlichen Teile der Funktion irgendwo dazwischen befinden würden.

Der Fall, in dem die Funktionen sich treffen, aber nicht kreuzen, ist ein wenig schwieriger, aber die gleiche Art von Idee.

EDIT:

Dergleichen ist am einfachsten, den Kopf wickeln um mit dem Bild, damit ich eine erstellt illustrieren, was ich meine.

Plot of y1 and y2

Hier habe ich noch viel weniger Punkte als Sie versuchen, zu verwenden, aber die Idee ist die gleiche. Sie können sehen, dass sich die fortlaufenden Versionen von y1 und y2 an mehreren Stellen kreuzen. Was Sie Matlab jedoch fragen, ist, einen Punkt in y1 zu finden, der einem Punkt in y2 für identische Werte von x entspricht. In diesem Bild können Sie sehen, dass viele in der Nähe sind, aber Ihr Computer speichert Gleitkommazahlen mit einer sehr hohen Genauigkeit und so ist die Wahrscheinlichkeit, dass sie tatsächlich gleich sind, sehr gering.

Wenn Sie die Anzahl der Abtastpunkte erhöhen, sieht das Bild mehr wie sein fortlaufendes Gegenstück aus.

Image with increased sample points

0

Vielleicht haben die beiden Vektoren nirgendwo genau die gleichen Werte. Sie könnten versuchen, einen kleinsten Unterschied suchen:

abs(y1-y2)<tolerance 

wo Toleranz = 0,001 eine kleine Zahl

1

Die beide bestehende Antworten erklären, warum man nicht einen exakten Schnitt so leicht finden. Aber was Sie wirklich brauchen, ist eine Antwort auf was zu tun ist stattdessen, um präzise Schnittpunkte zu erhalten?

In Ihrem speziellen Fall kennen Sie die analytischen Funktionen, die Sie herausfinden möchten, die Schnittmenge von.Sie können fzero mit einer (ggf. anonym) Funktion verwenden, um die Null der Funktion durch die Differenz Ihrer beide ursprünglichen Funktionen definiert zu finden:

y1fun = @(x) sin(x)+cos(1+x.^2)-1; 
y2fun = @(x) ((1/2).*x)-1; 
diff_fun = @(x) y1fun(x)-y2fun(x); 
x0 = 1; % starting point for fzero's zero search 
x_cross = fzero(diff_fun,x0); 

, das Ihnen gibt eine Null der Differenzfunktion wird nun dh ein Schnittpunkt Ihrer Funktionen. Es stellt sich heraus, dass das Auffinden von alle Null einer Funktion ist eine schwierige Aufgabe. Generell müssen Sie fzero mehrfach mit verschiedenen Startpunkten x0 aufrufen. Wenn Sie vermuten, wie Ihre Funktionen aussehen, ist das überhaupt nicht hoffnungslos.

Was passiert also, wenn Ihre Funktionen unordentlicher sind? Im allgemeinen Fall können Sie eine Interpolations-Funktion verwenden, um den Teil des y1fun und y2fun im Beispiel oben zum Beispiel interp1 durch Verwendung zu spielen:

% generate data 
xdata = 0:0.001:5; 
y1data = sin(xdata)+cos(1+xdata.^2)-1; 
y2data = ((1/2).*xdata)-1; 

y1fun = @(x) interp1(xdata,y1data,x); 
y2fun = @(x) interp1(xdata,y2data,x); 
x0 = 1; % starting point for fzero's zero search 
x_cross = fzero(@(x)y1fun(x)-y2fun(x),x0); 

, die zum ursprünglichen Problem zurückführt. Beachten Sie, dass interp1 standardmäßig eine lineare Interpolation verwendet. Je nachdem, wie Ihre Funktion aussieht und wie Ihre Daten streuen, können Sie andere Optionen auswählen. Beachten Sie auch die Option zur Extrapolation (zu vermeiden).

Also in beiden Fällen erhalten Sie eine Kreuzung für jeden Anruf an fzero. Wenn Sie die Startpunkte sorgfältig auswählen, sollten Sie alle Nullen so genau wie möglich finden können.