MATLAB Answers


Symbolic expression with matrix input and output

Asked by Hendrik Lorenz on 12 Jun 2019
Latest activity Commented on by Hendrik Lorenz on 12 Jun 2019
I want to symbolically define a matrix weighted norm like this:
Obviously I do not want to hard code the dimensions of vector and matrix.
I tried to define a symbolic expression like this:
C_mat_g_term_vec = sym('C_g_T_%d%d', [1, 18]);
C_mat_g_term = diag(C_mat_g_term_vec)
g_term_vec = sym('g_term_%d%d', [18, 1]);
% norm_mat_expr = @(v_in, W_in)((eye(size(v_in, 1), size(v_in,1))*v_in)).'*eye(size(W_in, 1))*W_in*(eye(size(v_in), size(v_in,1))*v_in)
norm_mat_expr = @(v_in, W_in)(v_in).'*W_in*(v_in)
norm_mat = sym(norm_mat_expr)
norm_mat(g_term_vec, C_mat_g_term)
Giving the error message:
Error using sym/subsindex (line 825)
Invalid indexing or function definition. Indexing must follow MATLAB indexing. Function arguments must be symbolic variables, and function body must be sym expression.
R_tilde = builtin('subsref',L_tilde,Idx);
So apparently Matlab Sim-Engine handles symbols as scalars.
Does someone has a practical solution for this? :)
The concrete answer is given in the comments below:
C_mat_g_term_vec = sym('C_g_T_%d_%d', [1, 18]);
syms C_mat_g_term
C_mat_g_term = diag(C_mat_g_term_vec);
g_term_vec = sym('g_term_%d_%d', [18, 1]);
norm_mat_expr = @(v_in, W_in)(v_in).'*W_in*(v_in)
norm_mat_expr(g_term_vec, C_mat_g_term)


Sign in to comment.




1 Answer

Answer by Walter Roberson
on 12 Jun 2019
 Accepted Answer

The symbolic engine does treat all unresolved symbols as scalars. That is hardcoded into the way it works internally and would be difficult to change. Therefore at the MATLAB level any symbolic function you define must be a function with particular size of arguments.
It looks to me as if you should not sym() the function handle and should instead pass particular arrays to it.


What I meant about passing particular arrays is that if you were to try to define
syms x y
f(x,y) = x*y;
intending matrix multiplication, then you would not be able to do so. In the second statement, MATLAB would resolve x and y each to symbolic variables that are scalars, and it "knows" that scalar times scalar is scalar, so it would treat the * as element-by-element multiplication. If you to later try f(C_mat_g_term_vec, g_term_vec) it would not use matrix multiplication as you might hope: it would do element-by-element multiplication. That would generate an error because implicit expansion is not done for symbolic operations.
In turn this means you cannot develop algorithms such as
syms x y a b
g(x,y) = inv(x) * f(x,y)
h(a, b) = sin(a) + g(a,b) %here you are passing nominal arrays a and b to g
c = sym('c', [4, 4]);
d = sym('d', [4, 4]);
h(c,d) %here you are passing actual arrays c and d to h
and what you have to do instead is
f = @(x,y) x*y
g = @(x,y) inv(x) * f(x,y)
h = @(a,b) sin(a) + g(a,b);
c = sym('c', [4, 4]);
d = sym('d', [4, 4]);
h(c,d) %here you are passing actual arrays c and d to h
The actual full-sized symbolic arrays get passed to the function handles, and the function handles preserve that full size into lower layer function handles and preserve algebraic operatons, so the x*y within f will be doing a matrix multiply of two actual arrays instead of two nominal arrays represented by symbols.
You could define a symbolic function
syms g C
g2c(g,C) = transpose(g) * C * g
but because symbolic variables are treated as scalars, this would come out as C*g.^2
You could define
C = sym('c', [4, 4]);
g = sym('d', [4, 4]);
g2c(reshape([g,C],1,[])) = transpose(g) * C * g
but that would define
g2c(d1_1, d2_1, d3_1, d4_1, d1_2, d2_2, d3_2, d4_2, d1_3, d2_3, d3_3, d4_3, d1_4, d2_4, d3_4, d4_4, c1_1, c2_1, c3_1, c4_1, c1_2, c2_2, c3_2, c4_2, c1_3, c2_3, c3_3, c4_3, c1_4, c2_4, c3_4, c4_4) =
which takes specific sizes of matrix inputs and would not work for (say) 5 x 5
There is no way at the MATLAB level to define a symbolic function that takes "a matrix" as an argument. Function handles bridge the gap.
There are ways inside the symbolic engine to create complete symbolic functions that accept arrays and can deal with them, and if you know the right rituals you can create such a function inside the symbolic engine starting at the MATLAB level -- but MATLAB has no way to display the result, and will crash the symbolic engine when you try to display the result.
Thanks again for the detailed explanation, much appreciated! Function handles as described work fine for my purposes.

Sign in to comment.