Determining several unknown variables in an equation using measured data.

I am trying to calculate several unknown variable in an equation. I have measured data that is to fit an equation and I want to calculate the unknown variables. The data is measured S-Parameter data (y axis) and frequency (x axis). This data is converted to impedance and graphed with frequency on the x axis and the impedance on the y axis. This data should fit the following equation
Zd(w) is the measured data. I know f[GHz], w is the converted frequency, I can calculated C, tano is also known and j in the imaginary number. Using this data and the known values I would like to use Matlab to calculate Rc, Rf and Ls.
I have read a number of examples for doing something similar though not the same. I have an average understanding of Matlab but I am no expert and many of the answers I've read assumed a certain level of programming knowledge that I do not have.
I was hoping someone could help get me started in the right direction. I've looked at things like the cftool and optimizer but I'm not knowlegable enough to know how to use them or if that is the correct tool for this case. I've also looked at things like the nonlinear curve fitting tool with no success. Any help would be greatly apprieated.

 Accepted Answer

Create a function
function goodness = fitparameters(RcRfLs, C, f, tandelta, w, Zd)
Rc = RcRfLs(1); Rf = RcRfLs(2); Ls = RcRfLs(3);
Zd_projected = Rc + Rf and so on
goodness = sum( (Zd_projected - Zd).^2 );
end
Now in the function that sets up all of the input values you can create
%assign to C, f, tandelta, w, Zd before this part
obj = @(RcRfLs) fitparameters(RcRfLs, C, f, tandelta, w, Zd);
Now you can minimize obj using your favorite minimizer, such as fmincon() or fminsearch()

13 Comments

