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

Add QR and RRQR interface methods #2211

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open

Add QR and RRQR interface methods #2211

wants to merge 23 commits into from

Conversation

pmli
Copy link
Member

@pmli pmli commented Oct 24, 2023

  • adds pymor.algorithms.qr module with qr and rrqr methods
  • replaces most usage of gram_schmidt in pymor/src (the exception is VectorArrayOperator.apply_inverse, because it uses reiterate=False, and it should anyway probably use an SVD method)
  • parameter copy in qr and rrqr is commonly used, parameter check is only used in reductors.basic and algorithms.svd_va

@pmli pmli added the pr:new-feature Introduces a new feature label Oct 24, 2023
@pmli pmli added this to the 2023.2 milestone Oct 24, 2023
@pmli pmli requested a review from sdrave October 24, 2023 21:30
Copy link
Member

@sdrave sdrave left a 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 in gram_schmidt could be deprecated.

src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Show resolved Hide resolved
src/pymor/algorithms/qr.py Show resolved Hide resolved
@pmli pmli self-assigned this Nov 2, 2023
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
Raises
------
RuntimeError
If the vectors in `V` are detected to be linearly dependent.
Copy link
Member

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?

Copy link
Member Author

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).

Copy link
Member

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.)

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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/qr.py Show resolved Hide resolved
src/pymor/algorithms/qr.py Show resolved Hide resolved
src/pymor/algorithms/qr.py Outdated Show resolved Hide resolved
src/pymor/algorithms/qr.py Show resolved Hide resolved
src/pymor/algorithms/qr.py Show resolved Hide resolved
src/pymor/algorithms/qr.py Show resolved Hide resolved
@@ -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)
Copy link
Member

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?

Suggested change
rrqr(image, offset=gram_schmidt_offset, product=product, copy=False)
rrqr(image, offset=len(image), product=product, copy=False)

Copy link
Member Author

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.

Copy link
Member

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_schmidtsince now it could be also a different algorithm. Maybe just offset would do?

Copy link
Member Author

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)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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')

Copy link
Member

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

Copy link
Member Author

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?

Copy link
Member

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.

Copy link
Member

@sdrave sdrave left a 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 ..

@pmli pmli requested a review from sdrave November 20, 2023 14:00
@pmli pmli removed this from the 2023.2 milestone Nov 29, 2023
@sdrave sdrave added this to the 2024.1 milestone Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr:new-feature Introduces a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants