# list math for version 1.5.2 without Numeric

Andrew Dalke dalke at dalkescientific.com
Wed Nov 28 18:44:30 CET 2001

```J.Jacob wrote:
>but i am not at all used to optimization wizardry so i have no idea if
>i can find a good solution.

You have

for j in range(self.nh):
sum = 0.0
for i in range(self.ni):
sum = sum + self.ai[i] * self.wi[i][j]

This can not be written easly in functional form because the indicies
of wi are in the wrong order.  If you instead had the transpose

for j in range(self.nh):
sum = 0.0
for i in range(self.ni):
sum = sum + self.ai[i] * self.wi[j][i]
#^^^^^^ difference here

then you could write it as

for j in range(self.nh):
sum = reduce(operator.add, map(operator.mul, self.ai, self.wi[j])

For what you have, a faster implementation is

ni_range = range(self.ni)  # compute the list only once
ai = self.ai               # turn attribute lookups into (faster)
wi = self.wi               #   local lookups
for j in range(self.nh):
sum = 0.0
for i in ni_range
sum = sum + ai[i] * wi[i][j]

or even (assuming self.ni == len(self.ai))

# precompute ai[i] and wi[i] as a list of 2-ples
ai_wi_pairs = zip(self.ai, self.wi)
for j in range(self.nh):
sum = 0.0
for ai_val, wi_val in ai_wi_pairs:
sum = sum + ai_val * wi_val[j]

Note: no testing, no performance comparsions -- just suggestions.

Andrew
dalke at dalkescientific.com

```