Визуализируйте функцию, используя двойную интеграцию в R - Wacky Result

Я пытаюсь визуализировать кривую распределения опыления. Я очень новичок в R, поэтому, пожалуйста, не расстраивайтесь из-за моей глупости.

llim <- 0
ulim <- 6.29

f <- function(x,y) {(.156812/((2*pi)*(.000005^2)*(gamma(2/.156812)))*exp(-((sqrt(x^2+y^2))/.000005)^.156812))}

integrate(function(y) {
     sapply(y, function(y) {
          integrate(function(x) f(x,y), llim, ulim)$value
          })
     }, llim, ulim)

fv <- Vectorize(f)

curve(fv, from=0, to=1000)

И я получаю:

Error in y^2 : 'y' is missing

person Andi Noakes    schedule 13.01.2015    source источник
comment
curve ожидает только одномерную функцию   -  person James    schedule 13.01.2015
comment
Если это невозможно в R, у меня есть и Matlab, и Mathematica, но я не знаю, как кодировать ни в одном из них (вообще). Еще раз спасибо!!!   -  person Andi Noakes    schedule 13.01.2015
comment
Спасибо, Джеймс. Есть ли другая команда, которую я могу использовать для построения этого графика?   -  person Andi Noakes    schedule 13.01.2015
comment
Вы, вероятно, хотите persp.   -  person Thomas    schedule 13.01.2015
comment
Взгляните на этот вопрос: stackoverflow.com/q/7568356/269476   -  person James    schedule 13.01.2015
comment
Это, безусловно, возможно в R. Однако можете ли вы лучше объяснить, что именно вы хотите от оси x и оси y?   -  person Anders Ellern Bilgrau    schedule 13.01.2015
comment
Я надеюсь на расстояние от 0 до 1000 метров по моей оси x и вероятность опыления (или плотность вероятности) по моей оси y. Я рад слышать, что это возможно в R! Я искал persp и пытался загрузить его, но, видимо, у меня нет подходящей версии R для этого? Не могу найти нужную версию. У меня 2.14.1, 2.14.2 и 3.1.2.   -  person Andi Noakes    schedule 13.01.2015


Ответы (2)


Я не совсем уверен, что вы просите заговорить. Но я знаю, что вы хотите визуализировать свою скалярную функцию двух аргументов.

Вот некоторые подходы. Сначала мы определяем вашу функцию.

llim <- 0
ulim <- 6.29

f <- function(x,y) {
  (.156812/((2*pi)*(.000005^2)*(gamma(2/.156812)))*exp(-((sqrt(x^2+y^2))/.000005)^.156812))
}

Из вашего заголовка я подумал о следующем. Функция, определенная ниже intf, интегрирует вашу функцию по квадрату [0,ul] x [0,ul] и возвращает значение. Затем мы векторизуем и строим интеграл по квадрату как функцию длины стороны квадрата.

intf <- function(ul) {
  integrate(function(y) {
    sapply(y, function(y) {
      integrate(function(x) f(x,y), 0, ul)$value
      })
    }, 0, ul)$value
}
fv <- Vectorize(intf)
curve(fv, from=0, to=1000)

Имгур

Если f является распределением, я думаю, вы можете сделать свою (несколько) красивую вероятностную интерпретацию этой кривой. (Т.е. ~20 % вероятность опыления(?) на площади 200 на 200 метров.)

Однако вы также можете построить контурный график (логарифмически преобразованных значений), который иллюстрирует функцию, которую мы интегрируем выше:

 logf <- function(x, y) log(f(x, y))
 x <- y <- seq(llim, ulim, length.out = 100)
 contour(x, y, outer(x, y, logf), lwd = 2, drawlabels = FALSE)

Имгур

Вы также можете построить некоторые профили поверхности:

plot(1, xlim = c(llim, ulim), ylim = c(0, 0.005), xlab = "x", ylab = "f")
y <- seq(llim, ulim, length.out = 6)
for (i in seq_along(y)) {
  tmp <- function(x) f(x, y = y[i])
  curve(tmp, llim, ulim, add = TRUE, col = i)
}
legend("topright", lty = 1, col = seq_along(y),
       legend = as.expression(paste("y = ",y)))

