# How to best program this function with cases?

**URL:** <https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703>\
**Category:** General Usage\
**Tags:** componentarrays\
**Created:** [September 24, 2021, 3:03pm UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703 "2021-09-24T15:03:21Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [September 24, 2021, 3:03pm UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/1 "2021-09-24T15:03:21Z")

</div>

I have this function that depends on cases `i`. I programmed it this way, but I am wondering if there is a better way of achieving the same result and with better performance.

```julia
using ComponentArrays

θ = ComponentArray(one=(α=0.1, γ=[0.2, 0.3]), two=(α=1.0, γ=[2.0, 3.0]))

function Zi(i, si; θ=θ)
    if i == 1
        α = θ.one.α
        γ = copy(θ.one.γ)
    elseif i == 2
        α = θ.two.α
        γ = copy(θ.two.γ)
    end
    α = exp(α)
    γ .= exp.(γ)
    abs(si)^α + sum(γ)
end

```

I also tried using value types, with a half the performance:

```julia
function _Zi(si, α, γ)
    α = exp(α)
    γ .= exp.(γ)
    abs(si)^α + sum(γ)
end

function Zi(::Val{1}, si; θ=θ)
    α = θ.one.α
    γ = copy(θ.one.γ)
    _Zi(si, α, γ)
end

function Zi(::Val{2}, si; θ=θ)
    α = θ.two.α
    γ = copy(θ.two.γ)
    _Zi(si, α, γ)
end

```

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [September 24, 2021, 3:10pm UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/2 "2021-09-24T15:10:44Z")

</div>

Why not just

```julia
α = [0.1, 1,0]
γ = [[0.2, 0.3], [2.0, 3.0]]

function Zi(i, si; α=α, γ=γ)
    α = exp(α[i])
    γ .= exp.(copy(γ[i]))
    abs(si)^α + sum(γ)
end

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [September 24, 2021, 4:28pm UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/3 "2021-09-24T16:28:06Z")

</div>

Creating value types from values not known at compile time forces dynamic dispatch. The situations for using them are very rare.

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [September 25, 2021, 1:19am UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/4 "2021-09-25T01:19:49Z")

</div>

I guess I have a problem of trying to use `ComponentArrays` too early into basic functions.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [September 25, 2021, 1:31am UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/5 "2021-09-25T01:31:45Z")

</div>

The way I look at it is that if you want your components to be numbers, you should just be using numbers instead of components. Components are useful for things like dimension names, but if you only want numbers, just use those.

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [September 25, 2021, 1:36am UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/6 "2021-09-25T01:36:04Z")

</div>

I use it for separating components of complex models. For example:

> [@Parsimonious way to unpack big structs](https://discourse.julialang.org/t/parsimonious-way-to-unpack-big-structs/66522/9):
>
> using your example, it would be using ComponentArrays using UnPack p = ComponentArray(α=0.1, β=0.2, γ=0.3) function f2(x; p=p) @unpack α, β, γ = p return x^(α) + x^(β) + x^(γ) end I also like to organize the parameters inside the ComponentArray, for example: using ComponentArrays using UnPack # full model function model(p; data=data) @unpack p1, p2 = p @unpack data1, data2 = data # component 1 r1 = f1(p1; data=data1) # component 2 r2 = f2(p2; data=data…

---

<div class="post-metadata">

**Author:** ![jonniedie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonniedie/32/12842_2.png) [@jonniedie](https://discourse.julialang.org/u/jonniedie)\
**Post date:** [October 2, 2021, 7:37pm UTC](https://discourse.julialang.org/t/how-to-best-program-this-function-with-cases/68703/7 "2021-10-02T19:37:09Z")

</div>

You could do it this way, although the inner-arrays-of-components thing is not quite as performant or flexible as I’d like it to be. The performance is more tuned for looping over inner arrays of components rather than indexing into them. And as for the limitations on flexibility: each component in the array must be the same size/type/layout. In this case it looks like you’re fine there, though.

```julia
using ComponentArrays

θ = ComponentArray(θ=[(α=0.1, γ=[0.2, 0.3]), (α=1.0, γ=[2.0, 3.0])])

function Zi(i, si; θ=θ)
    θ = θ.θ
    α = θ[i].α
    γ = copy(θ[i].γ)
    α = exp(α)
    γ .= exp.(γ)
    abs(si)^α + sum(γ)
end

```
