По определению, точка перегиба - это точка, в которой вторая производная функции равна нулю. На практике это означает, что точкой перегиба будет точка, в которой наклон переходит от увеличения к уменьшению, или vv. Используя это определение, я пришел с этим приблизительным и неавтоматическим подходом c: предположим, что у вас есть фрейм данных , который я назову all
, который содержит значения x в первом столбце и результат вычисления плотности во втором столбце. Из этого фрейма данных мы можем вычислить наклон двух последовательных точек следующим образом:
slopes <- vector()
for(i in (2:nrow(all))){
x1 <- all[i-1, 1]
x2 <- all[i, 1]
y1 <- all[i-1, 2]
y2 <- all[i, 2]
slope_i <- (y2-y1)/(x2-x1)
slopes <- append(slopes, slope_i)
}
По определению точки перегиба теперь мы можем вычислить, становится ли наклон больше или меньше от одной точки к другой. :
increment <- vector()
for(j in 2:length(slopes)){
increment_j <- slopes[j] - slopes[j-1]
increment <- append(increment, increment_j)
}
Точками перегиба будут те точки, где это приращение перешло от положительного к отрицательному, или vv
Теперь давайте разделим эти приращения на положительные и отрицательные:
pos <- which(increment>0)
neg <- which(increment<0
Теперь, когда есть скачок в этих pos
или neg
векторах, это означает, что у нас есть точка перегиба. Итак, еще раз:
steps_p <- vector()
for(k in 2:length(pos)){
steps_k <- pos[k] - pos[k-1]
steps_p <- append(steps_p, steps_k)
}
steps_n <- vector()
for(k in 2:length(neg)){
steps_k <- neg[k] - neg[k-1]
steps_n <- append(steps_n, steps_k)
}
Теперь просто спросите R:
which(steps_p>1)
which(steps_n>1)
Это индексы ваших точек перегиба, теперь просто go к исходному фрейму данных и попросите значение x:
all[pos[which(steps_p>1)],1]
all[neg[which(steps_n>1)],1]
Имейте в виду, что значение x будет близко к точному, но не совсем, так как в течение каждого l oop мы теряем один индекс, но он все равно будет очень близким раствор.