2 Stimmen

R Handlung implizite Funktion Außenbefehl

Ich möchte eine implizite Funktion von x und y plotten: 1 - 0.125 * y ^ 2 - x ^ 2 = 0.005 Ich weiß, dass sie als Konturplot dargestellt werden kann, habe aber Schwierigkeiten mit dem "outer"-Befehl im folgenden:

x<-seq(0.4,1.01,length=1000) y<-seq(0,3,length=1000) z<-outer(x,y,FUN="1-0.125*y^2-x^2=0.005") contour(x,y,z,levels=0,drawpoints=FALSE)

Ich habe die FAQ (7.17) zum "outer"-Befehl und der Notwendigkeit zur Vektorisierung der Funktion gelesen, bin aber immer noch in einem Dilemma.

5voto

Ben Bolker Punkte 190239

Ich glaube, du bist ein wenig verwirrt über die Bedeutung von 'Funktion'. Alle Operationen (+,-,^) in deiner Funktion sind vektorisiert, sodass alles bestens funktioniert.

x <- seq(0.4,1.01,length=1000)
y <- seq(0,3,length=1000)
z <- outer(x,y,function(x,y) 1-0.125*y^2-x^2-0.005)
contour(x,y,z,levels=0,drawlabels=FALSE)

Oder wenn du einen kleinen Shortcut möchtest:

library(emdbook)
curve3d(1-0.125*y^2-x^2-0.005,
        xlim=c(0.4,1.01),
        ylim=c(0,3),
        n=c(100,100),
        sys3d="contour",drawlabels=FALSE,levels=0)

Dies ist tatsächlich langsamer, weil es intern eine for-Schleife anstelle von outer() verwendet. Deshalb habe ich es auf 100x100 statt 1000x1000 gesetzt (was für dieses Beispiel sowieso übertrieben ist), aber es wird auch auf komplexeren Beispielen funktionieren, die nicht so leicht vektorisiert werden können ...

1voto

MySchizoBuddy Punkte 1078

Die Darstellung einer impliziten Gleichung als Konturplot ist übertrieben. Im Grunde genommen verwirfst du 99,99% der Berechnungen, die du gemacht hast.

Besser ist es, den Wert von y für ein gegebenes x zu finden, bei dem die Gleichung 0 wird. Hier ist der Code unter Verwendung von uniroot in base R.

R-Code unter Verwendung von uniroot aus base R

x = seq(0, 0.995, length = 100) # keine reale Null über x = 0.995
root <- function(a) {
        uniroot(function(x,y) 1 - 0.125 * y^2 - x^2 - 0.005, c(0, 3), x = a )$root #nur am Root interessiert
} 
y <- sapply(x, root)
plot(x,y, type = "l")

Ok, das c(0, 3) im Argument von uniroot ist der Bereich der y-Werte, in dem der Nullpunkt liegt. so wird für jeden gegebenen x-Wert uniroot nach einem y-Wert zwischen 0 und 3 für eine Null suchen.

R-Code unter Verwendung von fsolve aus dem Paket pracma

library("pracma")
x <- seq(0,0.995, length=100)
fun <- function(y) c(1 - 0.125 * y^2 - x^2 - 0.005)
y_sol <- fsolve(fun, rep(1, length(x)))$x
plot(x,y_sol, type="l")

fsolve akzeptiert die Funktion, deren Nullpunkt gesucht wird, und Vermutungswerte für y für jeden gegebenen Wert von x. Hier sagen wir, dass die y-Werte nahe bei 1 liegen. wir geben ihm einen Erratungswert von 1's

uniroot möchte einen begrenzten Bereich, um nach dem Nullpunkt zu suchen, fsolve erfordert eine Vermutung, wo der Nullpunkt sein könnte.

Dies sind schnellere Möglichkeiten, um implizite Gleichungen darzustellen. Anschließend können Sie jedes Grafikpaket wie ggplot2/rbokeh zur Darstellung verwenden.

Ich habe keine Benchmarks durchgeführt, daher kann ich nicht sagen, welche Methode schneller ist. Für eine so einfache implizite Funktion spielt es jedoch keine Rolle.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X