After loading, a pre-fitted surface (sfit) model is something like in the following figure.
Question: How can I obtain the precise mean/std (not by tedious copying from the output) of x/y data from the sfit object?
Remarks:
I am able to get all the coefficients by calling its coeffnames/coeffvalues APIs. However it seems there's no similar API for the mean/std.
The original data that the sfit model is fit from is not accessible currently. So the method relying on the original data is not applicable.
Looking at the source of the sfit class, it turns out that the means and standard deviations are stored in private properties meanx, meany, stdx, stdy. The fact that these are private makes the job non-trivial, but thanks to Yair Altman we know that calling struct() on a class usually reveals all its goodness.
Using the slightly modified example from the sfit documentation,
x = 3 - 6 * rand( 49, 1 );
y = 3 - 6 * rand( 49, 1 );
z = peaks( x, y );
sf = fit( [x, y], z, 'poly32', 'normalize', 'on');
here's what we see:
>> sf
Linear model Poly32:
sf(x,y) = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p30*x^3 +
p21*x^2*y + p12*x*y^2
where x is normalized by mean -0.3736 and std 1.887
and where y is normalized by mean -0.04893 and std 1.644
Coefficients (with 95% confidence bounds):
p00 = 0.4227 (-0.3731, 1.218)
p10 = 1.764 (0.5627, 2.965)
p01 = 1.313 (0.7715, 1.855)
p20 = -0.1054 (-0.6496, 0.4389)
p11 = 0.4627 (0.03944, 0.8859)
p02 = 0.1898 (-0.2443, 0.6239)
p30 = -0.6345 (-1.247, -0.02209)
p21 = -0.8263 (-1.32, -0.3327)
p12 = -0.4908 (-1.011, 0.02911)
>> sf_struct=struct(sf)
Warning: Calling STRUCT on an object prevents the object from hiding its implementation details and should thus be avoided. Use DISP or
DISPLAY to see the visible public details of an object. See 'help struct' for more information.
sf_struct =
version: 2
fCoeffValues: {[0.4227] [1.7639] [1.3130] [-0.1054] [0.4627] [0.1898] [-0.6345] [-0.8263] [-0.4908]}
fProbValues: {1x0 cell}
sse: 59.5574
dfe: 40
rinv: [9x9 double]
activebounds: [9x1 logical]
meanx: -0.3736
meany: -0.0489
stdx: 1.8875
stdy: 1.6441
xlim: [-2.8236 2.8090]
ylim: [-2.7585 2.6763]
fType: 'poly32'
fTypename: 'Poly32'
fCategory: 'library'
defn: 'p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p30*x^3 + p21*x^2*y + p12*x*y^2'
fFeval: 1
expr: #polySurface
Adefn: {}
Aexpr: {}
linear: 1
derexpr: #polySurfaceDerivative
intexpr: []
args: [11x3 char]
isEmpty: 0
numArgs: 11
numCoeffs: 9
assignCoeff: [1x234 char]
assignData: ' x = FITTYPE_INPUTS_{10}; y = FITTYPE_INPUTS_{11};'
assignProb: ''
indep: [2x1 char]
depen: 'z'
coeff: [9x3 char]
prob: ''
fConstants: {[3] [2]}
fNonlinearcoeffs: []
fFitoptions: [1x1 curvefit.llsqoptions]
fStartpt: []
>> [sf_struct.meanx, sf_struct.meany, sf_struct.stdx, sf_struct.stdy]
ans =
-0.3736 -0.0489 1.8875 1.6441
At least in R2012b the above works.
Related
I'm looking for finding the coefficients from the Taylor's series in Matlab. The way that I'm doing is:
% Declare symbolic expression and function:
syms x;
f = exp(x);
% Calculate the taylor expansions in a concrete point:
T = taylor(f, x, 0.5);
% And finally I simplify the expression:
coefs = simplify(T)
But the returned expression is:
Yes, the expression it's simplified, but actually what I want is:
Where each term is multiplied by his coefficient. How can I this? Options suchs as simplify(f, x, 0.5, 10, where 10 refers to the simplification step,doesn't work in my case. Also I've been seeing this question and the problem is the same:
How get to simplify a symbolic and numeric mixed expression in Matlab
Depending on how many digits you want and in what exact format you want the result, here is an example:
>> c = double(coeffs(T))
c =
Columns 1 through 4
0.999966624859531 1.000395979357109 0.498051217190664 0.171741799031263
Columns 5 through 6
0.034348359806253 0.013739343922501
>> digits 15
>> x.^(0:numel(c)-1) * sym(c,'d').'
ans =
0.0137393439225011*x^5 + 0.0343483598062527*x^4 + 0.171741799031263*x^3 + 0.498051217190664*x^2 + 1.00039597935711*x + 0.999966624859531
EDIT
Note that you could also use vpa( ) instead of converting to double first:
>> c = coeffs(T)
c =
[ (2329*exp(1/2))/3840, (233*exp(1/2))/384, (29*exp(1/2))/96, (5*exp(1/2))/48, exp(1/2)/48, exp(1/2)/120]
>> x.^(0:numel(c)-1) * vpa(c).'
ans =
0.0137393439225011*x^5 + 0.0343483598062527*x^4 + 0.171741799031263*x^3 + 0.498051217190664*x^2 + 1.00039597935711*x + 0.999966624859531
I performed a surface fit of some data in Matlab using the fit function.
To be more specific:
func_trim= fit( [hopper_volume, water_ballast_volume], trim, 'poly55');
It returned a multi-variable polynomial:
Linear model Poly55:
func_trim(x,y) = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p30*x^3
+ p21*x^2*y + p12*x*y^2 + p03*y^3 + p40*x^4 + p31*x^3*y
+ p22*x^2*y^2 + p13*x*y^3 + p04*y^4 + p50*x^5 + p41*x^4*y
+ p32*x^3*y^2 + p23*x^2*y^3 + p14*x*y^4 + p05*y^5
Coefficients (with 95% confidence bounds):
p00 = -4.742 (-4.745, -4.74)
p10 = 5.068e-05 (4.969e-05, 5.167e-05)
p01 = 0.001447 (0.001436, 0.001459)
p20 = -3.565e-09 (-3.731e-09, -3.399e-09)
p11 = -6.534e-08 (-6.7e-08, -6.369e-08)
p02 = -1.6e-07 (-1.815e-07, -1.385e-07)
p30 = 5.919e-13 (5.795e-13, 6.043e-13)
p21 = 4.683e-12 (4.552e-12, 4.815e-12)
p12 = 1.129e-11 (9.908e-12, 1.267e-11)
p03 = 1.471e-10 (1.282e-10, 1.659e-10)
p40 = -2.017e-17 (-2.059e-17, -1.975e-17)
p31 = -1.562e-16 (-1.611e-16, -1.513e-16)
p22 = -6.93e-16 (-7.444e-16, -6.417e-16)
p13 = -9.909e-16 (-1.551e-15, -4.308e-16)
p04 = -6.751e-14 (-7.516e-14, -5.986e-14)
p50 = 2.446e-22 (2.392e-22, 2.5e-22)
p41 = 2.186e-21 (2.118e-21, 2.254e-21)
p32 = 1.321e-20 (1.243e-20, 1.4e-20)
p23 = 3.805e-20 (2.969e-20, 4.642e-20)
p14 = 2.262e-20 (-6.978e-20, 1.15e-19)
p05 = 1.059e-17 (9.424e-18, 1.175e-17)
I now want to use this object in the simulink environment.
One option would be to explicitly define this in simulink by just hard-coding it in. However I don't prefer this because the coefficients might change (quite frequently) over time and I would have to repeat this every time.
So in short. Are there any more elegant ways to use this object straight in simulink?
The easiest thing to do is to wrap the fit object into a function handle and then call that from an Interpreted MATLAB function block.
To create the function handle:
>> myFunc = #(u)feval(func_trim,u);
Then with the Interpreted MATLAB function block you'll need to
Mux the x and y signals together, then feed the combined signal into the block.
Use "myFunc(u)" - without the double quotes - as the name of the function to call.
The above is not the fastest approach from an execution pespective, nor will it allow for code generation, but it is by far the easiest/quickest to get something up an running.
I have an anonymous function with 10 variables
now I want to evaluate it with data in a p=1x10 matrix like this:
answer=func(p(1),p(2),p(3),p(4),p(5),p(6),p(7),p(8),p(9),p(10))
i don't want to use this, i need something like:
answer=func(p(:))
but it generates error
can anyone give me a solution?
You seem to have some basic misunderstandings using anonymous functions and its syntax.
For what I think you want to do, you basically have three options:
Option 1
Define the function with 10 input parameters and provide 10 input values - OR expand an input array as comma separated list using {:} which requires an intermediate num2cell step:
func1 = #(a,b,c,d,e,f,g,h,i,j) a + b + c + d + e + f + g + h + i + j
p = num2cell(p)
answer = func1(p{:})
Option 2
Define the function with 1 input parameters using an array with 10 values and provide this array:
func2 = #(p) p(1) + p(2) + p(3) + p(4) + p(5) + p(6) + p(7) + p(8) + p(9) + p(10)
answer = func2(p)
Option 3
The last option to use varargin is really case dependent and could look like:
func3 = #(varargin) [varargin{:}]
p = num2cell(p)
answer = func3(p{:})
Is there any way to extract data out of cfit or sfit object? I want to extract matrix of fitted values out of sfit object without accessing to every element of fit (very slow in 240x320 ). Problem is equivalent to extraction of vector out of cfit object. Is there a method defined over this object, or something similar?
Please, post a code!
thanks, Nikola
You can access an element of an sfit object with sfit.element. For example:
sf = fit([x,y],z,'poly23');
sf
Linear model Poly23:
sf(x,y) = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p21*x^2*y
+ p12*x*y^2 + p03*y^3
Coefficients (with 95% confidence bounds):
p00 = 1.118 (0.9149, 1.321)
p10 = -0.0002941 (-0.000502, -8.623e-05)
p01 = 1.533 (0.7032, 2.364)
p20 = -1.966e-08 (-7.084e-08, 3.152e-08)
p11 = 0.0003427 (-0.0001009, 0.0007863)
p02 = -6.951 (-8.421, -5.481)
p21 = 9.563e-08 (6.276e-09, 1.85e-07)
p12 = -0.0004401 (-0.0007082, -0.0001721)
p03 = 4.999 (4.082, 5.917)
To get one element of sf:
sf.p03
ans =
4.9994
I have a function
function y = testf(x,F,phi,M,beta,alpha)
y = -((F+(1 + phi.*cos(2.*pi.*x))).*M.^3.*(cosh((1 + phi.*cos(2.*pi.*x)).*M)+M.*beta.*sinh((1 + phi.*cos(2.*pi.*x)).*M)))./((1 + phi.*cos(2.*pi.*x)).*M.*cosh((1 + phi.*cos(2.*pi.*x)).*M)+(-1+(1 + phi.*cos(2.*pi.*x)).*M.^2.*beta).*sinh((1 + phi.*cos(2.*pi.*x)).*M))- (alpha.*(M.^2.*(F+(1 + phi.*cos(2.*pi.*x))).*(-1+2.*(1 + phi.*cos(2.*pi.*x)).^2.*M.^2+ cosh(2.*(1 + phi.*cos(2.*pi.*x)).*M)-2.*(1 + phi.*cos(2.*pi.*x)).*M.*sinh(2.*(1 + phi.*cos(2.*pi.*x)).*M)))./(8.*((1 + phi.*cos(2.*pi.*x)).*M.*cosh((1 + phi.*cos(2.*pi.*x)).*M)+(-1+(1 + phi.*cos(2.*pi.*x)).*M.^2.*beta).*sinh((1 + phi.*cos(2.*pi.*x)).*M)).^2));
integrating with
q = quad(#(x) testf (x, F, phi,M, beta, alpha), 0, h);
when q = 0 and x,F,phi,M,beta, how do I find alpha and draw the streamline?
It would be great if you gave some numbers, but here is how you would start this. It assumes you are using a version of Matlab that has MuPad as the Symbolic Engine.
First of all, I wouldn't use quad because symbolic expressions will be involved, use int instead.
If I understood you correctly, have the values of x, F, phi, M, beta and you would like to solve for alpha when q = 0
%define the known variables first
syms alpha %defining symbolic object
Now, the following may not work because it's a huge function:
q = int(y,x,0,h)
If it did, all you have to do is solve and evaluate the results for alpha (this may not work as well):
alpha = eval( solve( 'q' , alpha ) )
If the above didn't achieve anything, you might what to look at the 'IgnoreAnalyticConstraints' option.