0

I want to plot a function of a numpy matrix

f = lambda X: X.T @ X

but I'm not sure how to proceed. I'm familiar with the method for multivariable functions, and the equivalent function with multivariable functions (along with plotting) would be

g = lambda x, y: x**2 + y**2
X, Y = np.meshgrid(
    np.linspace(start = -10, stop = 10, num = 101),
    np.linspace(start = -10, stop = 10, num = 101))
plt.plot_surface(X,Y,g(X,Y))

so f(np.matrix((x,y))) == g(x,y), but I don't know how to extend this to my vector function. So how can this be achieved?

4
  • So at a point (xi, yi) what is the associated z value? Commented Feb 13, 2018 at 20:37
  • What is X.T @ X supposed to be? It's not valid python syntax, is it? Commented Feb 13, 2018 at 21:35
  • @ImportanceOfBeingErnest that's matrix multiplication, new in Python 3. See this documentation Commented Feb 13, 2018 at 22:00
  • @unutbu z = f(np.matrix((xi,yi))) Commented Feb 14, 2018 at 7:55

2 Answers 2

1

The issue here is arranging dimensions. Your f seem to expect X and Y to be cast as a collection of vectors. But X and Y are two 101x101 matrices. So some rearranging and massaging is required. The good news is that using the map command below can be done to any function. The bad news - efficiency is elegance are probably not optimal.

This is what I would try:

Z = map(f, np.array([X.ravel(), Y.ravel()]).T)
Z = np.array(list(Z)).reshape(X.shape)

And then

ax.plot_surface(X,Y,Z)
Sign up to request clarification or add additional context in comments.

Comments

1

Assuming that what is meant by X.T @ X is numpy.dot(X.T,X), you may directly plot the result just as with any other function.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

f = lambda X: np.dot(X.T,X)

fig = plt.figure()
ax = plt.subplot(projection="3d")

X, Y = np.meshgrid(
    np.linspace(start = -10, stop = 10, num = 101),
    np.linspace(start = -10, stop = 10, num = 101))
ax.plot_surface(X,Y,f(X))

plt.show()

enter image description here

However, in order to get the desired output from the question, the function depends on both x and y, so what is wanted is probably

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

f = lambda xi,yi: np.dot(np.dot([xi,yi],np.identity(2)),[[xi],[yi]])

fig = plt.figure()
ax = plt.subplot(projection="3d")

X, Y = np.meshgrid(
    np.linspace(start = -10, stop = 10, num = 101),
    np.linspace(start = -10, stop = 10, num = 101))

Z = np.vectorize(f)(X,Y)
ax.plot_surface(X,Y,Z)

plt.show()

enter image description here

10 Comments

@ was added in 3.5, but is equivalent to np.dot(,). While this approach works with this particular function, I was more interested in a slightly more general approach, as this break down for f = lambda X: X.T @ A @ X, where A is a square matrix of size n≠101.
Not sure what you mean. For matrix multiplication the number of columns of the first matrix needs to match the number of rows of the second. This is rather a mathematical necessity than a question of implementation in some programming language.
Indeed, so I believe the input to f should be a list of grid points, not a matrix of the gridlines.
What exactly is the desired outcome?
The exact same result as your plot above when using f = lambda X: X.T @ np.identity(2) @ X, which is mathematically identical to your function.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.