Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiplication and addition tests for custom arrays #98

Merged
merged 65 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ba96b35
Remove old array tests.
benedict-96 Dec 13, 2023
0fb9156
Removed the block matrices. This is now done by the LinearSympNetLayers.
benedict-96 Dec 13, 2023
dd4e8a5
Hope this fixed the TODO list.
benedict-96 Dec 13, 2023
35c0d48
We are not using those arrays anymore.
benedict-96 Dec 13, 2023
1f1e30d
Factored out sampling of arrays.
benedict-96 Dec 13, 2023
51c7c76
Got rid of some some symplectic arrays and included the supertype for…
benedict-96 Dec 13, 2023
3876be5
Updated docs.
benedict-96 Dec 13, 2023
48300b2
New supertype for the horizontal components.
benedict-96 Dec 13, 2023
0dfbc63
Added new routine for multiplying symmetric matrix from the right ont…
benedict-96 Dec 13, 2023
21bb931
Test addition of various custom arrays.
benedict-96 Dec 13, 2023
969a6cb
Removed tests for various symplectic arrays that are no longer part o…
benedict-96 Dec 13, 2023
e0b81cf
Added routine for Base.one. This is copied from SkewSymMatrix.
benedict-96 Dec 13, 2023
16b28ba
Slightly improved readability.
benedict-96 Dec 13, 2023
df07bfb
Added addition tests for the remaining custom arrays.
benedict-96 Dec 13, 2023
e81ff2e
Added tests for addition, scalar multiplication and matrix multiplica…
benedict-96 Dec 13, 2023
a94c57c
Changed order of how files are included. Symmetric now depends on Ske…
benedict-96 Dec 13, 2023
c6a350e
Fixed typo.
benedict-96 Dec 13, 2023
35b3db6
Renamed file to something more descriptive.
benedict-96 Dec 19, 2023
66f3279
Renamed file to something meaningful and made the test more readable.
benedict-96 Dec 19, 2023
e8ba5c1
Merge pull request #97 from JuliaGNI/put_sampling_of_arrays_into_extr…
michakraus Dec 19, 2023
257aeee
Added descriptions and a wrapper for using the custom loss function w…
benedict-96 Dec 19, 2023
9ca60ed
Added descriptions and a wrapper for using the custom loss function w…
benedict-96 Dec 19, 2023
fced8d8
Added documentation.
benedict-96 Dec 19, 2023
d95268d
Added constructor for optimizer if input arguments are flipped.
benedict-96 Dec 19, 2023
2abed87
Added a comment saying that the constructor can be called with DataLo…
benedict-96 Dec 19, 2023
0f62b8f
Added default for number of epochs.
benedict-96 Dec 19, 2023
3ab42f2
Combined matrix and tensor routines into one. Added another loss for …
benedict-96 Dec 19, 2023
5d22855
Commented out a section that is probably not needed.
benedict-96 Dec 19, 2023
86485ad
Test data loader for qp data.
benedict-96 Dec 19, 2023
cac1f18
Renamed and added tests.
benedict-96 Dec 19, 2023
4528053
Adjusted symplectic matrix.
benedict-96 Dec 19, 2023
6ed5c62
Renamed file to something more descriptive.
benedict-96 Dec 19, 2023
f4ddd3f
Renamed file to something meaningful and made the test more readable.
benedict-96 Dec 19, 2023
92ac2fe
Added descriptions and a wrapper for using the custom loss function w…
benedict-96 Dec 19, 2023
cb19f5b
Added descriptions and a wrapper for using the custom loss function w…
benedict-96 Dec 19, 2023
cb7725f
Added documentation.
benedict-96 Dec 19, 2023
90bbaa7
Added constructor for optimizer if input arguments are flipped.
benedict-96 Dec 19, 2023
137d640
Added a comment saying that the constructor can be called with DataLo…
benedict-96 Dec 19, 2023
b57d148
Added default for number of epochs.
benedict-96 Dec 19, 2023
3100b0b
Combined matrix and tensor routines into one. Added another loss for …
benedict-96 Dec 19, 2023
718174f
Commented out a section that is probably not needed.
benedict-96 Dec 19, 2023
370ee05
Test data loader for qp data.
benedict-96 Dec 19, 2023
14d6ae2
Renamed and added tests.
benedict-96 Dec 19, 2023
9edec7b
Adjusted symplectic matrix.
benedict-96 Dec 19, 2023
2acdd24
dim was missing for specifying default.
benedict-96 Dec 19, 2023
f8b8fff
dl has no field data.
benedict-96 Dec 19, 2023
8c4c73b
Fixed typos.
benedict-96 Dec 19, 2023
fc92faa
Merge branch 'increase_data_loader_test_coverage' of https://github.c…
benedict-96 Dec 19, 2023
d072594
Removed method that appeared twice for some reason.
benedict-96 Dec 19, 2023
d071839
Forgot to commit before.
benedict-96 Dec 19, 2023
2bb3f29
CompatHelper: bump compat for GPUArrays to 10, (keep existing compat)
Dec 20, 2023
8696833
Merge pull request #102 from JuliaGNI/compathelper/new_version/2023-1…
michakraus Dec 20, 2023
9b56781
Merge pull request #101 from JuliaGNI/increase_data_loader_test_coverage
michakraus Dec 20, 2023
7aff016
Added new routine for multiplying symmetric matrix from the right ont…
benedict-96 Dec 13, 2023
3321d4b
Resolved merge conflict.
benedict-96 Dec 20, 2023
65ee5c0
Resolved conflict (removed triangular matrices).
benedict-96 Dec 20, 2023
0f958d6
Slightly improved readability.
benedict-96 Dec 13, 2023
250c701
Resolved conflict.
benedict-96 Dec 20, 2023
b320aaf
Resolved conflict (accepted both changes).
benedict-96 Dec 20, 2023
5ae3067
Added tests for addition, scalar multiplication and matrix multiplica…
benedict-96 Dec 13, 2023
d4bbb6c
Resolved merge conflict.
benedict-96 Dec 20, 2023
f25e3fa
Fixed (apparent) conflict.
benedict-96 Dec 20, 2023
e0cc2d2
Fixed typo.
benedict-96 Dec 13, 2023
b7bf98b
Resolved merge conflicts.
benedict-96 Dec 20, 2023
1e659d7
Fixed comments from previous merge conflict.
benedict-96 Dec 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ ChainRulesTestUtils = "1"
Distances = "0.10"
Documenter = "0.27, 1"
ForwardDiff = "0.10"
GPUArrays = "8, 9"
GPUArrays = "8, 9, 10"
GeometricBase = "0.9"
GeometricEquations = "0.14"
GeometricIntegrators = "0.13"
Expand Down
7 changes: 2 additions & 5 deletions src/GeometricMachineLearning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,10 @@ module GeometricMachineLearning
export convert_to_dev, Device, CPUDevice

