# How to make a symbolic function of a matrix ?

Hi,

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)

edit retag close merge delete

Sort by » oldest newest most voted

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')]]);

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

# see result
Qf, Xf, X, f


produces

$$\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)
X


$$\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]

# see result


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

more

Ty so much :)

( 2017-02-21 14:37:45 +0200 )edit
1

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 ^^

( 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!

( 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)
-0.0

( 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!

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