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

Redesign to support slicing #10

Merged
merged 9 commits into from
Jan 3, 2025
Merged

Redesign to support slicing #10

merged 9 commits into from
Jan 3, 2025

Conversation

mtfishman
Copy link
Member

@mtfishman mtfishman commented Dec 31, 2024

Here is a brief demonstration of some of the newly supported functionality:

julia> using NamedDimsArrays: namedoneto

julia> i, j, k = namedoneto.(4, ("i", "j", "k"))
(named(Base.OneTo(4), "i"), named(Base.OneTo(4), "j"), named(Base.OneTo(4), "k"))

julia> a = randn(i, j)
named(4, named(Base.OneTo(4), "i"))×named(4, named(Base.OneTo(4), "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}}} with indices named(Base.OneTo(4), named(Base.OneTo(4), "i"))×named(Base.OneTo(4), named(Base.OneTo(4), "j"))
4×4 Matrix{Float64}:
  0.34339     0.31337    1.26852    -1.40212
  0.795976   -0.50429   -0.0727511  -0.916328
 -2.11173     0.305251  -1.28703    -0.0885537
 -0.0745913   0.145892   0.0768396   0.949534

julia> b = randn(j, k)
named(4, named(Base.OneTo(4), "j"))×named(4, named(Base.OneTo(4), "k")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}}} with indices named(Base.OneTo(4), named(Base.OneTo(4), "j"))×named(Base.OneTo(4), named(Base.OneTo(4), "k"))
4×4 Matrix{Float64}:
 -0.626989   0.601241   0.267535   0.445796
 -1.06342   -0.300968   0.614928   1.17934
 -0.395963  -0.221125   0.462799   0.309347
  0.960161  -0.608346  -1.02573   -0.874405

julia> a[i[2:3], j[2:3]] # Get a slice (copy)
named(2, named(2:3, "i"))×named(2, named(2:3, "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, UnitRange{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, UnitRange{Int64}, String}}} with indices named(Base.OneTo(2), named(2:3, "i"))×named(Base.OneTo(2), named(2:3, "j"))
2×2 Matrix{Float64}:
 -0.50429   -0.0727511
  0.305251  -1.28703

julia> @view a[i[2:3], j[2:3]] # Get a slice (view)
named(2, named(2:3, "i"))×named(2, named(2:3, "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, SubArray{Float64, 2, Matrix{Float64}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, UnitRange{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, UnitRange{Int64}, String}}} with indices named(Base.OneTo(2), named(2:3, "i"))×named(Base.OneTo(2), named(2:3, "j"))
2×2 view(::Matrix{Float64}, 2:3, 2:3) with eltype Float64:
 -0.50429   -0.0727511
  0.305251  -1.28703

julia> a[i[2:3], j[2:3]] = fill(1, (2, 2)) # Set a slice
2×2 Matrix{Int64}:
 1  1
 1  1

julia> a
named(4, named(Base.OneTo(4), "i"))×named(4, named(Base.OneTo(4), "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}}} with indices named(Base.OneTo(4), named(Base.OneTo(4), "i"))×named(Base.OneTo(4), named(Base.OneTo(4), "j"))
4×4 Matrix{Float64}:
  0.34339    0.31337   1.26852    -1.40212
  0.795976   1.0       1.0        -0.916328
 -2.11173    1.0       1.0        -0.0885537
 -0.0745913  0.145892  0.0768396   0.949534

julia> a[i[[2, 4]], j[[2, 4]]] # Get a non-contiguous slice
named(2, named([2, 4], "i"))×named(2, named([2, 4], "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedArray{Int64, 1, Vector{Int64}, String}, NamedDimsArrays.NamedArray{Int64, 1, Vector{Int64}, String}}} with indices named(Base.OneTo(2), named([2, 4], "i"))×named(Base.OneTo(2), named([2, 4], "j"))
2×2 Matrix{Float64}:
 1.0       -0.916328
 0.145892   0.949534

julia> a[i[2:3], j[2:3]] = a[i[2:3], j[2:3]] + fill(2, (i[2:3], j[2:3])) # Add over a slice
named(2, named(2:3, "i"))×named(2, named(2:3, "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, UnitRange{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, UnitRange{Int64}, String}}} with indices named(Base.OneTo(2), named(2:3, "i"))×named(Base.OneTo(2), named(2:3, "j"))
2×2 Matrix{Float64}:
 3.0  3.0
 3.0  3.0

julia> a
named(4, named(Base.OneTo(4), "i"))×named(4, named(Base.OneTo(4), "j")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}}} with indices named(Base.OneTo(4), named(Base.OneTo(4), "i"))×named(Base.OneTo(4), named(Base.OneTo(4), "j"))
4×4 Matrix{Float64}:
  0.34339    0.31337   1.26852    -1.40212
  0.795976   3.0       3.0        -0.916328
 -2.11173    3.0       3.0        -0.0885537
 -0.0745913  0.145892  0.0768396   0.949534

julia> a[i, j[[2, 4]]] * b[j[[2, 4]], k] # Contract over a sliced dimension (slices must match)
named(4, named(Base.OneTo(4), "i"))×named(4, named(Base.OneTo(4), "k")) NamedDimsArrays.NamedDimsArray{Float64, 2, Matrix{Float64}, Tuple{NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}, NamedDimsArrays.NamedUnitRange{Int64, Base.OneTo{Int64}, String}}} with indices named(Base.OneTo(4), named(Base.OneTo(4), "i"))×named(Base.OneTo(4), named(Base.OneTo(4), "k"))
4×4 Matrix{Float64}:
 -1.67951    0.758661   1.6309     1.59559
 -4.07009   -0.34546    2.78469    4.33926
 -3.27529   -0.849033   1.93562    3.61545
  0.756561  -0.621553  -0.884253  -0.658221

The new design principle in this PR idea is that the NamedDimsArray stores an unnamed array that it is wrapping, dimension names, and slice indices those dimensions run over. Operations like addition and contraction check that the dimension names and slice indices match (up to permutations).

Note that you can also use the Pair syntax:

julia> a[i[2:3], j[2:3]] == a[i => 2:3, j => 2:3]

like you can with scalar indexing.

Copy link

codecov bot commented Dec 31, 2024

Codecov Report

Attention: Patch coverage is 36.46724% with 223 lines in your changes missing coverage. Please review.

Project coverage is 33.56%. Comparing base (a8caa48) to head (bef1cc4).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/abstractnameddimsarray.jl 41.20% 147 Missing ⚠️
src/abstractnamedarray.jl 27.27% 24 Missing ⚠️
src/tensoralgebra.jl 8.69% 21 Missing ⚠️
...aysBlockArraysExt/NamedDimsArraysBlockArraysExt.jl 0.00% 12 Missing ⚠️
src/abstractnamedunitrange.jl 43.75% 9 Missing ⚠️
src/abstractnamedinteger.jl 0.00% 5 Missing ⚠️
src/nameddimsarray.jl 50.00% 4 Missing ⚠️
src/adapt.jl 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main      #10       +/-   ##
===========================================
+ Coverage   14.28%   33.56%   +19.28%     
===========================================
  Files          11       14        +3     
  Lines         343      566      +223     
===========================================
+ Hits           49      190      +141     
- Misses        294      376       +82     
Flag Coverage Δ
docs 33.45% <36.46%> (+20.00%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@mtfishman mtfishman merged commit b21c44e into main Jan 3, 2025
12 checks passed
@mtfishman mtfishman deleted the slicing branch January 3, 2025 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant