# Dot broadcasting of an assignment to a tuple

**URL:** https://discourse.julialang.org/t/dot-broadcasting-of-an-assignment-to-a-tuple/95829
**Category:** Statistics
**Created:** [March 9, 2023, 10:44pm UTC](https://discourse.julialang.org/t/dot-broadcasting-of-an-assignment-to-a-tuple/95829 "2023-03-09T22:44:59Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)
#### Post date: [March 9, 2023, 10:44pm UTC](https://discourse.julialang.org/t/dot-broadcasting-of-an-assignment-to-a-tuple/95829/1 "2023-03-09T22:44:59Z")

</div>

The context of this question is an algorithm called _iteratively re-weighted least squares_ (IRLS) used to fit _generalized linear models_ (GLMs). At each iteration vectors of the _mean responses_, `μ`, the _unit deviances_, `dev`, the _working weights_, `wwt`, and the _working residuals_, `wres`, are updated from a _response vector_, `y`, and a _linear predictor_, `η`.

These updates can be expressed as scalar evaluations to be mapped over the vectors. An example for a GLM with a Bernoulli response and the logit link function (for which the inverse link is the logistic function) can be run with

[Bernoulliupdate.jl](https://discourse.julialang.org/uploads/short-url/8FwVwh5px9ToBEwfHjRQW5dU1HV.jl) (934 Bytes)

Is there a way of writing this update using dot-vectorization? I tried expressions like

```julia
(μ, dev, wwt, wres) .= Bernoulliupdate.(y, η)

```

to update four vectors at once but that failed under Julia v1.8.5

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [March 9, 2023, 11:09pm UTC](https://discourse.julialang.org/t/dot-broadcasting-of-an-assignment-to-a-tuple/95829/2 "2023-03-09T23:09:20Z")

</div>

It’s probably best/cleanest to gather all your vectors into a single array, basically make a table.  
Then you get the desired broadcasting syntax:

```julia
# your Bernoulliupdate:
julia> f(x) = (a=x, b=x+1)

# your μ, dev, wwt, wres vectors together:
julia> A = StructArray(a=rand(2), b=rand(2))
2-element StructArray(::Vector{Float64}, ::Vector{Float64}) with eltype NamedTuple{(:a, :b), Tuple{Float64, Float64}}:
 (a = 0.7037272421570892, b = 0.9034695137409692)
 (a = 0.1435058682650946, b = 0.6068241303562021)

julia> A .= f.([1,2])
2-element StructArray(::Vector{Float64}, ::Vector{Float64}) with eltype NamedTuple{(:a, :b), Tuple{Float64, Float64}}:
 (a = 1.0, b = 2.0)
 (a = 2.0, b = 3.0)

```

Alternatively, and potentially even more conveniently, you can put all vectors into a single array, including y and η:

```julia
# your Bernoulliupdate:
julia> f(x) = (a=x.c, b=x.c+1)

julia> A = StructArray(a=rand(2), b=rand(2), c=rand(2))
# instead of broadcasting:
julia> map!(x -> merge(x, f(x)), A, A)
```
