## Introduction

All major parts of `online()`

are implemented in C++ for
speed. Usually, this comes at the cost of flexibility. However, the
profoc package exposes a C++ class `conline`

that allows you
to gain fine grained control over objects.`online()`

wraps this class and provides a convenient
interface for the most common use cases. However, if you need to alter
object initialization (i.e. provide custom basis / hat matrices for
smoothing) you can use the C++ class directly from R. This vignette
shows how to do this.

Note that we will reuse the data from
`vignette("profoc")`

.

## Online learning with `conline`

First, we need to create a new instance of the c++ class. This can be
done by calling `new(conline)`

.

Now we need to pass the data to the class instance. The whole list of
accessible field can be printed with `names(model)`

. Most of
them have defaults.

```
model$y <- y
tau <- 1:P / (P + 1)
model$tau <- tau
```

The experts array is a bit more complicated. C++ expects us to pass a
list of arrays. Thereby, the list itself must have dimension
`Tx1`

and the elements of the list (the arrays)
`D x P x K`

. For convenience we can use
`init_experts_list()`

to create such a list from our experts
array. Note that we must pass the true observations as well. They are
used to detect whether the data is univariate (`T x 1`

matrix) or multivariate (`T x D`

matrix).

```
experts_list <- init_experts_list(experts, y)
model$experts <- experts_list
```

Now suppose we want to alter the smoothing behavior across quantiles. We start by creating a new hat matrix.

```
hat <- make_hat_mats(
x = tau,
mu = 0.2, # Put more knots in the lower tail
periodic = TRUE
)
str(hat)
#> List of 2
#> $ hat :List of 1
#> ..$ :Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
#> .. .. ..@ i : int [1:99] 0 1 2 3 4 5 6 7 8 9 ...
#> .. .. ..@ p : int [1:100] 0 1 2 3 4 5 6 7 8 9 ...
#> .. .. ..@ Dim : int [1:2] 99 99
#> .. .. ..@ Dimnames:List of 2
#> .. .. .. ..$ : NULL
#> .. .. .. ..$ : NULL
#> .. .. ..@ x : num [1:99] 1 1 1 1 1 1 1 1 1 1 ...
#> .. .. ..@ factors : list()
#> ..- attr(*, "dim")= int [1:2] 1 1
#> $ params: num [1, 1:9] 99 0.2 1 0 1 ...
#> ..- attr(*, "dimnames")=List of 2
#> .. ..$ : NULL
#> .. ..$ : chr [1:9] "n" "mu" "sigma" "nonc" ...
```

We need a list of sparse matrices which `make_hat_mats()`

returns. So we can pass that directly to our class.

`model$hat_pr <- hat$hat`

The other smoothing matrices have to be filled with defaults (lists
of sparse identity matrices). Usually `online()`

takes care
of this. But we can do it manually as well.

```
model$basis_mv <- list(Matrix::sparseMatrix(i = 1:D, j = 1:D, x = 1))
model$basis_pr <- list(Matrix::sparseMatrix(i = 1:P, j = 1:P, x = 1))
model$hat_mv <- list(Matrix::sparseMatrix(i = 1:D, j = 1:D, x = 1))
```

Now we can specify the parameter grid. We will stick to the defaults here:

```
parametergrid <- as.matrix(
expand.grid(
forget_regret = 0,
soft_threshold = -Inf,
hard_threshold = -Inf,
fixed_share = 0,
basis_pr_idx = 1,
basis_mv_idx = 1,
hat_pr_idx = 1,
hat_mv_idx = 1,
gamma = 1,
loss_share = 0,
regret_share = 0
)
)
model$params <- parametergrid
```

Finally, we can run `model$set_defaults()`

. This populates
initial states (w0 for weights and R0 for regret).

`model$set_defaults()`

Now `model$set_grid_objects()`

will create the grid
objects (performance, weights, regret etc.)

`model$set_grid_objects()`

Finally, we can run `model$learn()`

to start the learning
process.

`model$learn()`

## Accessing the results

The learning process fills the class objects. So we can inspect them
using the `$`

operator, like we would with any other R
object. For example, we can access the weights:

```
head(model$weights[[T]][, , 1])
#> [1] 0.4892732 0.4058720 0.5979021 0.5770314 0.5487374 0.6287706
```

However, we can also use the post processing function of
`online()`

to access the results. This will create output
that is identical to the output of `online()`

:

```
names <- list(y = dimnames(y))
names$experts <- list(
1:T,
paste("Marginal", 1:D),
tau,
paste("Expert", 1:N)
)
output <- post_process_model(model, names)
```

We can now use `output`

in `update()`

,
`plot()`

and others.

At this point, we do not need to keep the model in memory anymore. So we can delete it:

`rm(model)`

## Summary

The C++ class `conline`

allows you to gain fine grained
control over the learning process. However, it is not as convenient as
the `online()`

wrapper. So you should only use it if you need
to alter the default behavior. However, mixing up helper functions from
`online()`

and the C++ class is possible. So you can compute
your combinations using the class interface while still being able to
use `update()`

, `plot()`

and others afterward.