Suppose I have a matrix
import numpy as np
from functools import reduce
np.random.seed(123)
X = np.random.normal(size=(5, 2))
and I want to compute X^t X without using numpy functions and using map
, reduce
and lambda
functions. Since we can write X^t X as a sum of outer products, my goal would be:
def outer_product(x):
"""Computes outer product of a vector with itself"""
pass
map(outer_product, X)
However I can't seem to find an efficient way of writing all of these with map reduce.
def outer(x):
xxx = np.repeat(x, len(x))
yyy = np.array(list(x) * len(x))
return np.reshape(list(map(lambda x, y: x*y, xxx, yyy)), (len(x), len(x)))
so that
outer(X[0, ])
And then I've written the covariance matrix as follows
def cov(X):
return np.array(reduce(lambda x, y: x + y, list(map(outer, X)))) / np.size(X, 0)
To answer your question, outer product can be defined as nested map such as
outer = lambda V: np.array(list(map(lambda x: list(map(lambda y: x*y, V)), V)))
X = np.random.normal(size=(5, 2))
>>> outer(X[1])
array([[ 0.08007683, -0.42624902], [-0.42624902, 2.26892377]])
Actually, it is simpler to use list comprehension
outer = lambda V: np.array([[x*x1 for a in V] for x1 in V])
will give you same result. Then you can map to your matrix like
>>> list(map(outer, X))
[array([[ 1.17859381, -1.08274874],
[-1.08274874, 0.99469794]]), array([[ 0.08007683, -0.42624902],
[-0.42624902, 2.26892377]]), array([[ 0.33477825, -0.9555216 ],
[-0.9555216 , 2.72724264]]), array([[5.88877215, 1.04083337],
[1.04083337, 0.18396604]]), array([[ 1.60259461, -1.0972381 ],
[-1.0972381 , 0.75123892]])]
Your reduce part is quite nice and concise by the way. I don't think that part requires any further refactoring.