Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
30b1dd2
added abstract types for CUR
nathanielpritchard Jul 11, 2025
006379a
added selector abstract types
nathanielpritchard Jul 14, 2025
9a00dad
adding forgotten selectors markdown
nathanielpritchard Jul 14, 2025
99b004e
added code for an LU with partial pivoting selector
nathanielpritchard Oct 6, 2025
fb81e89
fastforwarded with main
nathanielpritchard Oct 6, 2025
4505069
intialized the qr with column pivoting selection
nathanielpritchard Oct 6, 2025
43c3a22
corrected spelling in a comment
nathanielpritchard Oct 6, 2025
0c61034
added identity compressor
nathanielpritchard Oct 10, 2025
12e9711
merged with main
nathanielpritchard Oct 10, 2025
c6ad815
updated the technique structure to include cardinality
nathanielpritchard Oct 10, 2025
0a55ffb
Merge branch 'v0.2-null_compressor' into v0.2-selector
nathanielpritchard Oct 10, 2025
94ffc2f
modified compressor to allow for sketched LU
nathanielpritchard Oct 10, 2025
7c1757c
appropriately named selector directory
nathanielpritchard Oct 10, 2025
2771eba
Merge branch 'v0.2-null_compressor' into v0.2-QRCP
nathanielpritchard Oct 10, 2025
6b685cf
Merge branch 'v0.2-selector' into v0.2-QRCP
nathanielpritchard Oct 10, 2025
30b0a3a
corrected misspecified link
nathanielpritchard Oct 10, 2025
3880ef8
finished merge
nathanielpritchard Oct 10, 2025
6ae245c
updated the qrcp function to allow for sketching
nathanielpritchard Oct 10, 2025
ea75070
added sketching capabilities to qr
nathanielpritchard Oct 10, 2025
5a0b090
added qrcp test file
nathanielpritchard Oct 12, 2025
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
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ makedocs(
"Approximators" => [
"Approximators Overview" => "api/approximators.md",
"Approximator Sub-routines" => [
"ApproximatorErrors" => "api/approximator_errors.md"
"ApproximatorErrors" => "api/approximator_errors.md",
"Selectors" => "api/selectors.md"
],
],
],
Expand Down
4 changes: 4 additions & 0 deletions docs/src/api/compressors.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Gaussian

GaussianRecipe

Identity

IdentityRecipe

Sampling

SamplingRecipe
Expand Down
36 changes: 36 additions & 0 deletions docs/src/api/selectors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Selectors
```@contents
Pages = ["selectors.md"]
```

## Abstract Types
```@docs
Selector

SelectorRecipe
```

## Selector Structures
```@docs
RLinearAlgebra.LUPP

LUPPRecipe

QRCP

QRCPRecipe
```

## Exported Functions
```@docs
complete_selector

update_selector!

select_indices!
```

## Internal Functions
```@docs

```
10 changes: 10 additions & 0 deletions src/Approximators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ randomized rangefinder.
"""
abstract type RangeApproximatorRecipe <: ApproximatorRecipe end


###################################
# Docstring Components
###################################
Expand All @@ -72,6 +73,7 @@ approx_arg_list = Dict{Symbol,String}(
:A => "`A::AbstractMatrix`, a target matrix for approximation.",
:compressor_recipe => "`S::CompressorRecipe`, a fully initialized realization for a
compression method for a specific matrix or collection of matrices and vectors.",

)

approx_output_list = Dict{Symbol,String}(
Expand All @@ -82,8 +84,10 @@ approx_output_list = Dict{Symbol,String}(
approx_method_description = Dict{Symbol,String}(
:complete_approximator => "A function that generates an `ApproximatorRecipe` given
arguments.",

:update_approximator => "A function that updates the `ApproximatorRecipe` in place
given the arguments.",

:rapproximate => "A function that computes a low-rank approximation of the matrix `A`
using the information in the provided `Approximator` data structure.",
:complete_approximator_error => "A function that generates an `ApproximatorErrorRecipe`
Expand Down Expand Up @@ -161,6 +165,7 @@ function complete_approximator(approximator::Approximator, A::AbstractMatrix)
)
end


###################################
# rapproximate Interface
###################################
Expand Down Expand Up @@ -430,3 +435,8 @@ end
include("Approximators/RangeApproximators/rangefinder.jl")
include("Approximators/RangeApproximators/randsvd.jl")
include("Approximators/RangeApproximators/helpers/power_its.jl")

############################################
# Include the selector files
############################################
include("Approximators/Selectors.jl")
148 changes: 148 additions & 0 deletions src/Approximators/Selectors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
###################################
# Abstract Types
###################################
"""
Selector

An abstract type containing user controlled parameters for a technique that select indices
from a matrix.
"""
abstract type Selector end

"""
SelectorRecipe

An abstract type containing user controlled parameters and preallocated memory for a
technique that selects indices from matrix.
"""
abstract type SelectorRecipe end

select_arg_list = Dict{Symbol,String}(
:selector => "`selector::Selector`, a data structure containing the user-defined
parameters associated with a particular selection method.",
:selector_recipe => "`selector_recipe::SelectorRecipe`, a fully initialized realization
for a selector method for a particular matrix.",
:idx => "`idx::vector`, a vector where selected indices will be placed.",
:n_idx => "`n_idx::Int64`, the number of indices to be selected.",
:start_idx => "`start_idx::Int64`. the starting location in `idx` where the indices
will be placed.",
:A => "`A::AbstractMatrix`, a target matrix for approximation.",
)
select_output_list = Dict{Symbol,String}(
:selector_recipe => "A `SelectorRecipe` object.",
)
select_method_description = Dict{Symbol,String}(
:update_selector => "A function that updates the `SelectorRecipe` in place given the
arguments.",
:complete_selector => "A function that generates a `SelectorRecipe` given
arguments.",
:select_indices => "A function that selects indices from a matrix `A` using a specific
`SelectorRecipe`. It updates the vector `idx` in place with `n_idx` new indices starting
at index `start_idx`."
)
##################################
# Complete Selector Interface
##################################
"""
complete_selector(selector::Selector, A::AbstractMatrix)

