¿Cómo puedo ajustar una spline a los datos que contienen valores y derivados 1º / 2º?


14

Tengo un conjunto de datos que contiene, digamos, algunas mediciones de posición, velocidad y aceleración. Todos provienen de la misma "carrera". Podría construir un sistema lineal y ajustar un polinomio a todas esas medidas.

¿Pero puedo hacer lo mismo con splines? ¿Cuál es una forma 'R' de hacer esto?

Aquí hay algunos datos simulados que me gustaría ajustar:

f <- function(x) 2+x-0.5*x^2+rnorm(length(x), mean=0, sd=0.1)
df <- function(x) 1-x+rnorm(length(x), mean=0, sd=0.3)
ddf <- function(x) -1+rnorm(length(x), mean=0, sd=0.6)

x_f <- runif(5, 0, 5)
x_df <- runif(8, 3, 8)
x_ddf <- runif(10, 4, 9)

data <- data.frame(type=rep('f'), x=x_f, y=f(x_f))
data <- rbind(data, data.frame(type=rep('df'), x=x_df, y=df(x_df)))
data <- rbind(data, data.frame(type=rep('ddf'), x=x_ddf, y=ddf(x_ddf)))

library(ggplot2)
ggplot(data, aes(x, y, color=type)) + geom_point()


library(splines)
m <- lm(data$y ~ bs(data$x, degree=6)) # but I want to fit on f, df, ddf. possible?

ingrese la descripción de la imagen aquí


No sé la respuesta a su pregunta, pero ¿ splinefunpuedo calcular derivados y presumiblemente podría usar esto como punto de partida para ajustar los datos utilizando algunos métodos inversos? Estoy interesado en aprender la solución a esto.
David LeBauer

1
Este problema fue resuelto por Maurice Cox en su artículo de 1972. No sé si R lo admite, pero el término de búsqueda es "Hermite splines".
user14717

@DavidLeBauer esto es lo que estoy haciendo actualmente. Formalicé un problema de optimización que se ajusta a varios puntos, de modo que la spline y sus derivados se aproximan a los datos. Pero un método más directo sería genial.
dani

3
Un enfoque bastante estándar es a través del filtrado de Kalman. El estado (no observable) contiene las derivadas exactas y las observaciones son versiones ruidosas de estos. Por ejemplo, el modelo para una spline cúbica dice aproximadamente que la derivada de segundo orden es un ruido blanco (tiempo continuo), pero también se puede usar un modelo de orden superior. Tendrá que describir el ruido de medición según el orden de derivación para la observación actual. Tres variaciones de ruido (para estimar) pueden ser suficientes en un primer enfoque.
Yves

2
¿Qué es el error de medición en derivados? ¿Es mucho más alto que la posición? También en su trama ¿por qué no están alineados los puntos? ¿Qué es el eje x?
Aksakal

Respuestas:


9

Describiremos cómo se puede usar una spline a través de las técnicas de filtrado de Kalman (KF) en relación con un modelo de espacio de estado (SSM). El hecho de que algunos modelos spline puedan ser representados por SSM y calculados con KF fue revelado por CF Ansley y R. Kohn en los años 1980-1990. La función estimada y sus derivados son las expectativas del estado condicionadas a las observaciones. Estas estimaciones se calculan utilizando un suavizado de intervalo fijo , una tarea de rutina cuando se utiliza un SSM.

En aras de la simplicidad, suponga que las observaciones se realizan en los momentos t1<t2<<tn y que el número de observación k en tk involucra solo una derivada con el orden dk en {0,1,2} . La parte de observación del modelo se escribe como

