# How to return a Symmetric matrix?

**URL:** <https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212>\
**Category:** General Usage\
**Tags:** linearalgebra\
**Created:** [April 29, 2021, 2:05am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212 "2021-04-29T02:05:05Z")\
**Posts on this page:** 11\
**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:** [April 29, 2021, 2:05am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/1 "2021-04-29T02:05:05Z")

</div>

I’m constructing the Hessian of the Rosenbrock function. I want the return of `h!` to be of type `Symmetric`.

```julia
using LinearAlgebra

# for completeness
function f(x; a=1, b=100)
    (a - x[1])^2 + b*(x[2] - x[1]^2)^2
end

function h!(H, x; a=1, b=100)
    H[1, 1] = 2 + 8b*x[1]^2 - 4b*(x[2] - x[1]^2)
    H[1, 2] = -4b*x[1]
    #H[2, 1] = H[1, 2] I want to save this step
    H[2, 2] = 2b
    return H = copy(Symmetric(H))
end

```

Now let’s use those functions:

```julia
julia> H=Matrix{Real}(undef, 2,2)
2×2 Matrix{Real}:
 #undef #undef
 #undef #undef

julia> h!(H, [1.0, 1.0])
2×2 Symmetric{Real, Matrix{Real}}:
  802.0 -400.0
 -400.0 200

# however
julia> H
2×2 Matrix{Real}:
 802.0 -400.0
 #undef 200

```

Changing the last line of `h!` to `copy!(H, Symmetric(H))` returns

```julia
julia> H
2×2 Matrix{Real}:
  802.0 -400.0
 -400.0 200

```

How can I make `h!` return a matrix of type `Symmetric`?

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [April 29, 2021, 2:48am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/2 "2021-04-29T02:48:41Z")

</div>

`return Symmetric(copy(H))`?

---

<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:** [April 29, 2021, 3:00am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/3 "2021-04-29T03:00:14Z")

</div>

Your function _is_ returning a `Symmetric` matrix, it’s just not changing the type of `H`. As far as I know you can’t mutate something to a different type. Once you assign a type to something, it’s always going to be that type.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [April 29, 2021, 3:25am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/4 "2021-04-29T03:25:40Z")

</div>

Sorry, one more step: you have to assign the result to `H`.

---

<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:** [April 29, 2021, 3:41am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/5 "2021-04-29T03:41:25Z")

</div>

Returns `Symmetric`. It doesn’t change the type of `H`.

---

<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:** [April 29, 2021, 3:49am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/6 "2021-04-29T03:49:07Z")

</div>

But this: `H = Symmetric(H)` changes the type of `H`.

---

<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:** [April 29, 2021, 3:53am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/7 "2021-04-29T03:53:01Z")

</div>

@amrods That rebinds the variable name `H` to a new object but it doesn’t mutate the type of `H` itself.

---

<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:** [April 29, 2021, 4:10am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/8 "2021-04-29T04:10:07Z")

</div>

I see, so I should have started with a symmetric matrix to begin with? For example restricting the type of `H` in as input to `g!` to be `Symmetric`?

---

<div class="post-metadata">

**Author:** ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)\
**Post date:** [April 29, 2021, 4:50am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/9 "2021-04-29T04:50:25Z")

</div>

> [@amrods](#):
>
> ```julia
> function h!(H, x; a=1, b=100)
> H[1, 1] = 2 + 8b*x[1]^2 - 4b*(x[2] - x[1]^2)
> H[1, 2] = -4b*x[1]
> #H[2, 1] = H[1, 2] I want to save this step
> H[2, 2] = 2b
> return H = copy(Symmetric(H))
> end
> 
> ```

Yes I think so, and then you should modify the upper part of the “parent”:

```julia
julia> H0 = Symmetric(rand(2,2))
2×2 Symmetric{Float64, Matrix{Float64}}:
 0.195095 0.336915
 0.336915 0.599351

julia> function h!(H::Symmetric, x; a=1, b=100)
           H.data[1, 1] = 2 + 8b*x[1]^2 - 4b*(x[2] - x[1]^2)
           H.data[1, 2] = -4b*x[1]
           #H[2, 1] = H[1, 2] I want to save this step
           H.data[2, 2] = 2b
           H
       end
h! (generic function with 1 method)

julia> h!(H0, ones(2))
2×2 Symmetric{Float64, Matrix{Float64}}:
  802.0 -400.0
 -400.0 200.0

```

---

<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:** [April 29, 2021, 4:53am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/10 "2021-04-29T04:53:19Z")

</div>

are those `.data` fields present because `H` is `Symmetric`?

---

<div class="post-metadata">

**Author:** ![briochemc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/briochemc/32/4209_2.png) [@briochemc](https://discourse.julialang.org/u/briochemc)\
**Post date:** [April 29, 2021, 4:58am UTC](https://discourse.julialang.org/t/how-to-return-a-symmetric-matrix/60212/11 "2021-04-29T04:58:08Z")

</div>

Yes, `S = Symmetric(A)` is a view of the parent `A`. And `A` can be reached with `S.data`. For completeness, `S` also contains a character, either `'u'` or `'l'` to tell if the view uses the upper or lower part of `A`. At the REPL, a quick way to check what’s in an object is to place a dot and hit TAB to autocomplete:

```julia
julia> H0 = Symmetric(rand(2,2))
2×2 Symmetric{Float64, Matrix{Float64}}:
 0.422018 0.115722
 0.115722 0.732627

julia> H0. # press TAB twice here with the cursor after the dot
data uplo

julia> H0.data # the non-symmetric parent
2×2 Matrix{Float64}:
 0.422018 0.115722
 0.0112565 0.732627

julia> H0.uplo # tells that we use the upper part of the parent, i.e., H0[1,2] == H0.parent[1,2]
'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)

```
