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
Related
I am trying to write a function which takes the value x and y in cartesian coordinates as the input and outputs the polar and trigonometric forms. I would like the output to contain the exponential and sin/cos rather than the actual value. For example, if the cartesian is z=1i, I would like the function to output z=sqrt(2)e^(ipi/4) and z=sqrt(2)(cos(pi/4)+Isin(pi/4). How can I do this?
function coordinates(x,y)
r=sqrt(x.^2+y.^2);
theta=atan(y./x);
polarcoord=rexp(itheta)
trigcoord=r*(cos(theta)+i*sin(theta))
end
This gives me the following output :
polarcoord =
1.0000 + 1.0000i
trigcoord =
1.0000 + 1.0000i
thanks
Welcome to SO! You are using functions (sqrt(x) calculates the actual square root of x, exp(x) the exponential, ... So that is why you get the actual value, not the formula expression.
So, a possible way to output the formula is using strings to print the functions without calling them. Then, what you need to do is calculate the values you want inside the sqrt() and the fraction which * pi and add them to a string array. We can do that using square brackets [ ], the function num2string() and the operator + to add strings in the same string array:
function coordinates(x,y)
[num,dem] = rat(atan(y./x)/pi);
% rat converts theta to fraction
% divide by pi to extract pi from theta
root = ["sqrt(" + num2str(x^2+y^2) + ")"]; % i.e "sqrt(2)"
pi_value = ["(" + num2str(num) + "*pi/" + num2str(dem) + ")"];
% i.e "(1*pi/4)" o "(2*pi/5)"...
polarcoord = ["z = " + root + "e^(i" + pi_value]
trigcoord = ["z = " + root + "(cos" + pi_value + ")+i*sin" + pi_value]
end
Example:
coordinates(1,1)
Outputs:
polarcoord = "z = sqrt(2)e^(i(1*pi/4)"
trigcoord = "z = sqrt(2)(cos(1pi/4))+isin(1*pi/4)"
To calculate the fraction we use rat() function to obtain numerator and denominator from the double output of atan(y./x) and we divide by pi to extract its value from the theta value (we are representing pi already in the string).
I want to plot the Lorentz system (s=10, r=28, b=8/3) for a start condition which should give 0 since it's a start condition in the plane spanned by v1 and v2 and trough the critical point (0,0,0) (equation of the plane : -x + (-9- \sqrt(1201))/56 * y = 0) When I use the Runge-Kutta method to plot the solution with as start conditions ((-9-sqrt(1201))/56,1,10) my graph doesn't converge to 0 and I don't know why.
[X,Y,Z,T] = Runge(T0,(-9-sqrt(1201))/56,1,10,h,1000);
plot(T,X);
plot(T,Y);
plot(T,Z);
I expect a solution in which the lines in the plots go to 0. But I get some random function which goes up and down all the time.
Could this be caused by approximations?
Thanks in advance
This is the function Runge
function [X,Y,Z,T] = Runge(t0,x0,y0,z0,h,n)
X=[x0];
Y=[y0];
Z=[z0];
T=[t0];
k1x = 0;
k1y = 0;
k1z = 0;
k2x=0;
k2y=0;
k2z=0;
k3x=0;
k3y=0;
k3z=0;
k4x=0;
k4y=0;
k4z=0;
for k = 1:n
T(k+1)= T(k) +h;
k1x = F(X(k),Y(k),Z(k));
k1y = G(X(k),Y(k),Z(k));
k1z = H(X(k),Y(k),Z(k));
k2x = F(X(k)+h/2*k1x,Y(k) + h/2*k1y, Z(k) + h/2*k1z);
k2y= G(X(k)+h/2*k1x,Y(k) + h/2*k1y, Z(k) + h/2*k1z);
k2z= H(X(k)+h/2*k1x,Y(k) + h/2*k1y, Z(k) + h/2*k1z);
k3x= F(X(k)+h/2*k2x,Y(k)+h/2*k2y,Z(k) + h/2*k2z);
k3y=G(X(k)+h/2*k2x,Y(k)+h/2*k2y,Z(k) + h/2*k2z);
k3z=H(X(k)+h/2*k2x,Y(k)+h/2*k2y,Z(k) + h/2*k2z);
k4x= F(X(k)+h*k3x,Y(k)+h*k3y,Z(k)+h*k3z);
k4y=G(X(k)+h*k3x,Y(k)+h*k3y,Z(k)+h*k3z);
k4z=H(X(k)+h*k3x,Y(k)+h*k3y,Z(k)+h*k3z);
X(k+1) = X(k) + h/6 * (k1x + 2*k2x + 2*k3x + k4x);
Y(k+1) = Y(k) + h/6 * (k1y + 2*k2y + 2*k3y + k4y);
Z(k+1) = Z(k) + h/6 * (k1z + 2*k2z + 2*k3z + k4z);
end
end
There is no such plane for the non-linear system
Why do you think this plane is invariant?
In the system
F=#(x,y,z) sigma*(y-x);
G=#(x,y,z) x*(rho-z)-y;
H=#(x,y,z) x*y-beta*z;
no non-trivial linear combination of the first two equations is independent of z, which would be required to get an invariant expression in only x and y.
The invariant sub-spaces of the linearization are close to the stable and unstable manifolds, but they are not identical to them. So if you are on some invariant subspace of the linearization, you are in fact some distance away from any curved sub-manifolds related to the non-linear system, and numerical as well as exact solutions will move towards the chaotic attractor.
The Lorentz system is chaotic
Apart from that your observation is correct that floating point errors accumulate to drive the numerical solution away from the exact solution and any properties of it.
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.
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.
This is easy to do in OpenCV however I would like a native Matlab implementation that is fairly efficient and can be easily changed. The method should be able to take the camera parameters as specified in the above link.
The simplest and most common way of doing undistort (also called unwarp or compensating for lens distortion) is to do a forward distortion on a chosen output photo size and then a reverse mapping using bilinear interpolation.
Here is code I wrote for performing this:
function I = undistort(Idistorted, params)
fx = params.fx;
fy = params.fy;
cx = params.cx;
cy = params.cy;
k1 = params.k1;
k2 = params.k2;
k3 = params.k3;
p1 = params.p1;
p2 = params.p2;
K = [fx 0 cx; 0 fy cy; 0 0 1];
I = zeros(size(Idistorted));
[i j] = find(~isnan(I));
% Xp = the xyz vals of points on the z plane
Xp = inv(K)*[j i ones(length(i),1)]';
% Now we calculate how those points distort i.e forward map them through the distortion
r2 = Xp(1,:).^2+Xp(2,:).^2;
x = Xp(1,:);
y = Xp(2,:);
x = x.*(1+k1*r2 + k2*r2.^2) + 2*p1.*x.*y + p2*(r2 + 2*x.^2);
y = y.*(1+k1*r2 + k2*r2.^2) + 2*p2.*x.*y + p1*(r2 + 2*y.^2);
% u and v are now the distorted cooridnates
u = reshape(fx*x + cx,size(I));
v = reshape(fy*y + cy,size(I));
% Now we perform a backward mapping in order to undistort the warped image coordinates
I = interp2(Idistorted, u, v);
To use it one needs to know the camera parameters of the camera being used.
I am currently using the PMD CamboardNano which according to the Cayim.com forums has the parameters used here:
params = struct('fx',104.119, 'fy', 103.588, 'cx', 81.9494, 'cy', 59.4392, 'k1', -0.222609, 'k2', 0.063022, 'k3', 0, 'p1', 0.002865, 'p2', -0.001446);
I = undistort(Idistorted, params);
subplot(121); imagesc(Idistorted);
subplot(122); imagesc(I);
Here is an example of the output from the Camboard Nano. Note: I artificially added border lines to see what the effect was of the distortion close to the edges (its much more pronounced):
You can now do that as of release R2013B, using the Computer Vision System Toolbox. There is a GUI app called Camera Calibrator and a function undistortImage.