On Sat, Aug 15, 2020, 11:20 AM Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Ricky Teachey writes:

 > Well keep in mind that generally an engineer submits calculations-- not
 > code-- to be reviewed. This leaves me with a few options:


 > Hiding the portion of code that looks too much like programming (and not
 > enough like equations) takes some time, but if I do not do this it will
 > inevitably lead to a 40 minute phone call [...].

Ah, I misinterpreted your statement that engineers don't much use
linear algebra.  You *do* use it for *presentation*, but it's not very
useful in the programming that gets your results.

Yes I'd say this is generally true most of the time. There are certainly instances where I've needed to used matrices to solve a system of equations in an automated way. But most of time it's simply not needed, and if I do need to do it, I can always use Mathcad. 

General comment: a lot of my "I wish" thoughts regarding python syntax have to do with the idea that code could look more like handwritten mathematical calculations. But I recognize that a balance has to be maintained. 

> Furthermore, the same NYDoT reviewer might come back and say:
 > *"Rejected: calculation does not take into account change in friction angle
 > with depth."*
 > The official would be saying that friction (μ_s) is not a scalar, it should
 > be another array variable, because the soils apply different friction along
 > the shaft depth.

I don't think Steven's proposed matrix class can substitute for numpy
in general.  It will work for your case because '*' can be both scalar
multiplication and matrix multiplication.  That is, the scalar μ_s
(float, I presume?) doesn't know how to self.__mul__(q_s), but
q_s.__rmul__(μ_s) works fine.  Then tmp.__mul__(C_shaft) (C_shaft a
scalar or a vector of the same length) works.  But if you have *two*
variables, and the reviewer claims they have different (scalar)
coefficients, you're going to need numpy-style broadcasting.

I actually started trying to write a proof of concept for this last night. I'm sure it will be far far less usable and correct then Steven's but if I get it working I'll share it just for comparison of ideas.  

 > >>>  γ_per_ft = matrix( [120, 122, 118, 117] )
 > >>> print(f"{γ_per_ft=:.0f} pcf")
 > (120, 122, 118, 117) pcf
 > The idea here is that python knows the datatype of  γ_per_ft is float, so
 > it can format all the members of the array *one at a time*.

I think all you need to do is provide an appropriate __format__ method
on matrix objects.  That method will have access to the format spec
(ie, everything after the colon), and if there isn't a parser you can
just import, I'm sure there are plenty you can copy.  At least for
this case you can just apply it to the individual elements.

It's not obvious to me that elementwise is the "right" way to
implement matrix.__format__ (there may be "matrix-level" formatting
that takes precedence, for example how to treat rows wider than the
page width), but it's quite plausible.  Of course you can also derive
a simple subclass with elementwise __format__.

I'm going to try to solve this with my toy implementation, too. If it get it working I'll be sure to pass it along for comment.