[Python-ideas] Reduce/fold and scan with generator expressions and comprehensions
Danilo J. S. Bellini
danilo.bellini at gmail.com
Sun Nov 6 17:01:50 EST 2016
2016-11-06 18:00 GMT-02:00 Stephen J. Turnbull <
turnbull.stephen.fw at u.tsukuba.ac.jp>:
> Danilo J. S. Bellini writes:
>
> > About the effort, do you really find the examples below with the new
> > proposed syntax difficult to understand?
>
> No. I just don't see how they would become tools I would use. My main
> interest here was in your claim to have economic applications, but the
> examples you give don't seem to offer big wins for the kind of
> calculations I, my students, or my colleagues do. Perhaps you will
> have better luck interesting/persuading others.
>
If you want something simple, the itertools.accumulate examples from
docs.python.org include a simple "loan amortization" example:
>>> # Amortize a 5% loan of 1000 with 4 annual payments of 90
>>> cashflows = [1000, -90, -90, -90, -90]
>>> list(accumulate(cashflows, lambda bal, pmt: bal*1.05 + pmt))
[1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001]
>>> # With the proposed syntax
>>> payments = [90, 90, 90, 90]
>>> [bal * 1.05 - pmt for pmt in payments from bal = 1000]
[1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001]
>From the Wilson J. Rugh "Linear Systems Theory" book, chapter 20 "Discrete
Time State Equations", p. 384-385 (the very first example on the topic):
"""
A simple, classical model in economics for national income y(k) in year k
describes y(k) in terms of consumer expenditure c(k), private investment
i(k), and government expenditure g(k) according to:
y(k) = c(k) + i(k) + g(k)
These quantities are interrelated by the following assumptions. First,
consumer expenditure in year k+1 is proportional to the national income in
year k,
c(k+1) = α·y(k)
where the constant α is called, impressively enough, the marginal
propensity to consume. Second, the private investment in year k+1 is
proportional to the increase in consumer expenditure from year k to year
k+1,
i(k+1) = β·[c(k+1) - c(k)]
where the constant β is a growth coefficient. Typically 0 < α < 1 and β > 0.
>From these assumptions we can write the two scalar difference equations
c(k+1) = α·c(k) + α·i(k) + α·g(k)
i(k+1) = (β·α-β)·c(k) + β·α·i(k) + β·α·g(k)
Defining state variables as x₁(k) = c(k) and x₂(k) = i(k), the output as
y(k), and the input as g(k), we obtain the linear state equation
# ⎡ α α ⎤ ⎡ α ⎤
# x(k+1) = ⎢ ⎥·x(k) + ⎢ ⎥·g(k)
# ⎣β·(α-1) β·α⎦ ⎣β·α⎦
#
# y(k) = [1 1]·x(k) + g(k)
Numbering the years by k = 0, 1, ..., the initial state is provided by c(0)
and i(0).
"""
You can use my "ltiss" or "ltvss" (if alpha/beta are time varying)
functions from the PyScanPrev state-space example to simulate that, or some
dedicated function. The linear time varying version with the proposed
syntax would be (assuming alpha, beta and g are sequences like
lists/tuples):
>>> from numpy import mat
>>> def first_digital_linear_system_example_in_book(alpha, beta, c0, i0, g):
... A = (mat([[a, a ],
... [b*(a-1), b*a]]) for a, b in zip(alpha, beta))
... B = (mat([[a ],
... [b*a]]) for a, b in zip(alpha, beta))
... x0 = mat([[c0],
... [i0]])
... x = (Ak*xk + Bk*gk for Ak, Bk, gk in zip(A, B, g) from xk = x0)
... return [xk.sum() + gk for xk, gk in zip(x, g)]
If A and B were constants, it's simpler, as the scan line would be:
x = (A*xk + B*gk for gk in g from xk = x0)
--
Danilo J. S. Bellini
---------------
"*It is not our business to set up prohibitions, but to arrive at
conventions.*" (R. Carnap)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20161106/3584de2a/attachment.html>
More information about the Python-ideas
mailing list