Проверьте выпуклость любой функции в R - PullRequest
1 голос
/ 06 ноября 2019

Я должен проверить, является ли функция выпуклой или нет в заданном интервале.

Я использую формулу с лямбда-выражением. Функция f является выпуклой, если:

Formula

Это функция, которую я написал:

isConvex <- function(FUN, x1, x2, lambda) {
    if (!is.function(FUN))
        return(errorCondition("Argument FUN is not a function."))

    if (x1 > x2 )
        return(errorCondition("Argument x1 needs to be smaller than x2."))

    if (!(max(lambda) == 1 && min(lambda) == 0))
        return(errorCondition("Argument lambda needs to be a sequence from 0 to 1."))

    return (FUN( lambda*x1 + (1-lambda) * x2 ) - lambda*FUN(x1) + (1-lambda)*FUN(x2) <= 0)
}

isConvex(somefunction, -1, 1, seq(0,1,.01))

Функция должна возвращать либо TRUE, либо FALSE в зависимости отна выпуклости функции, однако я получаю вектор TRUE с и FALSE с.

Например, isConvex(exp, 1, 3, seq(0,1,.01)) должен вернуть [1] TRUE.

В соответствии с моей задачей, лямбда должна быть последовательностью.

1 Ответ

1 голос
/ 07 ноября 2019

Функция выпуклая, если неравенство применяется ко всем лямбда-значениям от 0 до 1, поэтому вам не нужно лямбда-аргумент в вашей функции.

Кроме того, в вашем неравенстве есть ошибка -последний + должен быть -. Неравенство должно быть f(Lx1+(1-L)x2) <= Lf(x1)+(1-L)f(x2) - т.е. функция должна быть ниже интерполирующей прямой линии между x1 и x2. (См. https://en.wikipedia.org/wiki/Convex_function)

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

isConvex <- function(FUN, x1, x2) { #don't need lambda as an argument
   lambda <- seq(0, 1, 0.01)
   test <- FUN(lambda * x1 + (1-lambda) * x2 ) - lambda*FUN(x1) - (1-lambda)*FUN(x2) <= 0
   return(all(test))
}

isConvex(exp, 1, 3)
[1] TRUE

На самом деле, чтобы доказать выпуклость, вынеобходимо проверить неравенство для всех комбинаций x1 и x2 в диапазоне, который вас интересует, поэтому это не так просто, как это (может быть «перегиб» между конечными точками, который все еще удовлетворяет неравенству) Альтернативным и, возможно, более надежным подходом будет проверка положительной второй производной. Это можно сделать, заменив вторую строку функции на

test <- diff(diff(FUN(lambda * x1 + (1 - lambda) * x2))) >= 0
.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...