# INCLUDE ARRAYS
include("arrays/block_identity_lower.jl")
include("arrays/block_identity_upper.jl")
include("arrays/skew_symmetric.jl")
include("arrays/symmetric.jl")
include("arrays/symplectic.jl")
include("arrays/symplectic_lie_algebra.jl")
include("arrays/symplectic_lie_algebra_horizontal.jl")
include("arrays/skew_symmetric.jl")
include("arrays/abstract_lie_algebra_horizontal.jl")
include("arrays/stiefel_lie_algebra_horizontal.jl")
include("arrays/grassmann_lie_algebra_horizontal.jl")

Expand Down
6 changes: 3 additions & 3 deletions src/architectures/sympnet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ TODO:
abstract type SympNet{AT} <: Architecture end

@doc raw"""
`LASympNet` is called with **a single input argument**, the **system dimension**. Optional input arguments are:
`LASympNet` is called with **a single input argument**, the **system dimension**, or with an instance of `DataLoader`. Optional input arguments are:
- `depth::Int`: The number of linear layers that are applied. The default is 5.
- `nhidden::Int`: The number of hidden layers (i.e. layers that are **not** input or output layers). The default is 2.
- `activation`: The activation function that is applied. By default this is `tanh`.
Expand All @@ -32,7 +32,7 @@ end
@inline AbstractNeuralNetworks.dim(arch::SympNet) = arch.dim

@doc raw"""
`GSympNet` is called with **a single input argument**, the **system dimension**. Optional input arguments are:
`GSympNet` is called with **a single input argument**, the **system dimension**, or with an instance of `DataLoader`. Optional input arguments are:
- `upscaling_dimension::Int`: The *upscaling dimension* of the gradient layer. See the documentation for `GradientLayerQ` and `GradientLayerP` for further explanation. The default is `2*dim`.
- `nhidden::Int`: The number of hidden layers (i.e. layers that are **not** input or output layers). The default is 2.
- `activation`: The activation function that is applied. By default this is `tanh`.
Expand All @@ -49,7 +49,7 @@ struct GSympNet{AT, InitUpper} <: SympNet{AT} where {InitUpper}
end


