solving equation with if statements
4 次查看(过去 30 天)
显示 更早的评论
antoine
2020-1-17
Hello
I am trying to solve the following equation given input time and values (y) vectors.
I tried the following
syms theta kappa alpha
if time < alpha
eqn = exp(-kappa*time)==y;
else
eqn = exp(-kappa)*exp(-theta*(time-alpha))==y;
end
vars = [theta kappa alpha];
S=solve(eqn);
but it raises an error...
Conversion to logical from sym is not possible.
I tried to convert alpha into double (i.e. double(alpha) ) in the if statement but it did not work...
Any suggestions?
the data look like :
采纳的回答
Walter Roberson
2020-1-17
syms theta kappa alpha time y real
eqn = y == piecewise(time < alpha, exp(-kappa*time), exp(-kappa)*exp(-theta*(time-alpha)));
vars = [theta kappa alpha];
S = solve(eqn, kappa, 'returnconditions', true); %solve for which variable ??
21 个评论
antoine
2020-1-17
thank you so much Walter! I want to solve all vars
Here 's what I did (mat files are vectors of proportion of survival overtime)
%%%equations
load('values_bupr1.mat')
load('days_bupr1.mat')
y=values_bupr_nodup;
time=days_bupr_nodup;
syms theta kappa alpha time y real
eqn = y == piecewise(time < alpha, exp(-kappa*time), exp(-kappa)*exp(-theta*(time-alpha)));
vars = [theta kappa alpha];S
S = solve(eqn, vars, 'returnconditions', true);
and I got empty output (I expect a value for each var)
S =
struct with fields:
theta: [2×1 sym]
kappa: [2×1 sym]
alpha: [2×1 sym]
parameters: [1×4 sym]
conditions: [2×1 sym]
Does that make sense?
antoine
2020-1-17
to complete my previous comment. The output are
>> S.kappa
ans =
-log(y)/time
z
>> S.alpha
ans =
u
z1
>> S.theta
ans =
x
log(y*exp(z))/(z1 - time)
but I don't know how to get a value for each of my var...I am probably missing an obvious step
Walter Roberson
2020-1-18
编辑:Walter Roberson
2020-1-18
You only have one equation, you can only solve for one variable.
Or is your y a vector?
Walter Roberson
2020-1-18
syms theta kappa alpha Time real
eqn = piecewise(Time < alpha, exp(-kappa*Time), exp(-kappa)*exp(-theta*(Time-alpha)));
residue = sum((subs(eqn, Time, time) - y).^2);
residueF = matlabFunction(residue, 'vars', {[theta kappa alpha]}, 'file', 'residue.m'); %must write to file!
Now residueF is a function handle to minimimize, such as
kappa_guess = mean(-log(y)./time);
theta_guess = randn;
alpha_guess = randn;
p0 = [theta_guess, kappa_guess, alpha_guess];
[best_parameters, best_residue] = fminsearch(residueF, p0);
It would be common that any particular initial guess will not get you to the best fit; you will probably need to try several values.
You must use the 'file' option with matlabFunction in this situation: because the value of alpha is not known, the piecewise() cannot be resolved even though the times are known, so the expression will have have a piecewise() expression in it, and matlabFunction can only handle piecewise() when writing to a file.
antoine
2020-1-18
My progress so far:
the code above is not working if I try to solve all 3 variables... Since I expect alpha to be between 60 and 300 , I tried to simplify the code and assign an alpha like:
alpha=90; % my first guess
syms theta kappa Time real
eqn = piecewise(Time < alpha, exp(-kappa*Time), exp(-kappa)*exp(-theta*(Time-alpha)));
residue = sum((subs(eqn, Time, time) - y).^2);
residueF = matlabFunction(residue, 'vars', {[theta kappa ]}, 'file', 'residue.m'); %must write to file!
kappa_guess = mean(-log(y)./time);
theta_guess = randn;
p0 = [theta_guess, kappa_guess];
[best_parameters, best_residue] = fminsearch(residueF, p0);
Here your code is working ONLY and I got the following theta and kappa
kappa_guess = 0.0023
theta_guess = 0.5377
Any suggestion? any ways alpha can also be an output?
thank you!
(I can share the data if you want)
antoine
2020-1-18
using strictly the code you suggested;
load('values_bupr1.mat')
load('days_bupr1.mat')
y=values_bupr_nodup;
time=days_bupr_nodup;
syms theta kappa alpha Time real
eqn = piecewise(Time < alpha, exp(-kappa*Time), exp(-kappa)*exp(-theta*(Time-alpha)));
residue = sum((subs(eqn, Time, time) - y).^2);
residueF = matlabFunction(residue, 'vars', {[theta kappa alpha]}, 'file', 'residue.m'); %must write to file!
Now residueF is a function handle to minimimize, such as
kappa_guess = mean(-log(y)./time);
theta_guess = randn;
alpha_guess = randn;
p0 = [theta_guess, kappa_guess, alpha_guess];
[best_parameters, best_residue] = fminsearch(residueF, p0);
I have the following error
Error using symengine
Unable to evaluate to Boolean.
Error in sym/mupadmexnout (line 1057)
out = mupadmex(fcn,args{:});
Error in sym/matlabFunction>optimize (line 468)
[tvalues,f,tnames] = mupadmexnout('symobj::optimizeWithIntermediates',f{:});
Error in sym/matlabFunction>writeMATLAB (line 443)
[f,tvalues,tnames] = optimize(f,optim);
Error in sym/matlabFunction (line 183)
g = writeMATLAB(funs,file,varnames,outputs,body, opts.Optimize, opts.Sparse, opts.Comments);
Error in SOLVER_3VARS (line 14)
residueF = matlabFunction(residue, 'vars', {[theta kappa alpha]}, 'file', 'residue.m'); %must write to file!
Walter Roberson
2020-1-19
It looks like it is probably easiest to construct
residue = @(tka) sum((project_y(tka, time) - y).^2);
function projected = project_y(tka, time)
theta = tka(1); kappa = tka(2); alpha = tka(3);
projected = exp(-kappa.*time);
mask = time >= alpha;
projected(mask) = exp(-kappa).*exp(-theta.*(time(mask)-alpha));
end
antoine
2020-1-19
Really feel bad but I can't make it work... can you share the full code for my input data? sorry but my lack of matlab experience is strickingly apparent.
thank you ++
antoine
2020-1-20
Hi Walter. Can you let me know if it works on your machine ? Would you mind sharing the full code for my input? thank you so much!
Walter Roberson
2020-1-20
load('values_bupr1.mat')
load('days_bupr1.mat')
y = values_bupr_nodup;
time = days_bupr_nodup;
residueF = @(tka) sum((project_y(tka, time) - y).^2);
kappa_guess = mean(-log(y)./time);
theta_guess = randn;
alpha_guess = 150;
p0 = [theta_guess, kappa_guess, alpha_guess];
opts = optimset('fminsearch');
opts = optimset(opts, 'MaxIter', 2000, 'MaxFunEvals', 10000, 'FunValCheck', 'on');
[best_parameters, best_residue] = fminsearch(residueF, p0, opts)
function projected = project_y(tka, time)
theta = tka(1); kappa = tka(2); alpha = tka(3);
projected = exp(-kappa.*time);
mask = time >= alpha;
projected(mask) = exp(-kappa).*exp(-theta.*(time(mask)-alpha));
end
My tests so far suggest that the best fit is near
theta = 0.000844900288029776
kappa = -556.133604457634
alpha = -659149.32154226
That is, with alpha so negative that time < alpha is false for all entries, and the exp(-theta*(time-alpha)) term heads towards 0.
antoine
2020-1-20
mmhhh.. that does help but alpha cannot be negative (it is a duration)
can we inforce alpha as positive? thank you!
Walter Roberson
2020-1-20
When you restrict to positive alpha, then fitting pretty much cannot tell the difference between large-ish negative theta and large-ish positive theta. The only consistency you get is that kappa narrows down to close to 0.00292734523205026836 and otherwise it becomes difficult to tell apart locations with theta anywhere above 788 or so, and the larger you make alpha the more decimal places you can grind out on essentially the same fit. At the moment, the best fit I have is at
theta = 5087.59871387777093
kappa = 0.00292734523205026836
alpha = 803477.437304047635
but the confidence intervals for theta and alpha are terrible.
antoine
2020-1-20
bummer... I will try to figure this out but this is definitely VERY helpful. I will keep you informed
Thank you so much for your patience and support. I learnt a lot
antoine
2020-1-20
If I run the code above once, I got the following
If 266 is alpha, this is really what I would expect... I am probably missing something (I used alpha guess=150)
best_parameters =
0.0065 0.0060 266.0000
Walter Roberson
2020-1-20
Yup, but that gives residue in the range of 62, whereas 5087.59871387777093, 0.00292734523205026836, 803477.437304047635 gives you residue in the range of 39.02 which is significantly better. Given that model, alpha should be large, over 100,000.
更多回答(2 个)
antoine
2020-1-18
time and y are vectors (see plot above for data input). all suggestions are welcome.
I can share the data if it helps
thank you ++
1 个评论
Walter Roberson
2020-1-18
Unless time and y are vectors of length 3 exactly, it seems unlikely that there would be any solutions.
It looks to me as if what you have should be a modeling task to estimate parameters rather than a set of simultaneous equations.
antoine
2020-1-18
good not know...Not sure I have the skills to do that.
I really appreciated your input and advices.
1 个评论
antoine
2020-2-22
dear Walter
Just realized I forgot to thank you for your help
Problem is fixed! I got my equations working.
(I am know stuck with other timer/loop function : see 'time-dependant iteration through a loop?' if you have time...)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Calculus 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)