Hello, thank you for the reply. I tried what you suggested. Still learning how to use the optimizer but I didn't make it past the first step. I tried to create the function as you suggested like this:
function goodness = fitparameters(RcRfLs, cap_0, fGHz, tandelta, w, Zd)
Rc = RcRfLs(1);
Rf = RcRfLs(2);
Ls = RcRfLs(3);
Zd_projected = Rc+Rf*sqrt(fGHz)+1i*(w*Ls-(1/(w*cap_0.*(1-(1i*tandelta)))))
goodness = sum((Zd_projected - Zd).^2);
end
However I get a error saying I need more input arguments. Any idea what I'm missing?
Thanks
I need to see your complete code.
Also, as you are using complex-valued expressions, probably the goodness calculation should be
goodness = sum(abs(Zd_projected - Zd).^2);
Currently the only code I have is to create the valiables cap_0, fGHz, tansdelta, w and Zd.
Zd, freq_0 and y12_0 are just pulled from an s2p file
Zd is the Z12 data from the file
freq_0 is the frequency range with
fGHz = freq_0 / 1e9;
w = freq_0*2*pi;
cap_0 = abs(imag(y12_0)./(2*pi*freq_0));
tandelta = real(y12_0)./imag(y12_0);
then I have to code I posted above where I tried to follow your suggestion.
Thank you
Where is your equivalent of
obj = @(RcRfLs) fitparameters(RcRfLs, C, f, tandelta, w, Zd);
and your call to a minimizer ?
I haven't added that part yet from your recommendations. I was just trying to see if I could get the function correct then add obj = @(RcRfLs) fitparameters(RcRfLs, C, f, tandelta, w, Zd); and final work on configuring the optimizer. Still have to learn how to properly operate that.
... then how did you call the function that resulted in the error about parameters?
I guess that’s where I’m confused. I don’t really have much experience doing this particular type of calculation so I’m not sure how I would implement the errror calculations. Would you mind elaborating? Thanks
The fitparameters() function already returns a measure of the error. A perfect fit would have it return 0; the larger the value returned, the less-good the fit.
Example,
format long g
Zd = rand(100,1);
freq_0 = rand()*1E9;
y12_0 = rand()*10 + rand()*10i;
fGHz = freq_0 / 1e9;
w = freq_0*2*pi;
cap_0 = abs(imag(y12_0)./(2*pi*freq_0));
tandelta = tan(rand()*pi/2);
obj = @(RcRfLs) fitparameters(RcRfLs, cap_0, fGHz, tandelta, w, Zd);
cfs0 = randn(1,3);
[best, fval] = fminsearch(obj, cfs0)
best = 1×3
1.08414599460078 -1.83547040997919 8.95330470586296e-11
fval =
45.1505543261584
function goodness = fitparameters(RcRfLs, cap_0, fGHz, tandelta, w, Zd)
Rc = RcRfLs(1);
Rf = RcRfLs(2);
Ls = RcRfLs(3);
Zd_projected = Rc+Rf*sqrt(fGHz)+1i*(w*Ls-(1/(w*cap_0.*(1-(1i*tandelta)))));
goodness = sum(abs(Zd_projected - Zd).^2);
end
I think I'm following. So I start with the Zd, y12_0, freq_0, cap_0, w, fGHz and tandelta all of which I either measured or calculated before hand. Then I create the function
function goodness = fitparameters(RcRfLs, cap_0, fGHz, tandelta, w, Zd)
Rc = RcRfLs(1);
Rf = RcRfLs(2);
Ls = RcRfLs(3);
Zd_projected = Rc+Rf*sqrt(fGHz)+1i*(w*Ls-(1/(w*cap_0.*(1-(1i*tandelta)))));
goodness = sum(abs(Zd_projected - Zd).^2);
end
which should show me the difference between the measured data and the equation I'm trying to fit. The difference being the values of Rc, Rf and Ls.
Then I run
obj = @(RcRfLs) fitparameters(RcRfLs, cap_0, fGHz, tandelta, w, Zd);
cfs0 = [.25,.25,1e-11];
[best, fval] = fminsearch(obj, cfs0);
I set cfs0 = to my inital guess and it runs. However the results aren't really what I'm expecting. In my case Zd, y12_0, freq_0, cap_0, w, fGHz and tandelta are all 400x1 vectors. Should I set this up to evaluate the functions at a single point in the vector one at a time?
Thanks
There are two different possibilities when you say that those are 400 x 1 vectors.
One possibility is that you are doing a multivariate fitting in which you are trying to find single Rc, Rf, Ls values that explain all of the variation. For example if you were trying to determine the specific heat capacity of something, then you would have a number of observations times in which each observation recorded time, temperature, pressure, whatever (acidity... whatever), and you combine all of the information to model the single factor(s) you are looking for that are constant across the experiment. Each time reading has a corresponding temperature, corresponding pressure, corresponding whatever.
For that situation, in which you have multiple variables each with a corresponding recording, then you just need to vectorize.
Zd_projected = Rc + Rf .* sqrt(fGHz) + 1i .* (w .* Ls - (1./(w .* cap_0 .* (1 - (1i .* tandelta)))));
The information from all of the readings is combined by the sum() of the squares down to a single error.
The other possibility is that you are running 400 different experiments, each of which has a separate Rc, Rf, Ls. If that was what you were doing, you would program differently to evaluate at single points. However... remember that if you have N parameters, then you need at least N different sets of input in order to be able to fit the parameters, so if you were doing 400 different experiments, you would need 1200 readings.
400 is not divisible by 3, so we can deduce that you are not doing 133 1/3 different experiments, with 3 sets of readings each.
We cannot rule out the possibility that you are doing 100 different experiments with 4 different readings each.
How many different Rc, Rf, Ls sets are you expecting based on your 400 readings? The answer is the same as the number of different sets you would split your data into for separate calculations.
I run one experiment at different voltages so cap_0 is 0 volts cap_5 would be 5 volts for this example I am just running the 0 volt. I collect just the S-parameters at each bias voltage. The S-parameters and frequency information are part of the file I am collecting. With that data I can calculate the Zd and y12_0 for each point so I would have a 400 element vector with the z and y information. Then I calculate the tandelta at each point again giving me a 400 element vector. W is just a conversion of the frequency. And finally I calculate the cap_0 from the y12_0 at each point. So it is really just one experiment for each bias voltage. In this case I'm am just trying look at the single experiment of the 0 volt experiment. I expect to get a single Rc, Rf and Ls but I wasn't sure if it made more sense to get a vector of each and find the average or just allow the optimizer to give me single values for each. The problem is that whe I run it on some test data I get results approx Rc = 300, Rf = -60 and Ls = 7e-13 and I'm expecting closer to Rc=0.5, Rf=0.025 and Ls=30e-11. Roughly. But none of them can be negative. I'm asssuming I have something wrong but I feel like I'm close.
Thanks
Use fmincon() with bounds instead of fminsearch()
I’ll try that. Thanks for all the help.

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!