function GSympNet(dl::DataLoader; upscaling_dimension=2*dim, nhidden=2, activation=tanh, init_upper=true)
function GSympNet(dl::DataLoader; upscaling_dimension=2*dl.input_dim, nhidden=2, activation=tanh, init_upper=true)
new{typeof(activation), init_upper}(dl.input_dim, upscaling_dimension, nhidden, activation)
end
end
Expand Down
4 changes: 4 additions & 0 deletions src/arrays/abstract_lie_algebra_horizontal.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@doc raw"""
`AbstractLieAlgHorMatrix` is a supertype for various horizontal components of Lie algebras. We usually call this \(\mathfrak{g}^\mathrm{hor}\).
"""
abstract type AbstractLieAlgHorMatrix{T} <: AbstractMatrix{T} end
37 changes: 0 additions & 37 deletions src/arrays/block_identity_lower.jl

This file was deleted.

37 changes: 0 additions & 37 deletions src/arrays/block_identity_upper.jl

This file was deleted.

15 changes: 1 addition & 14 deletions src/arrays/grassmann_lie_algebra_horizontal.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
"""
This implements the horizontal component of the Lie algebra (in this case just the skew-symmetric matrices).
The projection is:
S -> SE where
|I|
|0| = E.

An element of GrassmannLieAlgMatrix takes the form:
| -0 -B'|
| B 0 | where B is arbitrary.

This also implements the projection:
| 0 -B'| | 0 -B'|
| B 0 | -> | B 0 |.
This implements the horizontal component of a Lie algebra that is isomorphic to the Grassmann manifold.
"""

mutable struct GrassmannLieAlgHorMatrix{T, ST <: AbstractMatrix{T}} <: AbstractLieAlgHorMatrix{T}
B::ST
N::Int
Expand Down
2 changes: 1 addition & 1 deletion src/arrays/skew_symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ end

# the first matrix is multiplied onto A2 in order for it to not be SkewSymMatrix!
function Base.:*(A1::SkewSymMatrix{T}, A2::SkewSymMatrix{T}) where T
A1*(one(A2)*A2)
A1 * (one(A2) * A2)
end

@doc raw"""
Expand Down
41 changes: 26 additions & 15 deletions src/arrays/stiefel_lie_algebra_horizontal.jl
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
"""
This implements the horizontal component of the Lie algebra (in this case just the skew-symmetric matrices).
The projection is:
S -> SE where
|I|
|0| = E.
@doc raw"""
`StiefelLieAlgHorMatrix` is the *horizontal component of the Lie algebra of skew-symmetric matrices* (with respect to the canonical metric).
The projection here is: \(\pi:S \to SE \) where
```math
E = \begin{pmatrix} \mathbb{I}_{n} \\ \mathbb{O}_{(N-n)\times{}n} \end{pmatrix}.
```
The matrix \(E\) is implemented under `StiefelProjection` in `GeometricMachineLearning`.

An element of StiefelLieAlgMatrix takes the form:
| A -B'|
| B 0 | where A is skew-symmetric.

This also implements the projection:
| A -B'| | A -B'|
| B D | -> | B 0 |.
```math
\begin{pmatrix}
A & B^T \\ B & \mathbb{O}
\end{pmatrix},
```
where \(A\) is skew-symmetric (this is `SkewSymMatrix` in `GeometricMachineLearning`).

If the constructor is called with a big \(N\times{}N\) matrix, then the projection is performed the following way:
```math
\begin{pmatrix}
A & B_1 \\
B_2 & D
\end{pmatrix} \mapsto
\begin{pmatrix}
\mathrm{skew}(A) & -B_2^T \\
B_2 & \mathbb{O}
\end{pmatrix}.
```
The operation $\mathrm{skew}:\mathbb{R}^{n\times{}n}\to\mathcal{S}_\mahtrm{skew}(n)$ is the skew-symmetrization operation. This is equivalent to calling the constructor of `SkewSymMatrix` with an \(n\times{}n\) matrix.
"""

