# Finding matrices with the same l1 and l2 norm

**URL:** <https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404>\
**Category:** General Usage\
**Tags:** linearalgebra\
**Created:** [October 27, 2022, 9:26pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404 "2022-10-27T21:26:22Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [October 27, 2022, 9:26pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/1 "2022-10-27T21:26:22Z")

</div>

I want to begin with a matrix, A, and find a matrix where the l2 norm is the same as it is for A, but the l1 norm is reduced so that it is the same as the l2 norm. There is only 1 eigenvalue, which is the square of the l2 norm.

I also need to be able to reverse whatever this transformation is.

Is there a way to do this in Julia already prepared somewhere?

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [October 27, 2022, 11:33pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/2 "2022-10-27T23:33:39Z")

</div>

Is there some other relation that the new matrix must have with the original? If you just want a matrix with L1 and L2 norms set to the same value, you can do this

```julia
julia> σ = 19/4
4.75

julia> A = [σ 0; 0 0]
2×2 Matrix{Float64}:
 4.75 0.0
 0.0 0.0

julia> opnorm(A,1)
4.75

julia> opnorm(A,2)
4.75

```

---

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [October 28, 2022, 12:11am UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/3 "2022-10-28T00:11:16Z")

</div>

Thanks - sorry, I forgot to mention, it should be a rotation of the original.

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [October 28, 2022, 5:14pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/4 "2022-10-28T17:14:55Z")

</div>

What about this?

```julia
julia> using LinearAlgebra

julia> x = rand(3); A = x * x' # A is some random rank-1 matrix
3×3 Matrix{Float64}:
 0.0325498 0.0425725 0.16186
 0.0425725 0.0556812 0.211699
 0.16186 0.211699 0.804876

julia> opnorm(A, 1) ≈ opnorm(A, 2)
false

julia> (λ, U) = eigen(A);

julia> λ[3] ≈ opnorm(A, 2)
true

julia> B = U' * A * U # B is rotation of A (U is unitary)
3×3 Matrix{Float64}:
  1.60678e-19 -9.80364e-19 -5.815e-17
  3.23819e-18 -4.94158e-18 -1.73788e-16
 -2.77556e-17 -1.66533e-16 0.893107

julia> opnorm(B, 1) ≈ opnorm(B, 2) ≈ opnorm(A, 2)
true

julia> C = U * B * U'; C ≈ A # Transformation is reversible
true

```

EDIT: This code assumes the matrix is symmetric/Hermitian (i.e., has a unitary eigendecomposition). See my next post for a more general solution.

---

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [October 28, 2022, 6:25pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/5 "2022-10-28T18:25:47Z")

</div>

Amazing, thank you!!

I am just having a small error with

```julia
julia> λ[5.6141820573374055] ≈ opnorm(A, 2)

```

when the value includes a decimal place:

```julia
ERROR: ArgumentError: invalid index: 5.6141820573374055 of type Float64

```

---

<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:** [October 28, 2022, 6:30pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/6 "2022-10-28T18:30:29Z")

</div>

You can’t index a vector at a non-integer index. What did you want to do?

---

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [October 28, 2022, 6:40pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/7 "2022-10-28T18:40:01Z")

</div>

> [@StevenWhitaker](#):
>
> ```julia
> B = U' * A * U # B is rotation of A (U is unitary)
> 3×3 Matrix{Float64}:
> 1.60678e-19 -9.80364e-19 -5.815e-17
> 3.23819e-18 -4.94158e-18 -1.73788e-16
> -2.77556e-17 -1.66533e-16 0.893107
> 
> julia> opnorm(B, 1) ≈ opnorm(B, 2) ≈ opnorm(A, 2)
> true
> 
> julia> C = U * B * U'; C ≈ A # Transformation is reversible
> true
> 
> ```

Ah, it should have been my matrix size in there, not the eigenvalue…

```julia
λ[10] ≈ opnorm(A, 2)

```

But unfortunately

```julia
B = U' * A * U

```

doesn’t work for my matrix:

```julia
opnorm(B, 1) ≈ opnorm(B, 2) ≈ opnorm(A, 2)

```

is false  
opnorm(B, 1) = 7.815593862067465  
opnorm(B, 2) = 5.637588182823125  
opnorm(A, 2) = 5.6141820573374055

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [October 31, 2022, 5:06pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/8 "2022-10-31T17:06:55Z")

</div>

Sorry, I just realized I assumed your matrix was symmetric/Hermitian (i.e., had a unitary eigendecomposition). More generally, you want to use the singular value decomposition:

```julia
julia> using LinearAlgebra

julia> x = rand(3); y = rand(3); A = x * y' # A is some random rank-1 matrix
3×3 Matrix{Float64}:
 0.206881 0.02146 0.00257651
 0.139733 0.0144947 0.00174024
 0.395132 0.0409876 0.004921

julia> opnorm(A, 1) ≈ opnorm(A, 2)
false

julia> (U, σ, V) = svd(A);

julia> σ[1] ≈ opnorm(A, 2)
true

julia> B = U' * A * V # B is rotation of A (U and V are unitary)
3×3 Matrix{Float64}:
  0.469935 1.04626e-17 -8.67362e-19
  2.86845e-17 7.47916e-18 -3.92335e-19
 -0.0 0.0 0.0

julia> opnorm(B, 1) ≈ opnorm(B, 2) ≈ opnorm(A, 2)
true

julia> C = U * B * V'; C ≈ A # Transformation is reversible
true

```

---

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [October 31, 2022, 11:18pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/9 "2022-10-31T23:18:46Z")

</div>

What an easy way to do it! Is there a similar trick for non square matrices?  
Can you know how much this rotates it? Or is it tailored for each matrix?

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [November 1, 2022, 5:44pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/10 "2022-11-01T17:44:17Z")

</div>

> [@ccccc](#):
>
> Is there a similar trick for non square matrices?

The same code works regardless of the dimensions of the matrix (all matrices, square or not, have a singular value decomposition).

> [@ccccc](#):
>
> Can you know how much this rotates it?

I’m not sure what you mean by this. Once you compute the SVD of the matrix, then yes, you know how much the matrix is rotated (here rotation is a multidimensional generalization of what we typically envision when we think of rotation).

> [@ccccc](#):
>
> Or is it tailored for each matrix?

Yes, each matrix has its own SVD. So you can’t precompute `U` and `V` and have it work for any arbitrary matrix, if that’s what you’re asking. Though if you have an application where all your matrices share the same left and right singular vectors (`U` and `V` matrices), then you could compute the SVD just once and reuse `U` and `V`. But I’m not aware of any such application.

---

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [November 1, 2022, 8:51pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/11 "2022-11-01T20:51:31Z")

</div>

Thanks - unfortunately it’s not working the same way with non-square matrices. The resulting matrix is a different size, and the l1 norm is actually smaller than the l2 a lot of the time. This might just be the way it has to be, I guess?  
I tried doing full matrices and then adding zeros to the end of S and V, but this didn’t help.

I was wondering whether whenever you rotate by U.T it would rotate ‘A’ a specific amount from what it would be if you had done `U*A*V`, like 90 degrees, or whether the actual rotation from U to U.T depends on what the actual rotation matrix ‘U’ looks like…

Anyway, it’s great to know this for square matrices, thank you!

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [November 1, 2022, 10:06pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/12 "2022-11-01T22:06:00Z")

</div>

> [@ccccc](#):
>
> unfortunately it’s not working the same way with non-square matrices

Strange, because it worked for me for a random 3 \times 2 matrix (and a random 2 \times 3 matrix). Could you provide an example matrix for which it failed?

> [@ccccc](#):
>
> The resulting matrix is a different size, and the l1 norm is actually smaller than the l2 a lot of the time.

This is, again, strange, because it is theoretically impossible. An example of a matrix that came to this result would be useful here, too.

> [@ccccc](#):
>
> I was wondering whether whenever you rotate by U.T it would rotate ‘A’ a specific amount

The `U` and `V` matrices returned by `svd` (with the `full` keyword argument set to `true`) are unitary matrices (where a unitary matrix is a generalization of a rotation matrix). A matrix U is unitary iff U'U = UU' = I. Thinking about it as a rotation, if U rotates by \theta, then U' rotates by -\theta (rotation by U' undoes the rotation by U).

---

<div class="post-metadata">

**Author:** ![ccccc](https://avatars.discourse-cdn.com/v4/letter/c/aca169/32.png) [@ccccc](https://discourse.julialang.org/u/ccccc)\
**Post date:** [November 1, 2022, 11:37pm UTC](https://discourse.julialang.org/t/finding-matrices-with-the-same-l1-and-l2-norm/89404/13 "2022-11-01T23:37:50Z")

</div>

> [@StevenWhitaker](#):
>
> The `U` and `V` matrices returned by `svd` (with the `full` keyword argument set to `true`) are unitary matrices (where a unitary matrix is a generalization of a rotation matrix). A matrix U UU is unitary iff U’U = UU’ = I U′U=UU′=IU’U = UU’ = I . Thinking about it as a rotation, if U UU rotates by \theta θ\theta , then U’ U′U’ rotates by -\theta −θ-\theta (rotation by U’ U′U’ undoes the rotation by U UU ).

Thanks, that’s really helpful.

And… it does work! I had python open yesterday when I looked at this, so I just did it in there. Seems like it might be a bug there.

I was hoping that doing a rotation whereby the l1 and l2 norms are the same might be the rotation with the minimum singular values, since that’s what it would be for σ. I did find a rotation that does minimise them today though. I’m not sure it will be helpful for what i’m doing though, so I will try with both. Thank you!