(O1)y(tk)=f[dk](tk)+ε(tk)
dondef(t) denota lafunciónverdaderano observadayε(tk) es un error gaussiano con varianzaH(tk) dependiendo del orden de derivacióndk. La ecuación de transición (tiempo continuo) toma la forma general donde es el vector de estado no observado y es un ruido blanco gaussiano con covarianza , se supone que es independiente del ruido de observación r.vs . Para describir una spline, consideramos un estado obtenido al apilar las primeras derivadas, es decir, . La transición es
(T1)ddtα(t)=Aα(t)+η(t)
α(t)η(t)Qε(tk)mα(t):=[f(t),f[1](t),,f[m1](t)]
[f[1](t)f[2](t)f[m1](t)f[m](t)]=[010001100][f(t)f[1](t)f[m2](t)f[m1](t)]+[000η(t)]
2m2m-1m=2>1 y ( t k ) y luego obtenemos una spline polinomial con orden (y grado ). Mientras que corresponde a la spline cúbica habitual,2m2m1m=2>1. Para mantener un formalismo SSM clásico, podemos reescribir (O1) como donde la matriz de observación selecciona la derivada adecuada en y la varianza de se elige dependiendo de . Entonces donde , y . Del mismo modo
(O2)y(tk)=Z(tk)α(tk)+ε(tk),
Z(tk)α(tk)H(tk)ε(tk)dkZ(tk)=Zdk+1Z1:=[1,0,,0]Z2:=[0,1,0]Z3:=[0,0,1,0,]H(tk)=Hdk+1 H 1 H 2 H 3para tres variaciones , y . H1H2H3

Aunque la transición es en tiempo continuo, el KF es en realidad un tiempo discreto estándar . De hecho, en la práctica nos centraremos en los tiempos donde tenemos una observación, o donde queremos estimar las derivadas. Podemos tomar el conjunto como la unión de estos dos conjuntos de tiempos y asumir que puede faltar la observación en : esto permite estimar las derivadas en cualquier momento independientemente de la existencia de una observación. Queda por derivar el SSM discreto.t{tk}tkmtk

Usaremos índices para tiempos discretos, escribiendo para y así sucesivamente. El SSM de tiempo discreto toma la forma donde las matrices y se derivan de (T1) y (O2) mientras que la varianza de viene dada por siempre queαkα(tk)

