Skip to content

Support generic arrays #706

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

Closed

Conversation

amontoison
Copy link
Member

@amontoison amontoison commented Feb 9, 2023

close #605

using Krylov
using BlockArrays
K = rand(10,10)
B = rand(2, 10)

b = BlockVector(rand(Float64,12), [10,2])
2-blocked 12-element BlockVector{Float64}:
 0.8437110010150571  
 0.4530016441000567  
 0.686194576648592   
 0.34254162007097566 
 0.09544196921306347 
 0.5010761791056787  
 0.11907189994954914 
 0.17470076682895075 
 0.9550777571644686  
 0.4680632206046831  
 ────────────────────
 0.012863148806336877
 0.8840547265290272  

A = BlockArray(rand(Float64,12,12), [10,2], [10,2])
2×2-blocked 12×12 BlockMatrix{Float64}:
 0.116554   0.0703249  0.875842  0.506043   0.373476  0.23967    0.601902   0.860072   0.964966  0.436033    │  0.713543  0.470241
 0.799259   0.37769    0.346566  0.259132   0.635035  0.0446249  0.964017   0.92735    0.814636  0.669492    │  0.298945  0.921794
 0.816827   0.134661   0.127786  0.971469   0.840193  0.49803    0.892349   0.360627   0.160712  0.00137863  │  0.913815  0.846428
 0.20443    0.948703   0.137055  0.609844   0.164636  0.724305   0.90073    0.875758   0.862051  0.755453    │  0.145395  0.078032
 0.321294   0.687613   0.237468  0.0524443  0.833145  0.693929   0.237879   0.184222   0.625539  0.709003    │  0.515103  0.907079
 0.135291   0.879867   0.879918  0.279797   0.561364  0.963455   0.0180151  0.177779   0.994638  0.848967    │  0.21419   0.377067
 0.420909   0.864644   0.246007  0.709511   0.239352  0.279221   0.789019   0.526006   0.956405  0.581049    │  0.1384    0.642351
 0.709593   0.22967    0.274482  0.0517252  0.824723  0.934985   0.229917   0.514245   0.219793  0.583001    │  0.39413   0.196227
 0.350237   0.688092   0.994518  0.896093   0.103099  0.530616   0.420392   0.262814   0.622369  0.268439    │  0.169126  0.198431
 0.956745   0.696715   0.838499  0.576819   0.719354  0.250461   0.416511   0.963868   0.883324  0.630397    │  0.954737  0.9058  
 ────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────
 0.438206   0.566904   0.495495  0.183546   0.625943  0.256114   0.116151   0.725794   0.93137   0.564458    │  0.233888  0.410463
 0.0936359  0.838417   0.210066  0.848525   0.834449  0.314861   0.849024   0.0837541  0.379385  0.96699     │  0.788724  0.133835

A[Block(1,1)] = K;
A[Block(1,2)] = B';
A[Block(2,1)] = B;

x, stats = Krylov.gmres(A, b)
([-1.6804307117446322, 1.2278956836087573, 0.7522500694970368, -1.1813882696427558, -1.7308386536458193, 1.3297218781185194, 0.7128256864623073, 0.43277609013448326, 1.819601362734177, 1.6564852399189884, -1.897804683660123, -0.6132195202643419], SimpleStats
 niter: 12
 solved: true
 inconsistent: false
 residuals: []
 Aresiduals: []
 κ₂(A): []
 status: solution good enough given atol and rtol
)

x
2-blocked 12-element BlockVector{Float64}:
 -1.6804307117446322 
  1.2278956836087573 
  0.7522500694970368 
 -1.1813882696427558 
 -1.7308386536458193 
  1.3297218781185194 
  0.7128256864623073 
  0.43277609013448326
  1.819601362734177  
  1.6564852399189884 
 ────────────────────
 -1.897804683660123  
 -0.6132195202643419 

norm(b - A * x)
2.8592284672503768e-15

@tmigot
Copy link
Member

tmigot commented Feb 13, 2023

Because 0 is an integer, similar(S, 0) can't be used for some storage types that are not a subtype of a DenseVector. I must allocate all optional vectors required for warm-start, regularization or preconditioners in the Krylov workspaces.
Do you have a better solution?

Thanks for the details. Isn't that strange the empty vector is not defined even for sparse arrays ? In the worst-case could you do similar(S, 1) instead to avoid depending on the size?

Copy link
Member

@tmigot tmigot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments, and then looks good to me, thanks!

@amontoison
Copy link
Member Author

amontoison commented Feb 13, 2023

Because 0 is an integer, similar(S, 0) can't be used for some storage types that are not a subtype of a DenseVector. I must allocate all optional vectors required for warm-start, regularization or preconditioners in the Krylov workspaces. Do you have a better solution?

Thanks for the details. Isn't that strange the empty vector is not defined even for sparse arrays ? In the worst-case could you do similar(S, 1) instead to avoid depending on the size?

I don't understand your comment Tangi. 1 is also an integer like 0. The problem is not the value 0, I just want to create a vector that satisfy ::S and take the minimum amount of memory. Some vectors require the constructor with the axes to be initialized.

For the sparse arrays, I will add a check to insure that S is never a sparse arrays. It's for that reason that I added S <: DenseVector everywhere in the past.

@amontoison amontoison force-pushed the support_generic_arrays branch from a346c40 to aff18f8 Compare February 13, 2023 23:16
@tmigot
Copy link
Member

tmigot commented Feb 14, 2023

don't understand your comment Tangi. 1 is also an integer like 0. The problem is not the value 0, I just want to create a vector that satisfy ::S and take the minimum amount of memory. Some vectors require the constructor with the axes to be initialized.

Ok, I didn't understand the problem at first. Do you have an example that would not work?

@amontoison
Copy link
Member Author

don't understand your comment Tangi. 1 is also an integer like 0. The problem is not the value 0, I just want to create a vector that satisfy ::S and take the minimum amount of memory. Some vectors require the constructor with the axes to be initialized.

Ok, I didn't understand the problem at first. Do you have an example that would not work?

Yes, I do.

using BlockArrays, Krylov

T = Float64
n = 10
x = BlockVector(rand(T,n), [n-2,2])
S = Krylov.ktypeof(x)
similar(S, 0)

@tmigot
Copy link
Member

tmigot commented Feb 24, 2023

don't understand your comment Tangi. 1 is also an integer like 0. The problem is not the value 0, I just want to create a vector that satisfy ::S and take the minimum amount of memory. Some vectors require the constructor with the axes to be initialized.

Ok, I didn't understand the problem at first. Do you have an example that would not work?

Yes, I do.

using BlockArrays, Krylov

T = Float64
n = 10
x = BlockVector(rand(T,n), [n-2,2])
S = Krylov.ktypeof(x)
similar(S, 0)

Well... that won't really help but you could create an issue on this package and on the packages where the empty vector is not defined. To me, it looks like a very natural property for any vector type,

@amontoison amontoison closed this Oct 17, 2024
@amontoison amontoison deleted the support_generic_arrays branch October 17, 2024 21:45
@gdalle
Copy link

gdalle commented Jun 15, 2025

@amontoison sorry to revive old threads, can you explain why this was closed?

@amontoison
Copy link
Member Author

amontoison commented Jun 15, 2025

@gdalle I added a KrylovConstructor that can be passed to any KrylovWorkspace with a recent release.

It should handle many fancy array types.

Documentation: https://jso.dev/Krylov.jl/dev/inplace/#Krylov.KrylovConstructor

PS: Corner cases are LN / LS problems with array types that hardcode the length of the vector in the type.

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.

Compatibility with BlockArrays
6 participants