abstract type AbstractLieAlgHorMatrix{T} <: AbstractMatrix{T} end

mutable struct StiefelLieAlgHorMatrix{T, AT <: SkewSymMatrix{T}, ST <: AbstractMatrix{T}} <: AbstractLieAlgHorMatrix{T}
A::AT
B::ST
Expand Down
26 changes: 20 additions & 6 deletions src/arrays/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
So $S$ stores a string of vectors taken from $A$: $S = [\tilde{a}_1, \tilde{a}_2, \ldots, \tilde{a}_n]$ with $\tilde{a}_i = [[A]_{i1},[A]_{i2},\ldots,[A]_{ii}]$.

TODO:
-[x] Overload Adjoint operation for SymmetricMatrix!! (Aᵀ = A)
-[ ] implement matrix and vector products (to also work on GPU)
-[x] implement zero initialization (for optimizer)
-[ ] perform some tests (also with Zygote)
-[x] update the constructor (to work better for GPU)
-[ ] implement multiplication with a tensor
- [x] Overload Adjoint operation for SymmetricMatrix!! (Aᵀ = A)
- [ ] implement matrix and vector products (to also work on GPU)
- [x] implement zero initialization (for optimizer)
- [ ] perform some tests (also with Zygote)
- [x] update the constructor (to work better for GPU)
- [ ] implement multiplication with a tensor
"""
mutable struct SymmetricMatrix{T, AT <: AbstractVector{T}} <: AbstractMatrix{T}
S::AT
Expand Down Expand Up @@ -209,13 +209,27 @@
C
end

Base.:*(B::AbstractMatrix{T}, A::SymmetricMatrix{T}) where T = (A * B')'

function Base.:*(A::SymmetricMatrix{T}, B::SymmetricMatrix{T}) where T
A * (B * one(B))

Check warning on line 215 in src/arrays/symmetric.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symmetric.jl#L214-L215

Added lines #L214 - L215 were not covered by tests
end

function Base.:*(A::SymmetricMatrix{T}, b::AbstractVector{T}) where T
backend = KernelAbstractions.get_backend(A.S)
c = KernelAbstractions.allocate(backend, T, A.n)
LinearAlgebra.mul!(c, A, b)
c
end

function Base.one(A::SymmetricMatrix{T}) where T
backend = KernelAbstractions.get_backend(A.S)
unit_matrix = KernelAbstractions.zeros(backend, T, A.n, A.n)
write_ones! = write_ones_kernel!(backend)
write_ones!(unit_matrix, ndrange=A.n)
unit_matrix

Check warning on line 230 in src/arrays/symmetric.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symmetric.jl#L225-L230

Added lines #L225 - L230 were not covered by tests
end

# define routines for generalizing ChainRulesCore to SymmetricMatrix
ChainRulesCore.ProjectTo(A::SymmetricMatrix) = ProjectTo{SymmetricMatrix}(; symmetric=ProjectTo(A.S))
(project::ProjectTo{SymmetricMatrix})(dA::AbstractMatrix) = SymmetricMatrix(project.symmetric(map_to_S(dA)), size(dA, 2))
Expand Down
80 changes: 24 additions & 56 deletions src/arrays/symplectic.jl
Original file line number Diff line number Diff line change
@@ -1,75 +1,43 @@

@doc raw"""

