# MLE and Quantile Evaluation for a Clayton AR(1) Model with Student Marginals

#### Original demo from Roeger Koenker; by Marius Hofert, Ivan Kojadinovic, Martin Mächler, Jun Yan

#### 2026-01-13

    require(copula)
    set.seed(271)

First, let’s fix some parameters.

    mu <- 0
    sigma <- 1
    df <- 3
    alpha <- 10

For the marginals, we will use location- and scale- transformed Student distributions (only `dtls` and `ptls` are necessary for fitting).

    rtls <- function(n, df, mu, sigma) sigma * rt(n,df) + mu
    ptls <- function(x, df, mu, sigma) pt((x - mu)/sigma,df)
    qtls <- function(u, df, mu, sigma) sigma * qt(u,df) + mu
    dtls <- function(u, df, mu, sigma) dt((x - mu)/sigma,df)/sigma

## Generating the data

Let’s generate some data.

    rclayton <- function(n, alpha) {
        u <- runif(n+1) # innovations
        v <- u
        for(i in 2:(n+1))
                v[i] <- ((u[i]^(-alpha/(1+alpha)) -1)*v[i-1]^(-alpha) +1)^(-1/alpha)
        v[2:(n+1)]
    }
    n <- 200
    u <- rclayton(n, alpha = alpha)
    u <- qtls(u, df=df, mu=mu, sigma=sigma)
    y <- u[-n]
    x <- u[-1]

We now estimate the parameters under known marginals

    fitCopula(claytonCopula(dim=2),
              cbind(ptls(x,df,mu,sigma), ptls(y,df,mu,sigma))) -> fmN
    summary(fmN) # alpha 11.08 (0.858)

    ## Call: fitCopula(claytonCopula(dim = 2), cbind(ptls(x, df, mu, sigma),
    ##     ptls(y, df, mu, sigma)))
    ## Fit based on "maximum pseudo-likelihood" and 199 2-dimensional observations.
    ## Clayton copula, dim. d = 2
    ##       Estimate Std. Error
    ## alpha    11.08      0.858
    ## The maximized loglikelihood is 226.5
    ## Optimization converged
    ## Number of loglikelihood evaluations:
    ## function gradient
    ##        7        7

## Estimation under unknown marginal parameters

    ## Identical margins
    M2tlsI <- mvdc(claytonCopula(dim=2), c("tls","tls"),
                   rep(list(list(df=NA, mu=NA, sigma=NA)), 2), marginsIdentical= TRUE)
    (fit.id.mar <- fitMvdc(cbind(x,y), M2tlsI, start=c(3,1,1, 10), optim.control = list(trace=TRUE)))

    ## initial  value 446.087010
    ## iter  10 value 338.225036
    ## final  value 338.224762
    ## converged
    ## initial  value 338.224762
    ## final  value 338.224762
    ## stopped after 1 iterations

    ## Call: fitMvdc(data = cbind(x, y), mvdc = M2tlsI, start = c(3, 1, 1,
    ##     10), optim.control = list(trace = TRUE))
    ## Maximum Likelihood estimation based on 199 2-dimensional observations.
    ## Copula:  claytonCopula
    ## Identical margins:
    ##    m.df    m.mu m.sigma
    ##  3.9098  0.4095  0.7320
    ## Copula:
    ## alpha
    ## 5.938
    ## The maximized loglikelihood is -338.2
    ## Optimization converged

    ## Not necessarily identical margins
    M2tls <- mvdc(claytonCopula(dim=2), c("tls","tls"),
                  rep(list(list(df=NA, mu=NA, sigma=NA)), 2))
    fitMvdc(cbind(x,y), M2tls, start=c(3,1,1, 3,1,1, 10))

    ## Call: fitMvdc(data = cbind(x, y), mvdc = M2tls, start = c(3, 1, 1,
    ##     3, 1, 1, 10))
    ## Maximum Likelihood estimation based on 199 2-dimensional observations.
    ## Copula:  claytonCopula
    ## Margin 1 :
    ##    m1.df    m1.mu m1.sigma
    ##   3.7851   0.4150   0.7288
    ## Margin 2 :
    ##    m2.df    m2.mu m2.sigma
    ##   4.0760   0.4046   0.7358
    ## Copula:
    ## alpha
    ## 5.944
    ## The maximized loglikelihood is -338.1
    ## Optimization converged

## Plot some true and estimated conditional quantile functions

    u.cond <- function(z, tau, df, mu, sigma, alpha)
        ((tau^(-alpha/(1+alpha)) -1) * ptls(z,df,mu,sigma)^(-alpha) + 1) ^ (-1/alpha)
    y.cond <- function(z, tau, df, mu, sigma, alpha) {
        u <- u.cond(z, tau, df, mu, sigma, alpha)
        qtls(u, df=df, mu=mu, sigma=sigma)
    }
    plot(x, y)
    title("True and estimated conditional quantile functions")
    mtext(quote("for" ~~  tau == (1:5)/6))
    z <- seq(min(y),max(y),len = 60)
    for(i in 1:5) {
        tau <- i/6
        lines(z, y.cond(z, tau, df,mu,sigma, alpha))
        ## and compare with estimate:
        b <- fit.id.mar@estimate
        lines(z, y.cond(z, tau, df=b[1], mu=b[2], sigma=b[3], alpha=b[4]),
              col="red")
    }