$(select_method_description[:complete_selector])

# Arguments
- $(select_arg_list[:selector])
- $(select_arg_list[:A])

# Outputs
- $(select_output_list[:selector_recipe])
"""
function complete_selector(selector::Selector, A::AbstractMatrix)
return throw(
ArgumentError(
"No method `complete_selector` exists for selector of type\
$(typeof(selector)) and matrix of type $(typeof(A))."
)
)
end

##################################
# update_selector!
##################################
"""
update_selector!(selector::SelectorRecipe)

$(select_method_description[:update_selector])

# Arguments
- $(select_arg_list[:selector_recipe])

# Outputs
- $(select_output_list[:selector_recipe])
"""
function update_selector!(selector::SelectorRecipe)
return throw(
ArgumentError(
"No method `update_selector!` exists for selector of type\
$(typeof(selector))."
)
)
end

"""
update_selector!(selector::SelectorRecipe, A::AbstractMatrix)

$(select_method_description[:update_selector])

# Arguments
- $(select_arg_list[:selector_recipe])
- $(select_arg_list[:A])

# Outputs
- $(select_output_list[:selector_recipe])
"""
function update_selector!(selector::SelectorRecipe, A::AbstractMatrix)
return update_selector!(selector)
end

####################################
# select_indices!
####################################
"""
select_indices!(
selector::SelectorRecipe,
A::AbstractMatrix,
idx::AbstractVector,
n_idx::Int64,
start_idx::Int64
)

$(select_method_description[:select_indices])

# Arguments
- $(select_arg_list[:selector_recipe])
- $(select_arg_list[:A])
- $(select_arg_list[:idx])
- $(select_arg_list[:n_idx])
- $(select_arg_list[:start_idx])

# Outputs
- Returns `nothing`
"""
function select_indices!(
idx::AbstractVector,
selector::SelectorRecipe,
A::AbstractMatrix,
n_idx::Int64,
start_idx::Int64
)
return throw(
ArgumentError(
"No method `select_indices` exists for selector of type $(typeof(selector)),\
matrix of type $(typeof(A)), idx of type $(typeof(idx)), n_idx of type \
$(typeof(n_idx)), and start_idx of type $(typeof(start_idx))."
)
)
end

# Include the selector files
include("Selectors/qrcp.jl")
include("Selectors/lupp.jl")
94 changes: 94 additions & 0 deletions src/Approximators/Selectors/lupp.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""
LUPP <: Selector

A `Selector` that implements LU with partial pivoting for selecting column indices from a
matrix.

# Fields
- `compressor::Compressor`, the compression technique that will applied to the matrix,
before selecting indices.

# Constructor
LUPP(;compressor = Identity())

## Keywords
- `compressor::Compressor`, the compression technique that will applied to the matrix,
before selecting indices. Defaults the `Identity` compressor.

## Returns
- Will return a `Selector` object.
"""
mutable struct LUPP <: Selector
compressor::Compressor
end

function LUPP(;compressor = Identity())
LUPP(compressor)
end

"""
LUPPRecipe <: SelectorRecipe

A `SelectorRecipe` that contains all the necessary preallocations for selecting column
indices from a matrix using LU with partial pivoting.

# Fields
- `compressor::Compressor`, the compression technique that will applied to the matrix,
before selecting indices.
- `SA::AbstractMatrix`, a buffer matrix for storing the sketched matrix.
"""
mutable struct LUPPRecipe <: SelectorRecipe
compressor::CompressorRecipe
SA::AbstractMatrix
end

function complete_selector(ingredients::LUPP, A::AbstractMatrix)
compressor = complete_compressor(ingredients.compressor, A)
n_rows, n_cols = size(compressor)
SA = Matrix{eltype(A)}(undef, n_rows, n_cols)
return LUPPRecipe(compressor, SA)
end

function update_selector!(selector::LUPPRecipe)
update_compressor!(selector.compressor)
return nothing
end

function select_indices!(
idx::AbstractVector,
selector::LUPPRecipe,
A::AbstractMatrix,
n_idx::Int64,
start_idx::Int64
)
if n_idx > size(A, 2)
throw(
DimensionMismatch(
"`n_idx` cannot be larger than the number of columns in `A`."
)
)
end

if start_idx + n_idx - 1 > size(idx, 1)
throw(
DimensionMismatch(
"`start_idx` + `n_idx` - 1 cannot be larger than the lenght of `idx`."
)
)
end

if n_idx > selector.compressor.n_rows
throw(
DimensionMismatch(
"Must select fewer indices then the `compression_dim`."
)
)

end

mul!(selector.SA, selector.compressor, A)
# because LUPP selects rows and selectors select columns we need to pivot on A'
p = lu!(selector.SA').p
idx[start_idx:start_idx + n_idx - 1] = p[1:n_idx]
return nothing
end
Loading
Loading