Add the constraint of normalization coefficient for matlab curve fitting - matlab

I want to use a custom model to fit some data. The syntax I used is fit(). The mathematical model I used has the form of this:
a*exp(-x*b)+c*exp(-y*d)+e*exp(-z*f)
where a,b,c,d,e,f are the parametres I will estimate and x,y,z are independent variables. (The actual mathematical formula is more complicated but something nonlinear like this.)
How can I add the constraint of a+c+e=1 (and a,c,e must be positive or 0) when fitting the curve? I know how to set the lower and upper bound but don't know how to add this normalization coefficient constraint to the fitting. Is it possible to do this when using the fit() method?

I think I already posted this somewhere, but can't find it right now.
As it is a non-linear fit, there is no big deal in transforming the parameters. say we chose the continuously differentiable and monotonic function:
a = f(s) = 1/2 ( 1 + s / sqrt( 1 + s^2 ) )
so for s in (-inf, inf) on gets a in (0,1). Actually, with some simple shifting and scaling we could get any a in ( u, v ).
Now we can do the same for b, but with the additional restriction a + b + c = 1 we know that at most c = 0 and b must definitively be smaller than 1 - f(s) = 1/2 ( 1 - s / sqrt( 1 + s^2 ) ). Now, hence, is the time for scaling and we can set:
b = g(t, s) = 1/2 ( 1 - s / sqrt( 1 + s^2 ) ) 1/2 ( 1 + t / sqrt( 1 + t^2 ) )
again with t in (-inf, inf). The first part is the scaling due to the already set value for a, the second part repeats the procedure from above.
Finally, cis simply 1- f(s) - g(t, s)
Eventually, the fit function with parameters s and t looks like:
+ 0.50 * ( 1 + s / sqrt( 1 + s^2 ) ) * exp( -x * b )
+ 0.25 * ( 1 - s / sqrt( 1 + s^2 ) ) * ( 1 + t / sqrt( 1 + t^2 ) ) * exp( -y * d )
+ (
+1.00
-0.50 * ( 1 + s / sqrt( 1 + s^2 )
-0.25 * ( 1 - s / sqrt( 1 + s^2 ) ) * ( 1 + t / sqrt( 1 + t^2 ) )
) * exp( -z * f )
Getting results for s and t provides a, b and c via error propagation

Related

Confirm that ( x + d/dx ) exp( -x^2 / 2 ) = 0 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have written a small code that is supposed to verify that ( x + d/dx ) exp(-x^2 / 2 ) = 0. The idea is to use a Fourier series exp( 2 * pi j n x / L ) with sufficiently large L to represent the Gaussian and perform the operation there.
The algorithm in Matlab works as follows:
function[] = verify
epsilon = 0.05; % step-size numerical integration
N = 40; % number of Fourier coefficients
L = 30; % window length numerical integration Fourier basis
X = -L / 2:epsilon:L / 2; % grid
xFourier = zeros(2 * N + 1); %Allocate space for Fourier coefficients of f(x)=x
inix = zeros(2 * N + 1); % Allocate space for Fourier coefficients of f(x)=exp(-x^2/2)
% Compute Fourier coefficients of f(x)=x
for i1=-N:N
A = X.*exp(-2 * pi * 1i * i1. * X / L ) / sqrt( L );
xFourier(i1 + ( N + 1 ) ) = trapz( X, A );
end
% Compute Fourier coefficients of f(x)=exp(-x^2/2)
for i1 = -N : N
A = 1 / sqrt(L) * exp(-X.^2 / 2 ). * exp(-2 * pi * 1i * i1. * X / L );
inix( i1 + N + 1 ) = trapz( X, A ); % These are the Fourier coefficients of the |x|^2*Gaussian part
end
TO = Hamilton( N, xFourier, L );
norm( TO * inix' )
end
So the heart of the above algorithm is the function Hamilton that I am calling, it contains the matrix representation of the operator x d/dx, which is why norm( TO * inix' ) should return something close to zero, but it does not(?) and the function Hamilton is as follows
function [ Hamilton ] = Hamilton( N, xFourier, L)
Hamilton = zeros( ( 2 * N + 1 ),( 2 * N + 1 ) );
for i1 = -N : N
for i2 = -N : N
if i1 == i2
Hamilton(
(i1 + ( N + 1 ) ), ( i2 + ( N + 1 ) )
) = Hamilton(
( i1 + ( N + 1)),( i2 + ( N + 1 ) )
) + 1i * 2 * pi / L * i1;
end
if abs( i2 - i1 ) <= N
Hamilton(
( i1 + ( N + 1 ) ), ( i2 + ( N + 1 ) )
) = Hamilton(
(i1 + ( N + 1 ) ), ( i2 + ( N + 1 ) )
) + xFourier( i1 - i2 + ( N + 1 ) );
end
end
end
end
Does anybody see a mistake?
While not into Matlab , I somewhat miss a few terms in the code, like the factor 2 pi j k for the derivative. So here I put a Python version of what I think it should look like (sorry for the Python, but I guess it translates to Matlab quite easily):
import numpy as np
## non-normalized gaussian with sigma=1
def gauss( x ):
return np.exp( -x**2 / 2 )
## interval on which the gaussian is evaluated
L = 10
## number of sampling points
N = 21
## sample rate
dl = L / N
## highest frequency detectable
kmax= 1 / ( 2 * dl )
## array of x values
xl = np.linspace( -L/2, L/2, N )
## array of k values
kl = np.linspace( -kmax, kmax, N )
## matrix of exponents
## the Fourier transform is defined via sum f * exp( -2 pi j k x)
## i.e. the 2 pi is in the exponent
## normalization is sqrt(N) where n is the number of sampling points
## this definition makes it forward-backward symmetric
## "outer" also exists in Matlab and basically does the same
exponent = np.outer( -1j * 2 * np.pi * kl, xl )
## linear operator for the standard Fourier transformation
A = np.exp( exponent ) / np.sqrt( N )
## nth derivative is given via partial integration as ( 2 pi j k)^n f(k)
## every row needs to be multiplied by the according k
B = np.array( [ 1j * 2 * np.pi * kk * An for kk, An in zip( kl, A ) ] )
## for the part with the linear term, every column needs to be multiplied
## by the according x or--as here---every row is multiplied element
## wise with the x-vector
C = np.array( [ xl * An for An in A ] )
## thats the according linear operator
D = B + C
## the gaussian
yl = gauss( xl )
## the transformation with the linear operator
print( np.dot( D, yl ).round( decimals=9 ) )
## ...results in a zero-vector, as expected
provides:
[ 0.+4.61e-07j 0.-3.75e-07j 0.+1.20e-08j 0.+3.09e-07j -0.-5.53e-07j
0.+6.95e-07j -0.-7.28e-07j 0.+6.54e-07j -0.-4.91e-07j -0.+2.62e-07j
-0.+0.00e+00j -0.-2.62e-07j -0.+4.91e-07j -0.-6.54e-07j 0.+7.28e-07j
-0.-6.95e-07j 0.+5.53e-07j -0.-3.09e-07j 0.-1.20e-08j 0.+3.75e-07j
0.-4.61e-07j]
This is basically zero.

HS and LK Robust Optical flow

I am trying to make LK and HS original algorithm robust using Black & Anandan Lorentzian method
I did not know how to apply this concept in my MATLAB code ! ... and when I tried to apply what I know I got worse results than the original HS
I will attach my MATLAB code ... if any one have any idea how to do it ... or where is my mistakes .. I will be appreciate it
this code read 4 gray images (i0, i1, i2, i3)
the actual robustness process in perform_reg_iter ( I tried to applied to data and smoothing term ) but it gives me worse flow than the original method
function [regularized_u,regularized_v]=regularization_robust (i0,i1,i2,i3)
alpha=10.0;
numpass=100;
ROBUST_FLAG = true;
[pic_x, pic_y]=size(i0);
I=cell(1,2);
I{1,1}=double(box_filter(i0,i1,i2));
I{1,2}=double(box_filter(i1,i2,i3));
%Simocelli
[Ix,Iy,It]=apply_Simoncelli_filters(I{1,1},I{1,2});
[row, col]= size(Ix);
%%%caculate the flow %%%%%%
[regularized_u,regularized_v]= calc_intensity_regularization_flow(Ix,Iy,It,alpha,numpass, ROBUST_FLAG);
%%%%% print output
end
function [seq]=box_filter(seq1,seq2,seq3)
box(1)=0.25;
box(2)=0.5;
box(3)=0.25;
seq=box(1)*seq1+box(2)*seq2+box(3)*seq3;
temp=imfilter(seq,box,'same','conv','symmetric');
seq=imfilter(temp,box','same','conv','symmetric');
end % box_filter
function [Ix,Iy,It]=apply_Simoncelli_filters(I1,I2)
It=I2-I1;
gd=[1 -8 0 8 -1]/12;
Ix=-imfilter(I1,gd,'conv','symmetric','same');
Iy=-imfilter(I1,gd','conv','symmetric','same');
end
% Robust function
function [y]= robust_functions (type, x, sigma, order)
switch (type)
case 'lorentzian'
switch (order)
case 0
y = log(1 + x.^2 / (2 * sigma^2));
case 1
y = 2 * x ./ (2 * sigma^2 + x.^2);
if (2 * sigma^2 + x.^2) ==0
y = 100;
end
case 2
y = 2 ./ (2 * sigma^2 + x.^2);
end
case 'quadratic'
switch (order)
case 0
y = x.^2 / sigma^2;
case 1
y = 2 * x / sigma^2;
case 2
y = repmat(2 / sigma^2, size(x));
end
otherwise
error('Invalid robust function type.');
end
end
function [regularized_u,regularized_v]=...
calc_intensity_regularization_flow(Ix,Iy,It,alpha,numpass,ROBUST_FLAG)
regularized_u=zeros(size(Ix),'double');
regularized_v=zeros(size(Iy),'double');
% Perform iterations
for iter_no=0:2:numpass
[u2,v2]=perform_reg_iter(regularized_u,regularized_v,...
Ix,Iy,It,alpha,ROBUST_FLAG);
[regularized_u,regularized_v]=perform_reg_iter(u2,v2,Ix,Iy,It,...
alpha,ROBUST_FLAG);
end
end
function [u,v]=perform_reg_iter(u,v,Ix,Iy,It,alpha,ROBUST_FLAG)
kernel_1=[1/12 1/6 1/12;1/6 0 1/6;1/12 1/6 1/12];
estimator_weight=0.0;
robust_type= 'lorentzian'; % 'lorentzian'; % charbonnier
% (0) original ... (1) first derivative ... (2) 2 ./ (2 * sigma^2 + x.^2)
% in Sun paper
robust_order=2;
uAvg=conv2(u,kernel_1,'same');
vAvg=conv2(v,kernel_1,'same');
if (ROBUST_FLAG)
% Smoothing term
% robust_sigma =1; %0.03 in Sun paper
%uAvg = feval('robust_functions',robust_type,uAvg,robust_sigma,robust_order);
%vAvg = feval('robust_functions',robust_type,vAvg,robust_sigma,robust_order);
%Data term
robust_sigma=0.01; % 1.5 in Sun paper
value = Ix.*u + Iy.*v + It;
estimator_weight =
feval('robust_functions',robust_type,value,robust_sigma,robust_order);
Ix= Ix.* estimator_weight;
Iy= Iy.* estimator_weight;
It= It.* estimator_weight;
end
u= uAvg - ( Ix .* ( ( Ix .* uAvg ) + ( Iy .* vAvg ) + It ) ) ./ ...
( alpha^2 + Ix.^2 + Iy.^2);
v= vAvg - ( Iy .* ( ( Ix .* uAvg ) + ( Iy .* vAvg ) + It ) ) ./ ...
( alpha^2 + Ix.^2 + Iy.^2);
end
Without Robust calculation I got this results
with the robust I got this result

Matlab - Creating two arrays that consider all possible values for two objects

I have two physical "objects." I am representing their positions with two different arrays.
• Object 1 moves in the xy-plane only
• Object 2 moves in all three physical dimensions
Objective: Vectorize the four for loops without distorting the data. Also, the intent is to perform this operation for all possible values of object 1 to be compared with object 2.
Here is the code snippet:
Npos = 21;
Nsam = 200;
% dummy initialisation
AX = rand(1, Npos);
AY = zeros(1, Npos);
AZ = rand(1, Npos);
Bx = rand(Nsam);
By = rand(Nsam);
Bz = rand(Nsam);
for qx = 1 : Npos
for yx = 1 : Npos
for zx = 1 : Nsam
for cx = 1 : Nsam
Tx2Array( qx, yx, zx, cx ) = sqrt( ( AX( qx ) - Bx( zx, cx ) ).^2 + ( AY( yx ) - By( zx, cx ) ).^2 + ( AZ( yx ) - Bz( zx, cx ) ).^2 );
end
end
end
end
% Result is a 21 x 21 x 200 x 200 matrix filled with all real numbers
Legend
AX, AY, AZ are 1 x 21 arrays and represent the (x,y=0,z) of Object 1
AY is all zeros, but for readability is still included (hence no fifth loop!)
Bx, By, Bz are all 200 x 200 arrays and represent the (x,y,z) of Object 2
Npos = 21; Nsam = 200;
The formula used above is:
sqrt( (a1-b1)^2 + (a2-b2)^2 + (a3-b3)^2 )
If you have the Statistics Toolbox available, you can use pdist2 to calculate the distance between each coordinate for Object 1 and each coordinate for Object 2:
[X1, Z1] = ndgrid(AX(:), AZ(:)); % X1 and Z1 will be 21x21
D = pdist2([X1(:), zeros(size(X1(:))), Z1(:)], [Bx(:), By(:), Bz(:)]);
The output in this case will be a 441 x 40,000 array where D(i, j) gives you the distance between point i of Object 1 and point j of Object 2, both using linear indexing.
You can avoid the to inner loops by replacing zx and cx with : as follows:
Tx2Array = zeros(Npos, Npos, Nsam, Nsam); % preallocate memory
for qx = 1 : Npos
for yx = 1 : Npos
Tx2Array( qx, yx, :, : ) = sqrt( ( AX( qx ) - Bx( :, : ) ).^2 + ( AY( yx ) - By( :, : ) ).^2 + ( AZ( yx ) - Bz( :, : ) ).^2 );
end
end
In this way, the largest dimensions are vectorised. So, the largest improvement is already done.
By converting your B* to 4D and generating a mesh for your A* matrices, you can even remove all the for loops as follows:
[AX_, AZ_] = meshgrid(AX, AZ);
AX_ = AX_';
AZ_ = AZ_';
AY_ = zeros(Npos);
Bx_(1, 1, :, :) = Bx;
By_(1, 1, :, :) = By;
Bz_(1, 1, :, :) = Bz;
Tx2Array2 = sqrt( ( AX_ - Bx_ ).^2 + ( AY_ - By_ ).^2 + ( AZ_ - Bz_ ).^2 );
You can check the the results are the same using the following check:
max(max(max(max(abs(Tx2Array - Tx2Array2))))) < eps
If the arrays are correctly initialized your task will be very simple:
Initialize the arrays with the correct dimensions
AX = rand( Npos,1);
AY = zeros(1, Npos);
AZ = rand(1, Npos);
Bx = rand(1,1,Nsam,Nsam);
By = rand(1,1,Nsam,Nsam);
Bz = rand(1,1,Nsam,Nsam);
Then in MATLAB r2016b / Octave you can simply write:
Tx2Array = sqrt( ( AX - Bx ).^2 + ( AY - By ).^2 + ( AZ - Bz ).^2 );
In pre r2016b you can use bsxfun:
Tx2Array = sqrt(bsxfun(#plus,bsxfun(#plus,bsxfun(#minus,AX , Bx).^2,bsxfun(#minus,AY , By).^2),bsxfun(#minus,AZ , Bz).^2));

program runs differently depending on the use of cos or cosd( matlab functions)

My Matlab program works properly when the angles are in radians and thus I call cos and sin functions in the code below. When the angles are in degrees and thus I call cosd and sind, my program doesn't work as expected.
%Initial configuration of robot manipulator
%There are 7DOF( degrees of freedom) - 1 prismatic, 6 revolute
%vector qd represents these DOF
%indexes : d = gd( 1), q1 = qd( 2), ..., q6 = qd( 7)
qd( 1) = 1; % d = 1 m
qd( 2) = pi / 2; % q1 = 90 degrees
qd( 3 : 6) = 0; % q2 = ... = q6 = 0 degrees
qd( 7) = -pi / 2;
%Initial position of each joint - the tool is manipulated separately
%calculate sinusoids and cosines
[ c, s] = sinCos( qd( 2 : length( qd)));
and here is the sinCos code
function [ c, s] = sinCos( angles)
%takes a row array of angles in degrees and returns all the
%sin( angles( 1) + angles( 2) + ... + angles( i)) and
%cos( angles( 1) + angles( 2) + ... + angles( i)) where
%1 <= i <= length( angles)
sum = 0;
s = zeros( 1, length( angles)); % preallocate for speed
c = zeros( 1, length( angles));
for i = 1 : length( angles)
sum = sum + angles( i);
s( i) = sin( sum); % s( i) = sin( angles( 1) + ... + angles( i))
c( i) = cos( sum); % c( i) = cos( angles( 1) + ... + angles( i))
end % for
% end function
The whole program is ~ 700 lines, so I displayed only the part above. My program simulates the motion of a redundant robot that tries to reach a goal while avoiding two obstacles.
So, does my problem relates to cos and cosd? Do cos and cosd have a different behavior that affects my program? Or I have a bug in my program that is revealed?
By difference, do you mean something on the order of less than .00001? Because extremely small errors can be discounted due to floating point arithmetic errors. Computers are not able to accurately calculate decimal numbers with as much accuracy as they are able to store them. It is for this reason you should never directly compare two floating-point numbers; a range of error must be allowed for. You can read more about this here: http://en.wikipedia.org/wiki/Floating_point#Machine_precision_and_backward_error_analysis
If your error is greater than .0001 or so, you might consider searching for a bug in your program. If you are not already using matlab to convert units for you, consider doing so as I have found that it can eliminate many 'obvious' errors (and in some cases increase precision).

Gabor Phase ?? my values are too small

Hi every one >> hope you all are doing fine
I wanted to ask you about calculating the phase values for an image ,, you see I used the Gabor wavlet like so :
k = ( Kmax / ( f ^ v ) ) * exp( 1i * u * pi / 8 );% Wave Vector
kn2 = ( abs( k ) ) ^ 2;
GW = zeros ( R , C );
for m = -R/2 + 1 : R/2
for n = -C/2 + 1 : C/2
GW(m+R/2,n+C/2) = ( kn2 / Delt2 ) * exp( -0.5 * kn2 * ( m ^ 2 + n ^ 2 ) / Delt2) * ( exp( 1i * ( real( k ) * m + imag ( k ) * n ) ) - exp ( -0.5 * Delt2 ) );
end
end
I=imread('a.pgm');
Myimage=conv2(I,double(GW),'same');
then I called the image and the filter with different orientations and scales and stored the phase in P then I wanted to quantize it with rang 4 i:
close all;
clear all;
clc;
% Parameter Setting
R = 32;
C = 32;
Kmax = pi;
f = sqrt( 2 );
Delt = 2 * pi;
Delt2 = Delt * Delt;
% Show the Gabor Wavelets
for v=1:7 %v = 1 : 7
for u = 1:5 % u= 1: 5
[GW,Myimage]= GaborWavelet ( R, C, Kmax, f, u, v, Delt2 ); % Create the Gabor wavelets
figure;
subplot( 5, 8, v * 7 + u ),imshow ( real( GW ) ,[]); % Show the real part of Gabor wavelets
end
figure ;
subplot( 1, 5, v + 1 ),imshow ( abs( GW ),[]); % Show the magnitude of Gabor wavelets
end
%clear I;
R=real(GW);
I=imag(GW);
M=abs(Myimage);
P=atan(imag(Myimage)/real(Myimage)); <<<< is this even right ??
%P=atan(I/R);
save P P;
[xx,yy] = size (P);
DATA =zeros(size(P));
for i=1:48
for j=1:48
for zz=1:3
if (360* zz/4) <= abs(P(i,j))&& abs(P(i,j))<(360*(zz+1)/4)
DATA(i,j)=zz ; end;
end;
end;
end;
save DATA DATA ;
But the data is so small like : -1.49279186693682 1.50990968797986 -1.39225915272978 0.966151874072431
which leads to quantized value of 0 >> Where did I go wrong
I think values seem small because they are given in radians and you expect them in degrees. As for getting the magnitude and angle of a complex number, take a look at http://www.mathworks.fr/fr/help/matlab/ref/angle.html.
I quote:
"For complex Z, the magnitude R and phase angle theta are given by
R = abs(Z)
theta = angle(Z)"
Z would be your GW.
Hope this helps!