(DT)αk+1=Tkαk+ηkyk=Zkαk+εk
TkQk:=Var(ηk)εkHk=Hdk+1ykTk=exp{δkA}=[ 1 δ 1 kNo falta. Usando algo de álgebra podemos encontrar la matriz de transición para el SSM de tiempo discreto where para . De manera similar, la matriz de covarianza para el SSM de tiempo discreto se puede dar como
Tk=exp{δkA}=[1δk11!δk22!δkm1(m1)!01δk11!δk11!01],

δk:=tk+1tkk<nQk=Var(ηk)
Qk=ση2[δk2mij+1(mi)!(mj)!(2mij+1)]i,j
donde los índices y están entre y .ij1m

Ahora, para transferir el cálculo en R, necesitamos un paquete dedicado a KF y que acepte modelos que varían con el tiempo; El paquete CRAN KFAS parece una buena opción. Podemos escribir funciones R para calcular las matrices y partir del vector de tiempos para codificar el SSM (DT). En las anotaciones utilizadas por el paquete, una matriz viene a multiplicar el ruido en la ecuación de transición de (DT): lo consideramos aquí como la identidad . También tenga en cuenta que aquí debe usarse una covarianza inicial difusa.TkQktkRkηkIm

EDITAR La como se escribió inicialmente era incorrecta. Corregido (también en código R e imagen).Q

CF Ansley y R. Kohn (1986) "Sobre la equivalencia de dos enfoques estocásticos para el suavizado de estrías" J. Appl. Probab , 23, págs. 391–405

R. Kohn y CF Ansley (1987) "Un nuevo algoritmo para el suavizado de estrías basado en el suavizado de un proceso estocástico" SIAM J. Sci. y Stat. Comput , 8 (1), págs. 33–48

J. Helske (2017). "KFAS: Modelos de espacio de estado familiar exponencial en R" J. Stat. Suave. , 78 (10), pp. 1-39

suavizado con derivados

smoothWithDer <- function(t, y, d, m = 3,
                          Hstar = c(3, 0.2, 0.1)^2, sigma2eta = 1.0^2) {

    ## define the SSM matrices, depending on 'delta_k' or on 'd_k'
    Tfun <- function(delta) {
        mat <-  matrix(0, nrow = m, ncol = m)
        for (i in 0:(m-1)) {
            mat[col(mat) == row(mat) + i] <- delta^i / gamma(i + 1)
        }
        mat
    }
    Qfun <- function(delta) {
        im <- (m - 1):0
        x <- delta^im / gamma(im + 1)
        mat <- outer(X = x, Y = x, FUN = "*")
        im2 <- outer(im, im, FUN = "+")
        sigma2eta * mat * delta / (im2 + 1) 
    }
    Zfun <-  function(d) {
        Z <- matrix(0.0, nrow = 1, ncol = m)
        Z[1, d + 1] <- 1.0
        Z
    }
    Hfun <- function(d) ifelse(d >= 0, Hstar[d + 1], 0.0)
    Rfun <- function() diag(x = 1.0, nrow = m)

    ## define arrays by stacking the SSM matrices. We need one more
    ## 'delta' at the end of the series
    n <- length(t)
    delta <-  diff(t)
    delta <- c(delta, mean(delta))

    Ta <- Qa <- array(0.0, dim = c(m, m, n))
    Za <- array(0.0, dim = c(1, m, n))
    Ha <- array(0.0, dim = c(1, 1, n))
    Ra <-  array(0.0, dim = c(m, m, n))

    for (k in 1:n) {
        Ta[ , , k] <- Tfun(delta[k])
        Qa[ , , k] <- Qfun(delta[k])
        Za[ , , k] <- Zfun(d[k])
        Ha[ , , k] <- Hfun(d[k])
        Ra[ , , k] <- Rfun()
    }

    require(KFAS)
    ## define the SSM and perform Kalman Filtering and smoothing
    mod <- SSModel(y ~ SSMcustom(Z = Za, T = Ta, R = Ra, Q = Qa, n = n,
                                 P1 = matrix(0, nrow = m, ncol = m),
                                 P1inf = diag(1.0, nrow = m), 
                                 state_names = paste0("d", 0:(m-1))) - 1)
    out <- KFS(mod, smoothing = "state")
    list(t = t, filtered = out$att, smoothed = out$alphahat)

}

## An example function as in OP
f <- function(t, d = rep(0, length = length(t))) {
    f <- rep(NA, length(t))
    if (any(ind <- (d == 0))) f[ind] <- 2.0 + t[ind] - 0.5 * t[ind]^2
    if (any(ind <- (d == 1))) f[ind] <- 1.0 - t[ind]
    if (any(ind <- (d == 2))) f[ind] <- -1.0
    f
}

set.seed(123)
n <-  100
t <- seq(from = 0, to = 10, length = n)
Hstar <- c(3, 0.4, 0.2)^2
sigma2eta <- 1.0

fTrue <- cbind(d0 = f(t), d1 = f(t, d = 1), d2 = f(t, d = 2))

## ============================================================================
## use a derivative index of -1 to indicate non-observed values, where
## 'y' will be NA
##
## [RUN #0]  no derivative  m = 2 (cubic spline)
## ============================================================================
d0 <- sample(c(-1, 0), size = n, replace = TRUE, prob = c(0.7, 0.3))
ft0 <-  f(t, d0)
## add noise picking the right sd
y0 <- ft0 + rnorm(n = n, sd = c(0.0, sqrt(Hstar))[d0 + 2])
res0 <- smoothWithDer(t, y0, d0, m = 2, Hstar = Hstar)

## ============================================================================
## [RUN #1] Only first order derivative: we can take m = 2 (cubic spline)
## ============================================================================
d1 <- sample(c(-1, 0:1), size = n, replace = TRUE, prob = c(0.7, 0.15, 0.15))
ft1 <-  f(t, d1)
y1 <- ft1 + rnorm(n = n, sd = c(0.0, sqrt(Hstar))[d1 + 2])
res1 <- smoothWithDer(t, y1, d1, m = 2, Hstar = Hstar)

## ============================================================================
## [RUN #2] First and second order derivative: we can take m = 3
## (quintic spline)
## ============================================================================
d2 <- sample(c(-1, 0:2), size = n, replace = TRUE, prob = c(0.7, 0.1, 0.1, 0.1))
ft2 <-  f(t, d2)
y2 <- ft2 + rnorm(n = n, sd = c(0.0, sqrt(Hstar))[d2 + 2])
res2 <- smoothWithDer(t, y2, d2, m = 3, Hstar = Hstar)

## plots : a ggplot with facets would be better here.
for (run in 0:2) {
    resrun <- get(paste0("res", run))
    drun <- get(paste0("d", run))
    yrun <- get(paste0("y", run))
    matplot(t, resrun$smoothed, pch = 16, cex = 0.7, ylab = "", xlab = "")
    matlines(t, fTrue, lwd = 2, lty = 1)
    for (dv in 0:2) {
        points(t[drun == dv], yrun[drun == dv], cex = 1.2, pch = 22, lwd = 2,
               bg = "white", col = dv + 1)
    }
    title(main = sprintf("run %d. Dots = smooothed, lines = true, square = obs", run))
    legend("bottomleft", col = 1:3, legend = c("d0", "d1", "d2"), lty = 1)
}

Gracias por su respuesta. Estoy muy interesado en eso. Actualmente, no permite que el valor fy su derivada se utilicen de manera segura t. ¿Cómo es posible usar toda la información? De nuevo, merci por tu respuesta.
dani

Mi lectura es que todo debajo de T1 trata sobre el uso de múltiples derivadas en el mismo procedimiento de inferencia. Sin embargo, Yves puede confirmar.
eric_kernfeld

De hecho, puede usar digamos derivados de para una : la observación es entonces un vector y tiene filas que las derivadas deseadas. Estoy seguro de que un común obras con KFAS , pero mediante el uso de AN puede ser posible tener un tiempo variable así. ok>1tkykZkoko>1o
Yves

@Yves interés he entendido bien: Si tengo la primera y segunda derivada en el punto en The Kid, entonces el Z_k se parece a esto: matrix(c(0,0,0, 0,1,0, 0,0,1), nrow=length(d_k), ncol=m, byrow = T). Entonces, en general, sería un cubo de dimensión 'derivada más alta' * 'grado de spline' * '# de pasos de tiempo'
dani

Sí @dani, casi: el número de filas para todas las matrices es es decir en el ejemplo. Este es el orden derivado más alto más uno. Además, el grado de la spline es , no . En su ejemplo, dado que no observa la derivada del orden (la función en sí misma), debe establecerse en las observaciones y también puede eliminar la primera fila. Sin embargo, sospecho que en este caso específico el problema está mal planteado, el SSM puede no ser observable . Zkmaxk{dk+1}32m1m0NA
Yves

5

Puede hacerlo espectacularmente bien con una rutina estándar de mínimos cuadrados, siempre que tenga una idea razonable de los tamaños relativos de los errores aleatorios cometidos para cada derivada. No hay restricción en la cantidad de mediciones que realiza para cada valor de , incluso puede medir simultáneamente diferentes derivadas en cada una. La única limitación en el uso de mínimos cuadrados ordinarios (OLS) es la habitual: se supone que las mediciones son independientes.x

La idea básica se puede expresar más claramente abstrayendo el problema. Su modelo utiliza un conjunto de funciones (como cualquier base de spline) como base para predecir los valores de una función desconocida en los puntos Esto significa que busca estimar coeficientes para los cuales cada una de las combinaciones lineales aproxima aceptablemente a Llamemos a este espacio (vector) de combinaciones linealespfj:RR, j=1,2,,pyi=f(xi)f(x1,x2,,xn).βjjβjfj(xi)yi.F.

Lo especial de este problema es que no necesariamente observas elyi. En cambio, hay un conjunto definido de funciones lineales asociado con los datos. Recuerde que un funcional es una "función de una función": cada asigna un número a cualquier función El modelo postula queLiLiLi[f]fF.

(1)yi=Li[f]+σiεi

donde los reciben funciones, el son factores de escala conocidos y el son variables aleatorias independientes e idénticamente distribuidas.Liσi>0εi

Dos supuestos adicionales hacen que OLS sea aplicable y estadísticamente significativo:

  1. La distribución común de tiene una variación finita.εi

  2. Cada es un funcional lineal . Un es lineal cuando para cualquier elemento y los números correspondientesLiLfjFαj,

    L[jαjfj]=jαjL[fj].

(2) permite que el modelo se exprese más explícitamente como(1)

yi=β1Li[f1]++βpLi[fp]+σiεi.

El objetivo de esta reducción es que debido a que usted ha estipulado todos los funcionales todas las funciones de base y las desviaciones estándar los valores son todos los números - -se trata de las "variables" o "características" habituales de un problema de regresión, y son meras ponderaciones (relativas). Por lo tanto, en el sentido óptimo del teorema de Gauss-Markov, OLS es un gran procedimiento para usar.Li,fj,σi,Li[fj]σi

Los funcionales involucrados en la pregunta son los siguientes:

  • Evalúe en un punto específico Esto es lo que solemos hacer. Esto es lineal porque, por definición, las combinaciones lineales de funciones se evalúan puntualmente.fx: L[f]=f(x).

  • Evalúe la derivada en un punto específico Esto es lineal porque la diferenciación es lineal.fx: L[f]=f(x).

  • Evalúe la segunda derivada en un punto específicofx: L[f]=f(x).


Bien, ¿qué tan bien funciona este enfoque? Como de costumbre, estudiaremos los residuos comparando los valores ajustados con los valores observados. Dado que las posiciones, las velocidades y las aceleraciones están en unidades diferentes, deben trazarse en ejes separados.y^iyiy^i

Figura

La fila superior usa curvas para graficar y sus dos primeras derivadas. Los puntos de datos relevantes se trazan sobre las curvas: valores observados a la izquierda, derivadas observadas en el medio y segundas derivadas observadas a la derecha.y^

La fila inferior traza los residuos correspondientes. Como de costumbre, estamos buscando una falta de relación apreciable: esperamos que los valores residuales (sus coordenadas y) varíen aleatoriamente de izquierda a derecha, mostrando independencia y sin tendencias.

Los valores de datos se generaron exactamente como en la pregunta (después de establecer la semilla de número aleatorio en 17 usando para la reproducibilidad). Exploré los ajustes usando los espacios B-spline generados por la función , también como en la pregunta, para los grados 1 a 6. Esta figura muestra los resultados para el grado 2, que es el grado más bajo (es decir, el modelo más simple) exhibiendo un AIC bajo y un buen comportamiento residual, así como el modelo indicado por un ANOVA de los seis modelos (anidados).n=23set.seed(17)FRbs

El ajuste es

y^=27.48993+2.54078f1+2.97679f2

donde y son las funciones B-spline creadas por .f1f2bs

Los residuos se comportan bien. Los ajustes son buenos. Además, este enfoque encontró el modelo correcto : los datos se generaron a partir de una función cuadrática (grado 2). Además, las desviaciones estándar de los residuos son aproximadamente los tamaños correctos: 0.11, 0.20 y 0.61 en comparación con 0.1, 0.3 y 0.6 utilizados para generar los errores originales. Eso es bastante sorprendente dado que estas curvas obviamente extrapolan las observaciones (que no van más allá de ) y usan un conjunto de datos tan pequeño ( ).x=5n=23

Finalmente, los residuos de los ajustes para splines de mayor grado son cualitativamente los mismos; solo realizan ligeras mejoras a un costo de usar modelos menos plausibles. Para grados suficientemente altos, comienzan a oscilar violentamente para valores pequeños de entre los valores observados, por ejemplo. Para ilustrar este comportamiento (malo), aquí está el ajuste de grado 9:x

Figura 2

Finalmente, aquí hay un ejemplo donde se hicieron múltiples observaciones de varios funcionales lineales de la base. El código para generar estas observaciones cambió de aquel en la pregunta a

mult <- 2
x_f <- rep(runif(5, 0, 5), mult)       # Two observations per point
x_df <- rep(runif(8, 3, 8), mult)      # Two derivatives per point
x_ddf <- c(x_df, rep(runif(10, 4, 9))  # Derivative and acceleration per point

figura 3


El Rcódigo para llevar estos cálculos es bastante general. En particular, utiliza la diferenciación numérica para encontrar las derivadas de modo que no dependa del tipo de spline utilizado. Maneja los diferentes valores de ponderando las observaciones proporcionalmente a Construye y se ajusta automáticamente a un conjunto de modelos en un bucle. Los funcionales lineales y las desviaciones estándar están codificados. Hay tres de cada uno, seleccionados de acuerdo con el valor de la variable en el conjunto de datos.σi1/σi2.Liσitype

Como ejemplos de cómo puede usar los ajustes, la Coda imprime resúmenes, una lista de sus AIC y un ANOVA de todos ellos.

#
# Estimate spline derivatives at points of `x`.
#
d <- function(x, s, order=1) {
  h <- diff(range(x, na.rm=TRUE))
  dh <- h * 1e-4
  lags <- seq(-order, order, length.out=order+1) * dh/2
  b <- choose(order, 0:order) * (-1)^(order:0)
  y <- b %*% matrix(predict(s, c(outer(lags, x, `+`))), nrow=length(lags))
  y <- matrix(y / (dh^order), nrow=length(x))
}
#
# Fit and plot models by degree.
#
data$order <- c(f=0, df=1, ddf=2)[data$type]
k <- max(data$order)
x <- data$x
w <- (c(0.1, 0.3, 0.6)^(-2))[data$order+1] # As specified in the question

fits <- lapply(1:6, function(deg) {
  #
  # Construct a model matrix.
  #
  s <- bs(x, degree=deg, intercept=TRUE)
  X.l <- lapply(seq.int(k+1)-1, function(i) {
    X <- subset(data, order==i)
    Y <- as.data.frame(d(X$x, s, order=i))
    cbind(X, Y)
  })
  X <- do.call("rbind", X.l)
  #
  # Fit WLS models.
  #
  f <- as.formula(paste("y ~ -1 +", paste0("V", 0:deg+1, collapse="+")))
  fit <- lm(f, X, weights=w)
  msr <- tapply(residuals(fit), data$order, function(r) {
    k <- length(r) - 1 - deg
    ifelse(k >= 1, sum(r^2) / k, 1)
  })
  #
  # Compute predicted values along the graphs.
  #
  X.new <- data.frame(x = seq(min(X$x), max(X$x), length.out=101))
  X.new$y.hat <- predict(s, X.new$x) %*% coefficients(fit)
  X.new$Dy.hat <- d(X.new$x, s, 1) %*% coefficients(fit)
  X.new$DDy.hat <- d(X.new$x, s, 2) %*% coefficients(fit)
  X$Residual <- residuals(fit)
  #
  # Return the model.
  #
  fit$msr <- msr
  fit
})
lapply(fits, function(f) sqrt(f$msr))
lapply(fits, summary)
lapply(fits, AIC)
do.call("anova", fits)

1

En primer lugar, quiero agradecerles por plantear esta pregunta. Es una pregunta REALMENTE interesante. Me encantan las estrías y las cosas geniales que puedes hacer con ellas. Y esto me dio una excusa para investigar un poco. :-)

BLUF: La respuesta corta es no. No conozco ninguna funcionalidad en R que haga esto automáticamente. La respuesta larga es ... mucho más complicada. El hecho de que las derivadas y los valores de función no se muestreen en el mismo lugar hace que esto sea más difícil. Y el hecho de que no tenga un valor de función cerca del extremo derecho del intervalo podría hacerlo imposible.

Comencemos con la spline cúbica. Dados los puntos y las segundas derivadas correspondientes , la spline cúbica que las atraviesa es:(xj,yj)zj

Sj(x)=Ayj+Byj+1+Czj+Dzj+1
donde Es bastante sencillo verificar que , , y . Esto garantiza que la spline y su segunda derivada sean continuas. Sin embargo, en este punto, no tenemos una primera derivada continua . Para forzar que la primera derivada sea continua, necesitamos la siguiente restricción:
hj=xj+1xjA=xj+1xhjB=1AC=16(A3A)hj2D=16(B3B)hj2
Sj(xj)=yjSj(xj+1)=yj+1Sj(xj)=zjSj(xj+1)=zj+1
(1)6hj1yj1(6hj1+6hj)yj+6hjyj+1=hj1zj1+2(hj1+hj)zj+hjzj+1
En la configuración clásica de spline cúbica, asume que tiene los puntos y usa la ecuación (junto con dos restricciones de límite adicionales) para resolver . Una vez que conoce , la spline está completamente especificada y puede usarla para interpolar en cualquier punto arbitrario. Como adicional, la ecuación convierte en una matriz tridiagonal que se puede resolver en tiempo lineal.(xj,yj)(1)zjzj(1)

Bien, ahora suponga que, en lugar de conocer , conoce . ¿Puedes usar la ecuación para resolver ? Desde un punto de vista de álgebra pura, parece factible. Hay ecuaciones y incógnitas, así que ... ¿por qué no? Pero resulta que no puedes; La matriz será singular. Y eso no debería sorprendernos. ¿Cómo podrías interpolar los valores de la función dados SOLO las segundas derivadas? Como mínimo, necesitaría un valor inicial, al igual que una ecuación diferencial.yjzj(1)yjNN

¿Qué hay de tu situación? Algunos de sus puntos tienen valores de función y algunos de sus puntos tienen derivadas. Por el momento, ignoremos las primeras derivadas (son un desastre para tratar en la base spline cúbica). Formalmente, sea sea ​​el conjunto de puntos con valores de función y sea ​​el conjunto de puntos con segundas derivadas. Todavía tenemos ecuaciones con incógnitas. Es solo que algunas de las incógnitas son y otras son . Resulta que obtendrá una solución si 0, 1 o 2 AND o(xi,yi),iI(xj,zj),jJNNyjzjIN3,N2N1I. En otras palabras, uno de los primeros tres puntos tiene que ser un valor de función Y uno de los últimos tres puntos tiene que ser un valor de función. Aparte de esa restricción, eres libre de agregar tantos derivados como quieras.

¿Qué tal esos primeros derivados? Ciertamente es posible incluir primeras derivadas en su spline. Pero, como dije, se vuelve mucho más desordenado. La primera derivada de la spline viene dada por: Por supuesto, solo estamos realmente interesados ​​en la derivada en los nudos, por lo que podemos simplificar esto un poco al evaluarlo en : Puede agregar estos restricciones a la matriz que obtienes de la ecuación

Sj(x)=yj+1yjhj3A216hjzj+3B216hjzj+1
xj
Sj(xj)=yj+1yjhj13hjzj16hjzj+1
(1)y la spline resultante tendrá las primeras derivadas especificadas. Además, esto ayudará con el problema de la matriz singular. Obtendrá una solución si TIENE un valor de función o una primera derivada en los primeros tres y últimos tres puntos.

Así que puse todo junto en un código y aquí está la imagen que obtuve:

Spline salió horrible mal

Como puede ver, los resultados no son excelentes. Esto se debe a que esta es una spline regular que debe respetar TODOS los datos. Dado que los datos son estocásticos, realmente necesitamos usar una spline de regresión. Ese es un tema para otra publicación. Pero si trabaja con las matemáticas, terminará optimizando una función objetivo cuadrática sujeta a restricciones de igualdad lineal, ¡y hay una solución de forma cerrada!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.