matlab: creating a symbolic vector
Asked Answered
F

1

6

I am trying to create a function using the symbolic toolbox in matlab. I have been having trouble creating a symbolic vector (not a vector of symbolic variables). Do you guys know a way to do this without creating and editing a text-like matlab function file in your path?

  • *After creating the symbolic variables and all I use 'matlabFunction' to create and save the function.

Example:

Function:

function f=test1(x,a) {
   f=x(1)/a(1)+x(2)/a(2);
}

Code:

a = sym('a', [1 2]);
x = sym('x', [1 2]);
% f(x, a) = sym('f(x, a)');
r=x(1)/a(1)+x(2)/a(2);
% f(x,a)=r;
% handle=matlabFunction(f(x,a),'file','test1');
handle=matlabFunction(r,'file','test1');
  • The problem is that the code seen above creates a function with the set of input arguments (x1, x2, a1, a2) instead of (x,a) and I can't change the form of input arguments, it must be uniform.
  • In reality I am trying to write a function that will create a polynomial of specified degree and save it to the path so I could use 'eval' with it (which doesn't support polyval), but it will probably be useful for more.
Fm answered 6/9, 2013 at 10:20 Comment(0)
P
7

Try:

>> x = sym('x',[1 2])
x =
[ x1, x2]

>> x(1)
ans =
x1

>> x(2)
ans =
x2

>> whos x
  Name      Size            Bytes  Class    Attributes

  x         1x2               112  sym      

This is similar to writing:

>> syms a1 a2
>> a = [a1 a2]

EDIT:

First we build an expression from the symbolic variables:

a = sym('a', [1 2]);
x = sym('x', [1 2]);
expr = x(1)/a(1)+x(2)/a(2);

Next we convert it to a regular MATLAB function:

fh = matlabFunction(expr, 'file','test1', 'vars',{a,x});

The generated function is:

function expr = test1(in1,in2)
    a1 = in1(:,1);
    a2 = in1(:,2);
    x1 = in2(:,1);
    x2 = in2(:,2);
    expr = x1./a1+x2./a2;
end

Initially I was thinking of using regular expressions to fix the function handle generated. This is a much dirtier hack, so I recommend using the previous approach instead:

% convert to a function handle as string
fh = matlabFunction(expr);
str = char(fh);

% separate the header from the body of the function handle
T = regexp(char(fh), '@\((.*)\)(.*)', 'tokens', 'once');
[args,body] = deal(T{:});

% extract the name of the unique arguments (without the index number)
args = regexp(args, '(\w+)\d+', 'tokens');
args = unique([args{:}], 'stable');

% convert arguments from: x1 into x(1)
r = sprintf('%s|', args{:}); r = r(1:end-1);
body = regexprep(body, ['(' r ')(\d+)'], '$1($2)');

% build the arguments list of the new function: @(a,b,c)
head = sprintf('%s,', args{:}); head = head(1:end-1);

% put things back together to form a function handle
f = str2func(['@(' head ') ' body])

The resulting function handle:

>> f
f = 
    @(a,x)x(1)./a(1)+x(2)./a(2)
Pavo answered 6/9, 2013 at 13:24 Comment(7)
tried it before, doesn't work. it creates a function with 4 input arguments: 'test1(x1, x2, a1, a2)' instead of 'test1(x, a)'.Fm
I dont follow, the above doesnt create a function, only the symbolic variables. Those will be the input to your functions that you will have to write.. Perhaps you could explain further exactly what you are doingPavo
after you create those symbolic variables and use them to create a function using 'matlabFunction' the function that it will create will have 4 input arguments (x1, x2, a1, a2) instead of (x, a), it will treat every cell in the vectors x and a as an individual variable and it won't except 2 vectors as needed, but 4 arguments instead.Fm
@Avico: ah now I understand, you didnt initially mention matlabFunction. Can you post the exact expression you are converting into a function handle? I'm thinking we can fix it by using some regular expression...Pavo
@Avico: try this: fh = matlabFunction(r, 'file','test1', 'vars',{a,x}) (you could reverse the order {x,a} if you like). This tells MATLAB to use vectors as inputPavo
@Avico: only as a reference, I posted my initial thought of using regexpPavo
The regexp approach is nice, but it's not so different than writing the function as a string in the first place and creating an text file with '.m' extension. if you don't care how the function looks, which you probably are if you're using 'matlabFunction', than the first solution is more elegant. If you want to create a more readable function you will probably have to write it as a string and save it to file.Fm

© 2022 - 2024 — McMap. All rights reserved.