`SymplecticMatrix(n)`
`SymplecticPotential(n)`

Returns a symplectic matrix of size 2n x 2n

```math
\begin{pmatrix}
0 & & & 1 & & & \\
& \ddots & & & \ddots & & \\
& & 0 & & & 1 \\
-1 & & & 0 & & & \\
& \ddots & & & \ddots & & \\
& & -1 & & 0 & \\
\mathbb{O} & \mathbb{I} \\
\mathbb{O} & -\mathbb{I} \\
\end{pmatrix}
```

`SymplecticProjection(N,n)`
Returns the symplectic projection matrix E of the Stiefel manifold, i.e. π: Sp(2N) → Sp(2n,2N), A ↦ AE

"""
#=
function SymplecticMatrix(n::Int, T::DataType=Float64)
BandedMatrix((n => ones(T,n), -n => -ones(T,n)), (2n,2n))
end

SymplecticMatrix(T::DataType, n::Int) = SymplecticMatrix(n, T)

@doc raw"""
```math
\begin{pmatrix}
I & 0 \\
0 & 0 \\
0 & I \\
0 & 0 \\
\end{pmatrix}
```
"""
=#

function SymplecticPotential(n::Int, T::DataType=Float64)
J = zeros(T, 2*n, 2*n)
J[1:n, (n+1):2*n] = one(ones(T, n, n))
J[(n+1):2*n, 1:n] = -one(ones(T, n, n))
function SymplecticPotential(backend, n2::Int, T::DataType=Float64)
@assert iseven(n2)
n = n2÷2
J = KernelAbstractions.zeros(backend, T, 2*n, 2*n)
assign_ones_for_symplectic_potential! = assign_ones_for_symplectic_potential_kernel!(backend)
assign_ones_for_symplectic_potential!(J, n, ndrange=n)

Check warning on line 20 in src/arrays/symplectic.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symplectic.jl#L15-L20

Added lines #L15 - L20 were not covered by tests
J
end

SymplecticPotential(n::Int, T::DataType=Float64) = SymplecticPotential(CPU(), n, T)
SymplecticPotential(bakend, T::DataType, n::Int) = SymplecticPotential(backend, n, T)

Check warning on line 25 in src/arrays/symplectic.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symplectic.jl#L24-L25

Added lines #L24 - L25 were not covered by tests

SymplecticPotential(T::DataType, n::Int) = SymplecticPotential(n, T)

struct SymplecticProjection{T} <: AbstractMatrix{T}
N::Int
n::Int
SymplecticProjection(N, n, T = Float64) = new{T}(N,n)
@kernel function assign_ones_for_symplectic_potential_kernel!(J::AbstractMatrix{T}, n::Int) where T
i = @index(Global)
J[map_index_for_symplectic_potential(i, n)...] = i ≤ n ? one(T) : -one(T)

Check warning on line 31 in src/arrays/symplectic.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symplectic.jl#L29-L31

Added lines #L29 - L31 were not covered by tests
end

function Base.getindex(E::SymplecticProjection,i,j)
if i ≤ E.n
if j == i
return 1.
end
return 0.
end
if j > E.n
if (j-E.n) == (i-E.N)
return 1.
end
return 0.
"""
This assigns the right index for the symplectic potential. To be used with `assign_ones_for_symplectic_potential_kernel!`.
"""
function map_index_for_symplectic_potential(i::Int, n::Int)
if i ≤ n
return (i, i+n)

Check warning on line 39 in src/arrays/symplectic.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symplectic.jl#L37-L39

Added lines #L37 - L39 were not covered by tests
else
return (i, i-n)

Check warning on line 41 in src/arrays/symplectic.jl

View check run for this annotation

Codecov / codecov/patch

src/arrays/symplectic.jl#L41

Added line #L41 was not covered by tests
end
return 0.
end


Base.parent(E::SymplecticProjection) = (E.N,E.n)
Base.size(E::SymplecticProjection) = (2*E.N,2*E.n)
end
Loading
Loading