# Passing struct as argument to optimizer

**URL:** https://discourse.julialang.org/t/passing-struct-as-argument-to-optimizer/109209
**Category:** General Usage
**Tags:** optim, struct, parametersjl
**Created:** [January 24, 2024, 8:02pm UTC](https://discourse.julialang.org/t/passing-struct-as-argument-to-optimizer/109209 "2024-01-24T20:02:26Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![structural](https://avatars.discourse-cdn.com/v4/letter/s/34f0e0/32.png) [@structural](https://discourse.julialang.org/u/structural)
#### Post date: [January 24, 2024, 8:02pm UTC](https://discourse.julialang.org/t/passing-struct-as-argument-to-optimizer/109209/1 "2024-01-24T20:02:26Z")

</div>

Is it possible to pass a struct of parameters as an argument to an optimizer? The example below estimates an OLS model in which the intercept and slope are passed a vector `p`.

```julia
function ssr(y,x,p)
    return sum((y .- (p[1] .+ p[2] .* x)).^2)
end

x1 = cumsum(ones(10))
y1 = 2 .+ 3 .* x1 .+ rand(10)

Optim.minimizer(optimize(p->ssr(y1,x1,p), ones(2)))

```

Is it possible to instead pass the intercept and slope as a struct?

```julia
struct ols_struct
   intercept::Float64
   slope::Float64
end
p = ols_struct(1,1)

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [January 24, 2024, 8:18pm UTC](https://discourse.julialang.org/t/passing-struct-as-argument-to-optimizer/109209/2 "2024-01-24T20:18:44Z")

</div>

Most optimizers expect a vector of unknowns, but you can just wrap an anonymous function around your struct `p -> ols_struct(p[1], p[2])`.

---

<div class="post-metadata">

### Author: ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)
#### Post date: [January 24, 2024, 9:38pm UTC](https://discourse.julialang.org/t/passing-struct-as-argument-to-optimizer/109209/3 "2024-01-24T21:38:51Z")

</div>

Most optimizers require flat arrays, but there are some options to pass more structured data instead:

```julia
function nice_ssr(y, x, p)
     sum(@. (y - (p.intercept + p.slope * x))^2)
end

```

[ComponentArrays.jl](https://github.com/jonniedie/ComponentArrays.jl) which allows to treat (nested) named tuples as flat vectors

```julia
using ComponentArrays

p0 = ComponentArray(intercept = 1.0, slope = 1.0)
optimize(p -> nice_ssr(y1, x1, p), p0)

```

or if you prefer using structs, [Functors.jl](https://github.com/FluxML/Functors.jl/tree/master) which help in converting between (nested) structs and flat vectors:

```julia
using Functors

 @functor ols_struct
_, rebuild = Functors.functor(ols_struct(1.0, 1.0))
optimize(x -> nice_ssr(y1, x1, rebuild(x)), ones(2))

```
