How to solve a matlab fit? - matlab

So I want to solve a plot fit for several points, but the problem, that I am facing right now is, that my fit object fit_eq is a char but solve needs a sym. I searched everywhere and couldn't find a solution how to fix this. Here is my code, I cut unimportant parts, and some variables are german words, so don't get confused. gesamt is a 60x20 matrix, where every odd column is the same (it's made out of 10 matrices which are an outcome of a meassurement).
anzahlproben = 10;
for i = 1:2:anzahlproben*2
probe = gesamt(:,i:i+1);
[row c]=find(probe==0);
row(1:2,:)=[];
for j=row
probe(j,:)=[];
end
N22_{(i+1)/2} = probe;
end
for i = 1:1:anzahlproben
x = N22_{i}(1:1:size(N22_{i},1),1);
y = N22_{i}(1:1:size(N22_{i},1),2);
ft = fittype('poly9');
fitobject_{i}=fit(x,y,ft);
end
cvalues = coeffvalues(fitobject_{1});
cnames = coeffnames(fitobject_{1});
fit_eq = formula(fitobject_{1});
for ii=1:1:numel(cvalues)
cname = cnames{ii};
cvalue = num2str(cvalues(ii));
fit_eq = strrep(fit_eq, cname , cvalue);
end
y=1;
syms x
erg = (solve(fit_eq == y,x))
I got the last part from here and gives an equation in a char.
Matlab gives the output:
erg =
Empty sym: 0-by-1
Which can't be right. Any ideas?

As mentioned in the first line of the doc:
Support for character vector or string inputs has been removed.
Instead, use syms to declare variables and replace inputs such as
solve('2*x == 1','x') with solve(2*x == 1,x).
So eqn should be of class sym not a string!
Try:
erg = solve(str2sym(fit_eq) == y,x)
If it still don't work either your equation is wrong or you've not declared the symbolic variables involved in your equation.

Related

Why I am getting matrix dimension error in the line while calculating n?

Can you please tell me what's wrong with the following code?
function [n]=calculate_n(p,delta)
e = 1.6*power(10,-19);
k = 1.38*power(10,-23);
T = 298;
co = 3.25*power(10,13)*e*power(10,4);
er=12.5;
eo=1.0;
Nv=3*power(10,13);
us = log((p*e)/sqrt(2*k*T*er*eo*Nv))*2*k*T;
tmp = delta+(e*e*p)/co+us;
n = 1/(exp((tmp))+1);
end
I am getting matrix dimension error while calculating n. Please help me.
Caller:
e = 1.6*power(10,-19);
x = logspace(13,18);
y=calculate_n(x,0.2*e);
semilogx(x,y,'-s');
grid on;
Just replace n = 1/(exp((tmp))+1); with n = 1./(exp(tmp)+1);. But beware, tmp is so small for these values that exp(tmp) will always be 1. Also, there is a surplus bracket around tmp, you might want to check if you put them correctly.
Edit:
The reason is that A/B tries to solve the system of linear equations A*x = B for x which is not what you wanted. It threw an error because it requires both variables to have the same number of columns. A./B performs element-wise matrix division which is what you wanted. However, if A and B are singular A/B = A./B. See the documentation for more info.

How to get only the positive solution to a quadratic equation using the MATLAB Symbolic Toolbox?

I want to solve this equation in Matlab.
e=2;
while (e<30)
syms v;
solve('(v-e) = -(0.5*0.2*1.276*v^2*0.3)');
e=e+1;
end
When I write for example "solve('(v-10) = -(0.5*0.2*1.276*v^2*0.3)');" it works. But I need variable "e" in this equation.
In some cases, this equation has 2 solutions (negative and positive), but I need only positive solutions. What is the correct syntax? Thank you.
To add e to your equation you can concact it as a number to your equation: ['equation part one', num2str(e), 'end of your equation'].
To only have the positive solution, you can add a condition to your equation ( v>=0 ).
Here is an example of a complete solution to your problem:
ans = zeros(1,size(2:29,2));
i = 0;
syms v;
for e = 2:29
i = i+1;
ans(i) = solve(['(v-',num2str(e),') = -(0.5*0.2*1.276*v^2*0.3) and v>=0']);
end
There's no need to use strings unless you're using a really old version of Matlab. This is the modern and preferred way of using solve:
syms v positive;
e = 2:29;
s = zeros(length(e),1);
for i=1:length(e)
s(i) = double(solve(v-e(i)==-0.5*0.2*1.276*v^2*0.3,v));
end
However, since this is just a polynomial you can use the roots function:
e = 2:29;
s = zeros(length(e),1);
for i=1:length(e)
r = roots([0.5*0.2*1.276*0.3 1 -e(i)]);
s(i) = r(r>=0);
end

Warning: Possibly spurious solutions. [solvelib::checkSolutions]

I am trying to solve four algebraic equations in a for loop. It is giving a warning 'Possibly spurious solutions'. Could you please help me to figure out how to remove it. Code is attached herewith.
a=[1.78E-05 3.39E-04 0.0104 -0.05791 -16.36];
for i=1:R/l0
syms x y l r
[sol_l,sol_r,sol_x,sol_y] = solve(l == (sqrt((x-x0)^2+(y-y0)^2)), r == abs((x+x0)/2),...
poly2sym(a) == y, l*r*t == l0*r0*t0,x,y,l,r, 'Real', true);
for j=1:length(sol_x)
if (sol_x(j)<0)&&(sol_x(j)>x0)
if (sol_y(j)<0)&&(sol_y(j)<y0)
x_req(1,i) = sol_x(j);
y_req(1,i) = sol_y(j);
end
end
end
x0 = x_req(1,i);
y0 = y_req(1,i);
r0 = R-l0*(2*i-1)/2;
end
If you change your first equation to this, the warning no longer crops up:
l^2 == (x-x0)^2+(y-y0)^2
I'm not sure that you actually have spurious values though. The it's possible that the square root gave solvelib::checkSolutions trouble.
You may have thought that you had spurious values when you checked because you weren't outputting the variables correctly. You specify that solve solve for x, y, l, r (in that order), but then you name the output variables as sol_l, sol_r, sol_x, sol_y (different order). You must use the same order as `solve cannot guess bases on the names of your variables.
Your code:
R=30;
x0=-R;
y0=0;
l0=R/100;
t0=1.2;
t=0.7071;
r0=R-l0/2;
a=[1.78E-05 3.39E-04 0.0104 -0.05791 -16.36];
[sol_x,sol_y,sol_l,sol_r] = solve(l^2 == (x-x0)^2+(y-y0)^2, ...
r == abs((x+x0)/2), ...
poly2sym(a) == y, ...
l*r*t == l0*r0*t0, ...
x,y,l,r, 'Real', true)
% Check
sol_l2.^2 - (sol_x2-x0).^2+(sol_y2-y0).^2
sol_r - abs((sol_x+x0)/2)
[subs(poly2sym(a),x,sol_x(1));subs(poly2sym(a),x,sol_x(2));...
subs(poly2sym(a),x,sol_x(3));subs(poly2sym(a),x,sol_x(4))]-sol_y;
sol_l2.*sol_r2*t - l0*r0*t0
The check returns small values close zero.

how to write this script in matlab

I've just started learning Matlab(a few days ago) and I have the following homework that I just don't know how to code it:
Write a script that creates a graphic using the positions of the roots of the polynomial function: p(z)=z^n-1 in the complex plan for various values for n-natural number(nth roots of unity)
so I am assuming the function you are using is p(z) = (z^n) - 1 where n is some integer value.
you can the find the roots of this equation by simply plugging into the roots function. The array passed to roots are the coefficients of the input function.
Example
f = 5x^2-2x-6 -> Coefficients are [5,-2,-6]
To get roots enter roots([5,-2,-6]). This will find all points at which x will cause the function to be equal to 0.
so in your case you would enter funcRoots = roots([1,zeros(1,n-1),-1]);
You can then plot these values however you want, but a simple plot like plot(funcRoots) would likely suffice.
To do in a loop use the following. Mind you, if there are multiple roots that are the same, there may be some overlap so you may not be able to see certain values.
minN = 1;
maxN = 10;
nVals = minN:maxN;
figure; hold on;
colors = hsv(numel(nVals));
legendLabels = cell(1,numel(nVals));
iter = 1;
markers = {'x','o','s','+','d','^','v'};
for n = nVals
funcRoots = roots([1,zeros(1,n-1),-1]);
plot(real(funcRoots),imag(funcRoots),...
markers{mod(iter,numel(markers))+1},...
'Color',colors(iter,:),'MarkerSize',10,'LineWidth',2)
legendLabels{iter} = [num2str(n),'-order'];
iter = iter+1;
end
hold off;
xlabel('Real Value')
ylabel('Imaginary Value')
title('Unity Roots')
axis([-1,1,-1,1])
legend(legendLabels)

vector comparison and new assignment

I'd like to ask you question about some matlab code I wrote, But first of all tell you my problem. I have 2 vectors, Test Labels and Predicted labels and I want to compare them for classification reasons. Further more I want to allocate some labels new. so I have something like this 111121111 = 1 or 1122222222 =2 which I want to achieve. My code is
y = [];
for k = 10:length(predictedLabel)-10
y = [y; newlabel(predictedLabel, k, 5)];
end
and the function newlabel is
function [nl] = newlabel(x, n, L)
numClasses = 3;
x1 = x(n-L:n+L);
c = zeros(numClasses, 1);
for k=1:length(x1)
c(x1(k)) = c(x1(k))+1;
end
[~,nl]=max(c);
end
My problem is now that I result following vector lengths
predictedLabel = 4996*1;
k=4986*1;
y=4977*1;
and I can't see my mistake
Any help is appreciated even new ideas with probability estimations
Thanks
loop
1- when using the length function on a scalar value it gives 1 then the value inside the for loop becomes from 10:1-10 which is meaningless. (If you want to use decreasing step you should provide something like this 10:-1:1).
2- if you want to make a vector with the size of 4996x1 it would be like this : zeros(4996,1) or ones(4996,1) or sth like this.
3- tell us about your desired result and your error.... the description is not obvious to me.