Имгур

Их нужно немного изменить, чтобы сделать их достойными публикации, но вы поняли идею. Наконец, вы можете сделать несколько 3D-графиков, как предлагали другие.

EDIT Согласно вашим комментариям, вы также можете сделать что-то вроде этого:

# Define the function times radius (this time with general a and b)
# The default of a and b is as before
g <- function(z, a = 5e-6, b = .156812) {
  z * (b/(2*pi*a^2*gamma(2/b)))*exp(-(z/a)^b)
}

# A function that integrates g from 0 to Z and rotates
# As g is not dependent on the angle we just multiply by 2pi
intg <- function(Z, ...) {
  2*pi*integrate(g, 0, Z, ...)$value
}

# Vectorize the Z argument of intg
gv <- Vectorize(intg, "Z")

# Plot
Z <- seq(0, 1000, length.out = 100) 
plot(Z, gv(Z), type = "l", lwd = 2)
lines(Z, gv(Z, a = 5e-5),         col = "blue", lwd = 2)
lines(Z, gv(Z, b = .150),         col = "red", lwd = 2)
lines(Z, gv(Z, a = 1e-4, b = .2), col = "orange", lwd = 2)

Имгур

Затем вы можете построить кривые для нужных a и b. Если какой-либо из них не указан, используется значение по умолчанию. Отказ от ответственности: мое исчисление заржавело, и я только что сделал это с головой. Вы должны убедиться, что я правильно выполнил вращение функции вокруг оси.

person Anders Ellern Bilgrau    schedule 13.01.2015
comment
@AndiNoakes Нет проблем;) - person Anders Ellern Bilgrau; 13.01.2015
comment
Ладно, еще кое-что, с чем ты мог бы мне помочь, раз уж ты теперь мой герой. Я пытаюсь визуализировать график кумулятивной доли пыльцы, собранной в круге радиуса Z (с центром на материнском родительском элементе), путем интегрирования: (b/2pia^2(gamma(2/b))*exp(-(z /a)^b) от тета=0 до тета=2pi и от z=0 до z=Z (где Z — радиус круга, в котором собрана кумулятивная доля пыльцы, т. е. произошло опыление). параметр масштаба, b — параметр формы, а z — sqrt(x^2+y^2). - person Andi Noakes; 13.01.2015
comment
@AndiNoakes Я отредактировал свой ответ. Это то, что вы хотите? Пожалуйста, проверьте математику самостоятельно. - person Anders Ellern Bilgrau; 13.01.2015

В пакете lattice есть несколько функций, которые помогут вам рисовать трехмерные графики, включая wireframe() и persp(). Если вы предпочитаете не использовать 3D-график, вы можете создать контурный график с помощью contour().

Примечание. Я не знаю, сделано ли это намеренно, но ваши данные дают очень большой всплеск в одном углу графика. Это дает график, который во всех смыслах плоский, с едва заметным пиком в одном углу. Это особенно проблематично для контурного графика ниже.

library(lattice)

x <- seq(0, 1000, length.out = 50)
y <- seq(0, 1000, length.out = 50)

Сначала проволочный каркас:

df <- expand.grid(x=x, y=y)
df$z <- with(df, f(x, y))
wireframe(z ~ x * y, data = df)

введите здесь описание изображения

Далее перспективный сюжет:

dm <- outer(x, y, FUN=f)
persp(x, y, dm)

введите здесь описание изображения

Контурный участок:

contour(x, y, dm)

введите здесь описание изображения

person Andrie    schedule 13.01.2015
comment
Контурные графики обычно предпочтительнее других 3D-графиков. - person Roland; 13.01.2015
comment
Я должен указать, что я просто ищу 2D-кривую, которая показывает лептокуртоз распределения пыльцы. - person Andi Noakes; 13.01.2015