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
Add QR and RRQR interface methods #2211
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make a lot of sense to me. If we can agree on the interface (see my comments), we can merge this before the release IMHO.
- tests are still missing ..
- the
check
args ingram_schmidt
could be deprecated.
Raises | ||
------ | ||
RuntimeError | ||
If the vectors in `V` are detected to be linearly dependent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implies that an error is always raised. I don't think that will be the case in general?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean exactly. I would say that "detected" does a lot of heavy lifting here (V
with linearly dependent vectors may not be detected due to numerical roundoff).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understood @drittelhacker correctly, a 'good' QR method should not raise an error if there a linearly dependent vectors, but replace the dependent vector by, e.g., a random vector. So even if linearly dependence is detected, it is not necessarily expected behavior that an error is raised. We might even disallow this. (In gram_schmidt
we could replace the dependent vector by a random vector if a flag is set or so.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @sdrave misunderstood some comment I made. I do not think I suggested random basis extensions, but may have talked about random pivoting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was I who made a comment that a thin QR can be computed using gram_schmidt
by adding random vectors. But, after thinking about it, the implementation would not be that simple (I think the simplest way would be to first run gram_schmidt
, then replace the vectors flagged for removal with random vectors and insert zero rows into the R matrix, and finally orthonormalize the added random vectors w.r.t. the other vectors; almost doubling the code in gram_schmidt
). Therefore, my suggestion is to assume in qr
that the vectors are linearly independent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @sdrave misunderstood some comment I made. I do not think I suggested random basis extensions, but may have talked about random pivoting.
But do you expect qr(A), where A is rank deficient to fail or not, @drittelhacker?
Therefore, my suggestion is to assume in qr that the vectors are linearly independent.
I think we should first decide on the behavior we'd expect. I'm pretty sure we can come up with an acceptable solution for gram_schmidt
if needed.
src/pymor/algorithms/image.py
Outdated
@@ -212,7 +212,7 @@ def estimate_image_hierarchical(operators=(), vectors=(), domain=None, extends=N | |||
image.append(new_image, remove_from_other=True) | |||
if orthonormalize: | |||
with logger.block('Orthonormalizing ...'): | |||
gram_schmidt(image, offset=gram_schmidt_offset, product=product, copy=False) | |||
rrqr(image, offset=gram_schmidt_offset, product=product, copy=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this and delete line 211?
rrqr(image, offset=gram_schmidt_offset, product=product, copy=False) | |
rrqr(image, offset=len(image), product=product, copy=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is appended to image
in line 212, so maybe it should be as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, I just thought it would be good to remove the specific reference to gram_schmidt
since now it could be also a different algorithm. Maybe just offset
would do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, yes, that's a good point. I changed it now.
@@ -476,14 +476,14 @@ def extend_basis(U, basis, product=None, method='gram_schmidt', pod_modes=1, pod | |||
remove_from_other=(not copy_U)) | |||
elif method == 'gram_schmidt': | |||
basis.append(U, remove_from_other=(not copy_U)) | |||
gram_schmidt(basis, offset=basis_length, product=product, copy=False, check=False) | |||
rrqr(basis, offset=basis_length, product=product, copy=False, check=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rrqr(basis, offset=basis_length, product=product, copy=False, check=False) | |
rrqr(basis, offset=basis_length, product=product, copy=False, check=False, method='gram_schmidt') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either this or rephrase line 477
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's an interesting question. Maybe extend_basis
should have method in ('trivial', 'rrqr', 'pod')
. What do you think, @sdrave?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I guess we should not break the existing interface. So 'gram_schmit'
should remain a possible method. But I would be ok with deprecating it and adding 'rrqr'
as as method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comments to the ongoing discussions. I'd say we are almost good to go ..
pymor.algorithms.qr
module withqr
andrrqr
methodsgram_schmidt
inpymor/src
(the exception isVectorArrayOperator.apply_inverse
, because it usesreiterate=False
, and it should anyway probably use an SVD method)copy
inqr
andrrqr
is commonly used, parametercheck
is only used inreductors.basic
andalgorithms.svd_va