cite your reference
Thank you kindly for providing that .PNG algorithmic background
as review context, it is very helpful.
Besides the overall method, it explains why certain variable names
were chosen.
The PCG function absolutely has to mention that original author,
in the docstring.
And it needs to spell out that we compute a
preconditioned conjugate gradient.
Which brings us to the next point...
condition number
Why are we conditioning at all?
What is the domain that we are drawing our
(possibly nearly) collinear matrices from,
and how are we using them?
I would find a preconditioning argument
much more convincing if we compute
linalg.cond()
both before and afterward,
and verify the condition number was indeed reduced.
You didn't write a """docstring""",
therefore the docstring isn't commenting at
all on error sources nor on the consequences
of producing "small" or "large" errors.
As a user of this library, I would have
no idea if my use case matches what this
library addresses.
And no idea if the library author had
tested regions of the input- and output- space
that I care about.
Which brings us to the next issue...
test suite
You declined to provide a main() function
that trivially exercises the target code,
and we definitely don't see unit tests
which exercise multiple regions of the input space.
There is an opportunity to add small deltas
to input matrices, and verify that your proposed
method out-performs a baseline naïve method.
lint
Pep-8
asks that you spell it def pcg(..., lowercase.
(And then there's the usual "math vs. snake_case" tension
for a bunch of variables which we could more easily let slide,
since local variables are not part of the Public API.)
optional type hinting
You know, given the empty docstring and the complex signature,
we have arrived at the point where type annotation really
isn't optional any more.
Absent a citation in the code, a caller would have
no idea what shape input parameters should be passed in,
and what to expect as output.
(One might reasonably expect the output matrix to be accompanied
by a condition number or similar diagnostic, for example.)
I imagine that L, U were lower, upper.
But I'm free to pass in anything I want;
they are completely ignored and their meaning is obscure.
It is hard to tell if this codebase achieves its design goals,
partly because a bunch of goals were left implicit rather
than writing them down.
You don't know if it properly works as intended,
and neither do I.
There are several techniques you could apply
to improve our confidence in how it functions.
I would not be willing to delegate or accept maintenance tasks on this code.