MATLAB: How to get correct parameter values using greyest() function? - matlab

I'm using greyest() to find the correct parameter values of a transfer function. I have the input signal and the response of a Grey-Box dynamic system. Follows the code:
tsample = in.t(2)-in.t(1);
data = iddata(out.v,in.v,tsample);
Rf = 600e6;
Cf = 0.6e-9;
Rin = 0.56e3;
parameters = {'Rin',Rin;'Rf',Rf;'Cf',Cf};
sys = idgrey('amplif',parameters,'d',{},tsample);
opt = greyestOptions;
opt.InitialState = 'auto';
opt.SearchOptions.MaxIterations = 200;
opt.SearchOptions.Tolerance = 1e-200;
opt.Display = 'on';
opt.SearchMethod = 'grad';
Model = greyest(data,sys,opt)
Folllows the function "amplif.m":
function [A,B,C,D] = amplif(Rf, Cf, Rin, Ts)
% ODE function for computing state-space matrices as functions of parameters
Ac =[-(Cf*Rf + 2218.8e-12*Rin)/(Cf*2218.8e-12*Rf*Rin) -1/(Cf*2218.8e-12*Rf*Rin); 1 0];
Bc = [1; 0]; Cc = [-1/(Cf*Rin) 0];
Dc = 0;
% Discretize sysc = ss(Ac,Bc,Cc,Dc);
sysd = c2d(sysc,Ts,'least-squares');
[A,B,C,D] = ssdata(sysd);
I haven't found any problems with my code, although the output is always being the same values as initial parameters (Rf, Cf and Rin).
How to solve this problem!?
I tried to change some optinos of greyest function em to change the initial values of the three parameters.
Nothing is working.
I hope to find the correct values of the three parameters, depending on input and output of the dynamic system.

Related

Undefined function 'fitcnet' for input arguments of type 'string'

I have searched around for this for a long time but seems like nobody has any solution or used this function so called
fitcnet()
I keep getting the error Undefined function 'fitcnet' for input arguments of type 'string'.
I convert to table, double etc, but nothing works.
Here is my code:
clear;
close all;
clc
rng('default')
data = readtable('clean_data_nearmiss.csv');
data.Var1 = [];
enter code hesplit_size = 0.15;
N = size(data,1);
split = false(N,1);
split(1:round(split_size*N)) = true;
permutation = randperm(N);
split = split(permutation);
trainingSet = data(~split,:);
testingSet = data(split,:);
Separating variable predictors and output values for training and test sets.
trainingPredictors = trainingSet{:,1:30};
trainingOutcomes = trainingSet{:,31};
testingPredictors = testingSet{:,1:30};
testingOutcomes = testingSet{:,31};
X = trainingPredictors;
y = trainingOutcomes;
neural = fitcnet(X,y,"ClassNames",["0","1"]);

How to avoid tf() command using State-space models in Matlab

I'm trying to avoid the function tf() from Matlab since it requires specific toolboxes to run.
The transfer function that I'm using is quite simple. Is the model for a heatsink temperature.
H(s) = (Rth/Tau)/(s + 1/Tau)
In order to avoid the tf() function, I've tried to substitute the transfer function with a state space model coded in Matlab.
I've used the function ss() to get te values of A,B,C and D. And I've tried to compare the results from tf() and my function.
Here's the code that I've used:
Rth = 8.3220e-04; % ºC/W
Tau = 0.0025; % s
P = rand(1,10)*1000; % Losses = input
t = 0:1:length(P)-1; % Time array
%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Transfer function %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
H = tf([0 Rth/Tau],[1 1/Tau]);
Transfer_func = lsim(H,P,t);
figure, plot(Transfer_func),grid on,grid minor, title('Transfer func')
%%%%%%%%%%%%%%%%%%%%%%%%%
%%% My función ss %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
% Preallocate for speed
x(1:length(P)) = 0;
y(1:length(P)) = 0;
u = P;
sys = ss(H);
A = sys.A;
B = sys.B;
C = sys.C;
D = sys.D;
for k = 1:length(u)
x(k+1) = A*x(k) + B*u(k);
y(k) = C*x(k) + D*u(k);
end
figure, plot(y), grid on,grid minor, title('With my función')
I know that the values from A,B,C and D are ok, since I've checked them using
H = tf([0 Rth/Tau],[1 1/Tau]);
sys = ss(H);
state_space_sys = ss(sys.A,sys.B,sys.C,sys.D);
state_space = lsim(state_space_sys,P,t);
figure, plot(state_space),grid on,grid minor, title('State space')
As you can see, the results obtained from my funtion and the function tf() are very different.
Is there any mistakes on the approach?
If it's not possible to avoid the tf() function in this way, is there any other way?
At the end, I found another solution. I'm posting this here, so if someone has the same problem, can use this approach.
If you take the transfer function, and develop it, we reach to the following expresion
H(s) = deltaT(s)/P(s) = (Rth/Tau)/(s + 1/Tau)
deltaT(s) * (s + 1/Tau) = (Rth/Tau) * P(s)
deltaT(s) * s = (Rth/Tau) * P(s) - deltaT(s)/Tau
Now, we know that 1/s is equal to integrate. So in the end, we have to integrate the right side of the equation. The code would be like this.
Cth = Tau/Rth;
deltaT = zeros(size(P));
for i = 2:length(P)
deltaT(i) = (1/Cth * (P(i)-deltaT(i-1)/Rth))*(time(i)-time(i-1)) + deltaT(i-1);
end
This integral has the same output as the function tf().

