Ask Your Question

How to make a symbolic function of a matrix ?

asked 2017-02-21 02:33:30 +0200

Babacool51 gravatar image


I'm beginning with Sage. I've got two matrix Qf and Xf defined by :

Qf = 1000000*matrix([[0,0],[0,1]]);
Xf = matrix([1],[1675]);

I would like to write a symbolic function "f" which would take a matrix X with 2 rows & 1 column.

X = var('X');
f(X) = ((X-Xf).transpose()*Qf*(X-Xf));

I easily wrote it with python non-symbolic function syntax, but i didn't find a way to make it symbolic. Because I'll need his gradient later (which is easy to calculate by hand, that I conceed ^^).

Maybe, it's related with SR matrix, no idea, i'm beginning with Sage and that's why I'm asking for help x)

Thank you in advance.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2017-02-21 07:53:59 +0200

mforets gravatar image

updated 2017-02-21 12:46:09 +0200

Yes, SR matrices come in handy for that type of calculations.

# data
Qf = 1000000*matrix([[0,0],[0,1]]);
Xf = matrix([[1],[1675]]);

# matrix with symbolic coefficients
X = matrix([[var('x1')], [var('x2')]]);

# quadratic function
f = ((X-Xf).transpose()*Qf*(X-Xf));

# see result
Qf, Xf, X, f


$$ \newcommand{\Bold}[1]{\mathbf{#1}}\left(\left(\begin{array}{rr} 0 & 0 \\ 0 & 1000000 \end{array}\right), \left(\begin{array}{r} 1 \\ 1675 \end{array}\right), \left(\begin{array}{r} x_{1} \\ x_{2} \end{array}\right), \left(\begin{array}{r} 1000000 \, {\left(x_{2} - 1675\right)}^{2} \end{array}\right)\right). $$

To evaluate $f$, do f(x1=1,x2=1).

More generally, to define your $X$ it can be useful to do something like:

# create a coefficient matrix of m rows and n columns
m = 4; n = 2; 
xij = [[var('x'+str(1+i)+str(1+j)) for j in range(n)] for i in range(m)]
X = matrix(SR, xij)

$$ \newcommand{\Bold}[1]{\mathbf{#1}}\left(\begin{array}{rr} x_{11} & x_{12} \\ x_{21} & x_{22} \\ x_{31} & x_{32} \\ x_{41} & x_{42} \end{array}\right). $$

The quadratic function $f$ defined above is a $1\times 1$ matrix (convince yourself, for instance by reading the output of type(f)). To take the gradient this is one possible way:

# passing from a 1x1 matrix to a scalar
f = f[0, 0]

grad_f = f.gradient([x1, x2])

# see result

$$ \newcommand{\Bold}[1]{\mathbf{#1}}\left(0, 2000000 x_{2} - 3350000000\right). $$

edit flag offensive delete link more


Ty so much :)

Babacool51 gravatar imageBabacool51 ( 2017-02-21 14:37:45 +0200 )edit

Just one last thing, is there any way to make elegant evaluation of f, as something like :

M = matrix([[1,2],[3,4],[5,6],[7,8]]);
print f(M);

Or eventually :

M = matrix([[1,2],[3,4],[5,6],[7,8]]);
print f(xij = M[i][j]);

You see the idea ^^

Babacool51 gravatar imageBabacool51 ( 2017-02-21 15:03:30 +0200 )edit

going back to the example of above, and if v = vector([1, 2]), then f(X=v) will unfortunately not work, but with f.substitute([X[i][0] == v[i] for i in range(2)]) it evaluates $f$ at the point $(1, 2)$. I'm not sure if this is what you want to do, so don't hesitate to post a new question!

mforets gravatar imagemforets ( 2017-02-21 18:39:25 +0200 )edit

I works perfectly i'm actually gratefull, believe me :)

There is my code, if eventually it can serve to someone :

Qf = 1000000*matrix([[0,0],[0,1]]);
Xf = matrix([[1],[1675]]);
X = matrix(SR, [[var('X'+str(1+i)+str(1+j)) for j in range(1)] for i in range(2)]);
f = ((X-Xf).transpose()*Qf*(X-Xf))[0,0];

Xt = matrix([[1],[1]]);
print f;
print f.substitute([X[i,0]==Xt[i,0] for i in range(2)]);

-1000000.0*(X21 - 1659.0)*(-1.0*X21 + 1659.0)
Babacool51 gravatar imageBabacool51 ( 2017-02-21 19:52:47 +0200 )edit

may i ask you something babacool51, in which context you are using this code? like course of math (linear algebra?) or another? thanks for any feedback!

mforets gravatar imagemforets ( 2017-04-18 14:47:34 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2017-02-21 02:33:00 +0200

Seen: 445 times

Last updated: Feb 21 '17