2013-11-30 3 views
1

Hessian matrixR Матрица Гессе

Мне нужно создать матрицу Гессе функции, заданной как:

func <- expression(sin(x+y)+cos(x-y)) 
vars <- c("x", "y") 

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

funcD <- lapply(vars, function(v) D(func, v)) 
funcDD <- list(); for (i in 1:length(vars)) funcDD[[i]] <- lapply(vars, function(v) D(funcD[[i]], v)) 

Пока что это работает.

> funcDD 
[[1]] 
[[1]][[1]] 
-(sin(x + y) + cos(x - y)) 

[[1]][[2]] 
-(sin(x + y) - cos(x - y)) 


[[2]] 
[[2]][[1]] 
cos(x - y) - sin(x + y) 

[[2]][[2]] 
-(cos(x - y) + sin(x + y)) 

Теперь вопросы: Как я могу создать матрицу, содержащую значения вычисленных выражений? Пробовал внешний, не работал.

> h <- outer(c(1:length(vars)), c(1:length(vars)), function(r, c) eval(funcDD[[r]][[c]], envir = list(x = 1, y = 2))) 
Error in funcDD[[r]] : subscript out of bounds 

Другой вопрос: Есть ли более элегантный способ для хранения производных выражений второго порядка? Например, возможно ли хранить выражения в матрице вместо списков списков?

Третий вопрос: Можно ли получить вектор переменных выражения? Выше я использовал vars < - c ("x", "y"), который я ввел как ввод вручную, это необходимо или есть метод get_variables?

ответ

3

Ответ на второй вопрос есть, «в основном да», и предлагает почти немедленный ответ на ваш вопрос:

funcD <- sapply(vars, function(v) D(func, v)) 
funcDD <- matrix(list(), 2,2) 
for (i in 1:length(vars)) 
     funcDD[,i] <- sapply(vars, function(v) D(funcD[[i]], v)) 
funcDD 
#--------- 
    [,1]  [,2]  
[1,] Expression Expression 
[2,] Expression Expression 
> funcDD[1,1] 
[[1]] 
-(sin(x + y) + cos(x - y)) 

«в основном» квалификация является то, что нужно использовать «список», а не «выражение» как тип объекта, что матрица держит. Выражения на самом деле не квалифицируются как атомные объекты, и вы можете легко извлечь значение и использовать его в качестве вызова, который может быть даже удобнее, чем иметь его как выражение:

> is.expression(funcDD[1,1]) 
[1] FALSE 
> funcDD[1,1][[1]] 
-(sin(x + y) + cos(x - y)) 
> class(funcDD[1,1][[1]]) 
[1] "call" 

Оказывается, что хотели та же самая структура, таким образом, это вызывает каждый матричный элемент с тем же самым конкретным вектором в качестве среды оценки и возвращает их все в качестве матрицы .:

matrix(sapply(funcDD, eval, env=list(x=0, y=pi)), length(vars)) 
#--------- 
    [,1] [,2] 
[1,] 1 -1 
[2,] -1 1 
+0

Когда мне нужно Eval() все элементы в матрице, есть более элегантный способ, чем использование двойного цикла for-loop? –

+0

Я бы попробовал что-то вроде: 'eval (funcDD [1,1] [[1]], env = list (x = 0, y = pi))'. О, подумав еще раз, это, возможно, не то, что вы имели в виду. Возможно, вы должны представить более полный вариант использования. –

+1

Возможно: 'sapply (funcDD, eval, env = list (x = 0, y = pi)) # [1] 1 -1 -1 1'? –

0

Я думаю, было бы намного проще написать цикл, который вычисляет каждую производную и помещает ее значение непосредственно в матрицу. Таким образом,

hess<-matrix(nrow=N,ncol=N) #for x1 thru xN 
for(j in 1:N) { 
    for(k in 1:N) { 
     hess[i,j]<- Dfunc(func,vars[i,j]) 
     } 
    } 

Где вы должны настроить свой x1, x2, ... Xn переменные в матрице vars

Смежные вопросы