我想绘制x和y的隐式函数:1 - 0.125 * y ^ 2 - x ^ 2 = 0.005
我知道它可以绘制成等高线图,但是“外部”命令有问题
在下面:
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)
我阅读了有关“外部”命令的常见问题解答(7.17)以及对该功能进行矢量化的需要,但仍处于一个quardry中。
答案 0 :(得分:5)
我认为你对'功能'的含义有点困惑。 你的函数中的所有操作(+, - ,^)都是矢量化的,所以一切正常。
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)
或者如果你想要一个小捷径:
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)
这实际上比较慢,因为它在内部而不是for
使用outer()
循环,因此我将其设置为100x100而不是1000x1000(这对于此示例来说无论如何都是过度杀戮),但它会起作用更复杂的例子,无法轻易地进行矢量化......
答案 1 :(得分:1)
将隐式方程绘制为等高线图是过度的。你实际上丢弃了99.99%的计算量。
更好的方法是找到给定x的y的值,这将使得等式0.这是在基数R中使用uniroot的代码。
x = seq(0, 0.995, length = 100) # no real root above 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 #only care about the root
}
y <- sapply(x, root)
plot(x,y, type = "l")
好的,uniroot参数中的c(0,3)是根所在的y值范围。因此,对于每个给定的x值,uniroot将为根查找0到3之间的y值。
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接受寻找其根的函数,并为每个给定的x值猜测y的值。在这里,我们说y值接近1.我们给它一个猜测值为1&#39;
uniroot想要一个绑定范围来寻找root,fsolve需要猜测root可能在哪里。
这些是绘制隐式方程的更快方法。然后,您可以使用任何图形包(如ggplot2 / rbokeh)进行绘图。
我还没有完成任何基准测试,因此无法确定哪种方法更快。虽然对于这样一个简单的隐含函数,但它无关紧要