Matlab: Return multiple parameter values from a nlinfit (right now I only go through one index of the loop)

I am trying to pass three cell2mat arrays for I,V,H through this function and plot the result of the parameter from the nlinfit model below. But when the code is run it plots nothing and only stores one value. Any help is appreciated:)
function [Icp] = Fraunhofer_Function(I,V,H)
V1 = #(b,I)(b(1).*sign(I).*real(sqrt(I.^2 - (sign(I).*( (b(2)+b(3)/2) )).^2)) + b(4));
Vthresx = find(V<=1e-3 & V>=0);
Ithresvec = max(I(Vthresx));
Voffsetx = find(I<=0.1e-3 & I>=-.1e-3);
Voffset = max(V(Voffsetx));
Rn = (max(V)-min(V))/(max(I)-min(I));
beta1 = [Rn; Ithresvec; -Ithresvec; Voffset]; %Init values b1=Rn b2 = Icp, b3 = Icm, b4 = Voffset
opts = statset('MaxIter', 500000, 'MaxFunEvals', 100000, 'RobustWgtFun', 'andrews');
B1 = nlinfit(I, V, V1, beta1, opts ); %Fit
Icp = V1(B1,V);
end
files = dir('*.xlsx*');
for k =1:length(files)
filenames = files(k).name;
txt = 'I,V,H';
[num,txt,raw] = xlsread(filenames);
%Put data into numerical columns
Idata = num(:,1)'; Vdata = num(:,2)'; Hdata = num(:,3)';
[Hu,~,idx] = unique(Hdata);
Isplit = splitapply(#(x) {x}, [Idata(:)],idx);
Vsplit = splitapply(#(x) {x}, [Vdata(:)],idx);
Hsplit = splitapply(#(x) {x}, [Hdata(:)],idx);
for l = 1:length(Isplit)
I = (Isplit{l,1});
V = (Vsplit{l,1});
H = (Hsplit{l,1});
%fit the data to the functional form
Icp = Fraunhofer_Function(I,V,H);
end
end
Example of the I,V,H, data is below:enter image description here
Right now you are just setting Icp to the second estimated coefficient. From the Matlab docs nlinfit, the output beta:
beta — Estimated regression coefficients
vector
Estimated regression coefficients, returned as a vector. The number of elements in beta equals the number of elements in beta0.
So to use the estimated parameters, you should call your modelfun, with the parameters stored in B1:
Icp = V1(B1,V);
plot(H,Icp);

How to use dynamic function name in MATLAB?

I am trying to optimize the following program by using for loops
t = 0:0.1:100;
conc = rand(size(t));
syms x
equ_1(x) = 10*x.^2+1;
equ_2(x) = 5*x.^3+10*x.^2;
equ_3(x) = 5*x.^3+10*x.^2;
y_1 = equ_1(conc);
y_2 = equ_2(conc);
y_3 = equ_3(conc);
p_1 = polyfit(t,y_1,1);
p_2 = polyfit(t,y_2,1);
p_3 = polyfit(t,y_3,1);
yfit_1 = p_1(1)*conc+p_1(2);
yfit_2 = p_2(1)*conc+p_2(2);
yfit_3 = p_2(1)*conc+p_2(2);
rms_er_1 = double(sqrt((sum((yfit_1-y_1).^2)./length(yfit_1))));
rms_er_2 = double(sqrt((sum((yfit_2-y_2).^2)./length(yfit_2))));
rms_er_3 = double(sqrt((sum((yfit_3-y_3).^2)./length(yfit_3))));
rms = [rms_er_1 rms_er_2 rms_er_3]
In this program. I have many equations and I can write them manually like equ_1(x),equ_1(x),equ_1(x) etc. After writing equations, will it be possible to write remaining programs by using for loops?
Can anyone help?
Yes, it is possible. You can pack your functions in a cell array and give your values as parameters while looping over this cell array
t = (0:0.1:100)';
conc = rand(size(t));
% Packing your function handles in a cell array ( I do not have the
% symbolic math toolbox, so I used function handles here. In your case you
% have to pack your equations equ_n(x) in between the curly brackets{} )
allfuns = {#(x) 10*x.^2+1, ...
#(x) 5*x.^3+10*x.^2, ...
#(x) 5*x.^3+10*x.^2};
% Allocate memory
y = zeros(length(t), length(allfuns));
p = zeros(2,length(allfuns));
yfit = zeros(length(t), length(allfuns));
rms = zeros(1, length(allfuns));
% Loop over all functions the cell, applying your functional chain
for i=1:length(allfuns)
y(:,i) = allfuns{i}(t);
p(:,i) = polyfit(t,y(:,i),1);
yfit(:,i) = p(1,i)*conc+p(2,i);
rms(:,i) = double(sqrt((sum((yfit(:,i)-y(:,i)).^2)./ ...
length(yfit(:,i)))));
end
This leads to
>> rms
rms =
1.0e+06 *
0.0578 2.6999 2.6999
You can expand that to an arbitrary number of equations in allfuns.
Btw: You are fitting 1st order polynomials with polyfit to values calculated with 2nd and 3rd order functions. This leads of course to rough fits with high rms. I do not know how your complete problem looks like, but you could define an array poly_orders containing the polynomial order of each function in allfuns. If you give those values as parameter to the polyfit function in the loop, your fits will work way better.
You can try cellfun
Here is an example.
Define in a .m
function y = your_complex_operation(f,x, t)
y_1 = f(x);
p_1 = polyfit(t,y_1,1);
yfit_1 = p_1(1)*x+p_1(2);
y = double(sqrt((sum((yfit_1-y_1).^2)./length(yfit_1))));
end
Then use cellfunc
funs{1}=#(x) 10*x.^2+1;
funs{2}=#(x) 5*x.^3+10*x.^2;
funs{3}=#(x) 5*x.^3+10*x.^2;
%as many as you need
t = 0:0.1:100;
conc = rand(size(t));
funs_res = cellfun(#(c) your_complex_operation(c,conc,t),funs);

How to calculate the expected value of a function with random normally distributed X?

I am trying to calculate on MatLab the Expectation for the function e^X where X ~ N(mu,sigma^2). In my example, mu = 0 and sigma = 1.
function [E] = expectedval(m,s)
%find E(e^x) with X~N(mu,sigma)
% mu = 0 , sigma = 1
X = normrnd(m,s);
f=exp(X);
mean(f)
So by the end I can run expectedval(0,1) to get my solution. The code runs with no issue, but I would like to compile a histogram to analyse the data with several runs. How may I collect this data with some sort of loop?
I'd appreciate any improvement ideas or suggestions!
Actually, your function just creates one random value for the given mean and variance... so there's actually no point in calculating a mean. On the top of that, the output E value is not assigned before the function finishes. The function can therefore be rewritten as follows:
function E = expectedval(m,s)
X = normrnd(m,s);
E = exp(X);
end
If you want to draw a sample from the normal distribution, and use the mean to compute the correct expected value, you can rewrite it as follows instead:
function E = expectedval(m,s,n)
X = normrnd(m,s,[n 1]);
f = exp(X);
E = mean(f);
end
And here is an example on how to run your function many times with different parameters, collecting the output on each iteration:
m = 0:4;
m_len = numel(m);
s = 1:0.25:2;
s_len = numel(s);
n = 100;
data = NaN(m_len*s_len,1);
data_off = 1;
for s = 1:s_len
for m = 1:m_len
data(data_off) = expectedval(m,s,n);
data_off = data_off + 1;
end
end