Hi. I have symbolic expressions in a script file (that represent calculated partial derivatives. Because I need, at each iteration, that get the numeric value of the symbolic expression depending on the new set values of variables, I created a function, that compute this) Since that symbolic expression is different from case to case, is there a possibility that the expression automatic import in function without manual typing these expressions. I want to define this expression in one place in the script file, and than when you call functions, this expression be automatically loaded in function. Thank you in advance.
MATLAB: How automatic insert (once defined) symbolic expression from script or workspace to function
symbolic expressionuser function
Related Solutions
Hi Work Wolf
this is John BG ( <mailto:jgb2012@sky.com jgb2012@sky.com> ), please comment if the following answers your question, script and support function attached, following my understanding of the question:
% attached files: example_prob_density.m find_nearest_xk.m
1.
Defining a test x:
N=10 % define amount of points in x
x=randi([1 1000],1,10)/100 % generate x points
h=min(abs(diff(x))) % define h, here it's as small as the shortest step among x values
2.
Defining void grid for result, your px(x) I call it pv
dv=.1*hv=[min(x)-h:dv:max(x)+h]; % this is the grid to be used to calculate pk(x)
pv=zeros(1,numel(v));
3. check
stem(x);hold all;plot(x)
% x=[0 x 0]; not needed
4.
sweep v, not x
for k=1:1:length(v) [xk xk1 xk2]=find_nearest_xk(v(k),x) sgna=sign(v(k)-xk) da=abs(v(k)-xk) % abs(x-x(k)) within [0 h/3]
da1=abs(v(k)-xk1) % abs(x-x(k)) within [h/3 2*h/3]
da2=abs(v(k)-xk2) % abs(x-x(k)) within [2*h/3 h]
if da<=h/3 pv(k)=1-sgna*da;end; if da1>h/3 && da<2*h/3 pv(k)=.5-3*sgna*(da1-h); end; if da2>2*h/3 && da<h pv(k)=da2^3*sgna; end;end
5.
result
figure(2);plot(v,pv)hold all;stem(x);grid on
.
6.
the support function finds the nearest x(k) to each point of v, which is your input x, not the same as the input sequence of scattered points x [x1 x2 .. xn]
function [y y1 y2]=find_nearest_xk(a,b) % a is a point, b is a a group of points
% calculating length(b) distances to point a
% returning point b(k) closest to a, and adjacent points b(k-1) b(k+1)
% adjacent to b(k), not to a
db=0 for s=1:1:length(b) db=[db abs(a-b(s))]; end db(1)=[]; [db n_b]=min(db) % y=b(n_b)
if n_b==1 y=0;y1=b(1);y2=b(2); end if n_b==numel(b) y=b(numel(b)-1);y1=b(numel(b));y2=0; end if n_b>1 && n_b<numel(b) y=b(n_b-1);y1=b(n_b);y2=b(n_b+1); end % m=n_b % not needed, just for debugging
end
7.
comment, please note that in order to keep symmetry and shorten the amount of required Ifs I have used the following expression
8. update
ok, so far pk(x) now does something, not flat anymore, it looks like a noisy sin(v), sort of.
This is because the support function I initially used did not take into account x(k-1) and x(k+1), check 1st email.
I have updated both script and support function to take into account x(k-1) and x(k+1) as requested, check attachments to this answer and 3rd email.
Now, for different random sequences (10 samples only each test) one gets a clear spike, or a couple of them. Sample:
.
Hope it helps.
.
Work Wolf, also to PhD Adel Adel
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance
John BG
syms h(d1,d2) a b p1 p2 r1 r2P1 = 1/(1+d1);P2 = 1/(1+d2);h(d1, d2) = subs( ((a-b)*(p1*(r1-d1)-p2*(r2-d2))+1)/2, [p1 p2], [P1 P2]);h1 = diff(h,d1);h2 = diff(h,d2);eqs = subs( [-(-h/(1+d1)^2+h1*p1)*(r1-d1)-(a/(a+b)-h*p1)+h1*p2*(r2-d2)==0, (h2*p2+(1-h)/(1+d2)^2)*(r2-d2)-(a/(a-b)-p2*(1-h))-h2*p1*(r1-d1)==0], [p1 p2], [P1 P2]);D1 = solve(p1 == P1, d1);D2 = solve(p2 == P2, d2);eqns2 = subs( eqs, [d1 d2], [D1 D2]);unknowns = [p1,p2];sol = solve(eqns2, unknowns, 'ReturnConditions', true)
This will give 16 solutions, 8 of which are for the case that a is 0, and the other 8 for the case that a is not 0. 0 is the solution under several of the possibilities.
The solutions involve the roots of a degree 8 polynomial. The solver does not even attempt to merge the coefficients, so it comes out pretty long and unreadable (and the root expression occurs up to 5 times per solution of p1).
You can manually force MATLAB to take children of expressions until you extract the repeated root() term (using subexpr() helps some), after which you can strip the root() holder off using children(). Take that expression and apply coeffs() to it to pull out the various z terms. You can then simplify that. Multiply back by the powers of z (second output of coeffs) and sum to get a polynomial that is a bit easier to read. This basic polynomial has its roots extracted multiple times in the general solution for p1, but in different places different root numbers are used.
It might have been easier to solve your original equations for d1 and d2 and then to transform that to get p1 and p2. Or easier, perhaps, to use the p1 and p2 assignments as equations instead and then to solve for p1, p2, d1, d2... I did not try that.
Best Answer