This PR implements right-sketching with dense and sparse operators. The implementations pass reasonably thorough tests. Documentation is included for right-sketching in a way that matches left-sketching.
Secondary changes
This PR also simplifies a private helper function that's used with sparse sketching. The helper function's behavior was very complicated because it tried to avoid allocating memory. I've decided that for the sake of readability and simplicity, we should just always allocate that memory. The effect of this change is that the new LSKGES and RSKGES have about double the workspace requirement of the old LSKGES.
To bring this point home, I'll note that this means our sparse and dense sketching operators have different memory management semantics. With dense sketching, it's possible to define things so that [L/R]GESK3 does not allocate any dynamically sized arrays. But as of this PR, it's no longer possible to do that with sparse sketching. My belief (of which I'm fairly confident) is that this inefficiency will not have an observable impact on performance in downstream applications.
Remarks
Writing tests for this functionality was a bit onerous. I think we'd benefit from figuring out how to abstract away certain differences in testing with dense vs sparse operators. It might also be helpful to have each file test one method instead of one class.
Main changes
This PR implements right-sketching with dense and sparse operators. The implementations pass reasonably thorough tests. Documentation is included for right-sketching in a way that matches left-sketching.
Secondary changes
This PR also simplifies a private helper function that's used with sparse sketching. The helper function's behavior was very complicated because it tried to avoid allocating memory. I've decided that for the sake of readability and simplicity, we should just always allocate that memory. The effect of this change is that the new LSKGES and RSKGES have about double the workspace requirement of the old LSKGES.
To bring this point home, I'll note that this means our sparse and dense sketching operators have different memory management semantics. With dense sketching, it's possible to define things so that [L/R]GESK3 does not allocate any dynamically sized arrays. But as of this PR, it's no longer possible to do that with sparse sketching. My belief (of which I'm fairly confident) is that this inefficiency will not have an observable impact on performance in downstream applications.
Remarks
Writing tests for this functionality was a bit onerous. I think we'd benefit from figuring out how to abstract away certain differences in testing with dense vs sparse operators. It might also be helpful to have each file test one method instead of one class.