# Least square curve fit in MATLAB for Alpha power law MOSFET model

#### ANALA M REDDY

Joined Aug 14, 2017
22
For function like y = a*(x-b)^c, how can I use the least square curve fit feature to find out the coefficients a, b and c? But If i use the custom equation in cftool it reports " Complex value computed by model function, fitting cannot continue. Try using or tightening upper and lower bounds on coefficients".

#### MrAl

Joined Jun 17, 2014
8,477
Hi,

Basically if your model statement results in a complex value then the algorithm might not be able to handle that but it is also probable that you dont need to find complex solutions anyway,which you usually dont.

The problem could stem from the exponent 'c'. If you allow 'c' to go to say 1/2, then you are taking the square root of x-b. Now if your test data set includes a value for x of say 1 and the constant 'b' can have an upper limit of say 2, then you are trying to take the square root of -1 which results in a complex number.

So by the error description, you have to think about this and figure out better upper and lower limits for the constants in your model statement so that the model statement never produces a complex value when x is in the range of your test data set.

I dont use that program, but this is a general issue regarding curve fitting. Another issue that comes up is a zero in the denominator. If you have a model statement like 1/x and your data set included the point (0,y) then when the algorithm encounters that data point it's going to flag an error, division by zero. That's just one more example of what can go wrong in curve fitting algorithms.

In some cases you can change the model statement if you know something about the physical behavior of the phenomenon you are trying to model and get much better results. An example is curve fitting a thermistor where if you work in a logarithmic system you get a better result. I dont know if this will help your situation but if you take the log of both sides of your model statement you get:
log(y)=c*log(x-b)+log(a)

and since log(a) is another constant that simplifies that a little. This may or may not help in your case but that's up to you to figure out. log(1-2) will still produce a complex number for example.

#### ANALA M REDDY

Joined Aug 14, 2017
22
I have attached my data and script..
predicted = @(a,x) a(1)*((x-a(2)).^a(3));

a0 = [?:?:?];
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] = lsqcurvefit(predicted,a0,x,y);
May i know how to set the initial value of a0 inorder to obtain the fit and extract the co-efficients a1,a2,a3...?

#### Attachments

• 418 bytes Views: 3

#### MrAl

Joined Jun 17, 2014
8,477
Hi,

As i said, i dont have that program so you are going to have to write your question using everyday math syntax.
Also as i said, if you get a complex number then you need to set your range of constants differently.

The main problem seems to be in the part where you had x-b previously, or you have to limit c to be a
Since your test data seems to range 0 to 1 for x, that means b must be in the range -inf<b<0 which for all practical purposes would probably be something like -1000<b<0 or similar where -1000 is the highest number for b you think will ever be needed for the particular physical phenomenon.
If this range is not compatible with the physical phenomenon using that model, then you might have to look for solutions that involve complex values. You can also double check to see that you have the right model for the job. It is all too easy to select the wrong model.

I can take a look at your data more closely a little later and see if i can find some values that might get you started. I would have to ask though if you have done any curve fitting before using the least squares technique. If so, you may be able to rig up your own program, if you have done any programming.

In short though, you need to enter a range for 'b' that does not produce a negative value in (x-b) or else you'll get a complex number and for now i will assume you dont want that. If that doesnt work then you either have the wrong model statement for the physical phenomenon or you have to see if you can find a way to use the complex results that you get from raising a negative number up to a fractional power, or you have to limit the range of the constant 'c', but since 'c' may have to vary by fractional increments in the algorithm then you may be limited to setting the range of 'b' properly. When you do these you usually have to try values that are reasonable for the model and physical phenomenon.

[LATER]
Your 'y' data varies by a ratio of roughly 1:1e7 and this may cause numerical problems with any regular algorithm made for a regular PC computer without extended precision.
It does however look like the transformation to the natural log system could help because it limits the range to a ratio of about 1:17 which of cousre is much better. Whether or not this causes a problem when transforming back though would have to be seen by trial.
So to try this you would take your original model statement:
y=a*(x-b)^c

and take the log of both sides:
log(y)=c*log(x-b)+log(a)

and perhaps convert A=log(a) and get:
log(y)=c*log(x-b)+A

and convert Y=log(Y) and get:
Y=c*log(x-b)+A

and this is your new model statement, and your data then transforms as:
(x,y)=>(x,log(y))

and that becomes your new fit data.

Hopefully that helps I think this is just a conformal mapping like log(z) but with only the real part of 'z'. Whatever the case though, doing this often helps when the data is spread out by a wide ratio.

I also realize now that some algorithms dont have a range setting, only an initial value setting. This is not only strange but i dont know how to deal with that because the algorithms i've always used i wrote myself and always had a range setting so that you can control the spread of any constant as the calculations were taking place.
For example, if i was using y=1/x and of course want to eliminate the possibility of x=0, then i would set the range to maybe x=0.001 to x=100, or something similar. Other times it helps to remove that point altogether and use points from the left of the y axis such as x=-1 and that way we can get values that resemble the point at x=0 even though they dont fit the data exactly. So in other words, the point where x=0 is treated as an outlier.

Last edited: