Matlab: Computations with the translations of a function - matlab

Before the question, thank you for reading this post.
I have defined a real function, f= #(x) sin(x) + x.^2 and I want to store the N translates of f from 0 to N-1, in a vector w. I mean, I want to store the vector w=( sin(x) + x.^2 , ...., sin(x- (N-1)) + (x-(N-1)).^2)
I have a vector, v, of N real numbers.
Question: How to get the inner product, u, of v and w? I want to store it as a function because I want to calculate the FFT coefficients of u.
I'm trying to do this with a loop but I'm making a mess with the loop/s.
Would you help me, please?
Many thanks.
What I did with the help of #m7913d:
%%%code
N=10;
v=rand(1,N);%%vector
tras=1:N;
tsi=t.*ones(1,N);
%%ff(x)=sin(x)+x.^2
ff=sin(tsi+tras) +(tsi+tras).^2 ;
total=sum(ff.*v,2);
vpa(subs(total,t,0.1));%%check
Fs=100;% Sampling frequency
tt=-pi:1/Fs:pi;% Time vector
L=length(tt); % Signal length
X=double(subs(total, t,tt));
n=2^nextpow2(L);
coef=fft(X,n);

You can generate a cell array of functions as follows:
N = 10;
f= #(x) sin(x) + x.^2;
u = cell(N, 1);
v = rand(N, 1);
g = 0;
for i=0:(N-1)
u{i+1} = #(x) v(i+1)*f(x + i);
g = #(x) g(x) + u{i+1}(x);
end
Note that I calculated the u vector at once, without using the intermediate variable w.
Note that the calculations will be easier (and faster) if you immediately insert your desired x vector. In that case, you do not have to hassle with function handles.

The question is solved. Here is the code
%%%code
N=10;
v=rand(1,N);%%vector
tras=1:N;
tsi=t.*ones(1,N);
%%ff(x)=sin(x)+x.^2
ff=sin(tsi+tras) +(tsi+tras).^2 ;
total=sum(ff.*v,2);
vpa(subs(total,t,0.1));%%check
Fs=100;% Sampling frequency
tt=-pi:1/Fs:pi;% Time vector
L=length(tt); % Signal length
X=double(subs(total, t,tt));
n=2^nextpow2(L);
coef=fft(X,n);
Thanks to everyone for your help.

Related

Natural cubic spline function in MATLAB

I am trying to write a MATLAB function which interpolates data points in X to create a natural cubic spline, similar to interp1 but without using interp1. The function takes inputs vector x and c (from the system Ac=Y) and vector X of data points that I want to interpolate.
My function is almost complete, I have put the system in matrix form, found the y values, coefficients a,b,c and d but I do not know how to evaluate the X values to get my estimated value Y.
For example, this is what I have at the moment:
%cubic spline interpolation
n = length(x);
N = length(X);
Y = zeros(size(X));
for i = 1:n-1
for j = 1:N
while x(i) <= X(j) && x(i+1) >= X(j)
Y(j) = a(i)*(X(j)^3) + b(i)*(X(j)^2) + c(i)*X(j) + d(i);
break
end
end
end
My question is why does this not work? I know interp1 does not find the natural spline but I am very new to MATLAB so I was just using this built-in function as a reference as to how the graph should look and my function is just completely wrong. I hope that makes some sense. Any help would be great.

Using MATLAB to write a function that implements Newton's method in two dimensions

I am trying to write a function that implements Newton's method in two dimensions and whilst I have done this, I have to now adjust my script so that the input parameters of my function must be f(x) in a column vector, the Jacobian matrix of f(x), the initial guess x0 and the tolerance where the function f(x) and its Jacobian matrix are in separate .m files.
As an example of a script I wrote that implements Newton's method, I have:
n=0; %initialize iteration counter
eps=1; %initialize error
x=[1;1]; %set starting value
%Computation loop
while eps>1e-10&n<100
g=[x(1)^2+x(2)^3-1;x(1)^4-x(2)^4+x(1)*x(2)]; %g(x)
eps=abs(g(1))+abs(g(2)); %error
Jg=[2*x(1),3*x(2)^2;4*x(1)^3+x(2),-4*x(2)^3+x(1)]; %Jacobian
y=x-Jg\g; %iterate
x=y; %update x
n=n+1; %counter+1
end
n,x,eps %display end values
So with this script, I had implemented the function and the Jacobian matrix into the actual script and I am struggling to work out how I can actually create a script with the input parameters required.
Thanks!
If you don't mind, I'd like to restructure your code so that it is more dynamic and more user friendly to read.
Let's start with some preliminaries. If you want to make your script truly dynamic, then I would recommend that you use the Symbolic Math Toolbox. This way, you can use MATLAB to tackle derivatives of functions for you. You first need to use the syms command, followed by any variable you want. This tells MATLAB that you are now going to treat this variable as "symbolic" (i.e. not a constant). Let's start with some basics:
syms x;
y = 2*x^2 + 6*x + 3;
dy = diff(y); % Derivative with respect to x. Should give 4*x + 6;
out = subs(y, 3); % The subs command will substitute all x's in y with the value 3
% This should give 2*(3^2) + 6*3 + 3 = 39
Because this is 2D, we're going to need 2D functions... so let's define x and y as variables. The way you call the subs command will be slightly different:
syms x, y; % Two variables now
z = 2*x*y^2 + 6*y + x;
dzx = diff(z, 'x'); % Differentiate with respect to x - Should give 2*y^2 + 1
dzy = diff(z, 'y'); % Differentiate with respect to y - Should give 4*x*y + 6
out = subs(z, {x, y}, [2, 3]); % For z, with variables x,y, substitute x = 2, y = 3
% Should give 56
One more thing... we can place equations into vectors or matrices and use subs to simultaneously substitute all values of x and y into each equation.
syms x, y;
z1 = 3*x + 6*y + 3;
z2 = 3*y + 4*y + 4;
f = [z1; z2];
out = subs(f, {x,y}, [2, 3]); % Produces a 2 x 1 vector with [27; 25]
We can do the same thing for matrices, but for brevity I won't show you how to do that. I will defer to the code and you can see it then.
Now that we have that established, let's tackle your code one piece at a time to truly make this dynamic. Your function requires the initial guess x0, the function f(x) as a column vector, the Jacobian matrix as a 2 x 2 matrix and the tolerance tol.
Before you run your script, you will need to generate your parameters:
syms x y; % Make x,y symbolic
f1 = x^2 + y^3 - 1; % Make your two equations (from your example)
f2 = x^4 - y^4 + x*y;
f = [f1; f2]; % f(x) vector
% Jacobian matrix
J = [diff(f1, 'x') diff(f1, 'y'); diff(f2, 'x') diff(f2, 'y')];
% Initial vector
x0 = [1; 1];
% Tolerance:
tol = 1e-10;
Now, make your script into a function:
% To run in MATLAB, do:
% [n, xout, tol] = Jacobian2D(f, J, x0, tol);
% disp('n = '); disp(n); disp('x = '); disp(xout); disp('tol = '); disp(tol);
function [n, xout, tol] = Jacobian2D(f, J, x0, tol)
% Just to be sure...
syms x, y;
% Initialize error
ep = 1; % Note: eps is a reserved keyword in MATLAB
% Initialize counter
n = 0;
% For the beginning of the loop
% Must transpose into a row vector as this is required by subs
xout = x0';
% Computation loop
while ep > tol && n < 100
g = subs(f, {x,y}, xout); %g(x)
ep = abs(g(1)) + abs(g(2)); %error
Jg = subs(J, {x,y}, xout); %Jacobian
yout = xout - Jg\g; %iterate
xout = yout; %update x
n = n + 1; %counter+1
end
% Transpose and convert back to number representation
xout = double(xout');
I should probably tell you that when you're doing computation using the Symbolic Math Toolbox, the data type of the numbers as you're calculating them are a sym object. You probably want to convert these back into real numbers and so you can use double to cast them back. However, if you leave them in the sym format, it displays your numbers as neat fractions if that's what you're looking for. Cast to double if you want the decimal point representation.
Now when you run this function, it should give you what you're looking for. I have not tested this code, but I'm pretty sure this will work.
Happy to answer any more questions you may have. Hope this helps.
Cheers!

Making a function in terms of a sum from 1 to n in Matlab

I'm trying to get Matlab to take this as a function of x_1 through x_n and y_1 through y_n, where k_i and r_i are all constants.
So far my idea was to take n from the user and make two 1×n vectors called x and y, and for the x_i just pull out x(i). But I don't know how to make an arbitrary sum in MATLAB.
I also need to get the gradient of this function, which I don't know how to do either. I was thinking maybe I could make a loop and add that to the function each time, but MATLAB doesn't like that.
I don't believe a loop is necessary for this calculation. MATLAB excels at vectorized operations, so would something like this work for you?
l = 10; % how large these vectors are
k = rand(l,1); % random junk values to work with
r = rand(l,1);
x = rand(l,1);
y = rand(l,1);
vals = k(1:end-1) .* (sqrt(diff(x).^2 + diff(y).^2) - r(1:end-1)).^2;
sum(vals)
EDIT: Thanks to #Amro for correcting the formula and simplifying it with diff.
You can solve for the gradient symbolically with:
n = 10;
k = sym('k',[1 n]); % Create n variables k1, k2, ..., kn
x = sym('x',[1 n]); % Create n variables x1, x2, ..., xn
y = sym('y',[1 n]); % Create n variables y1, y2, ..., yn
r = sym('r',[1 n]); % Create n variables r1, r2, ..., rn
% Symbolically sum equation
s = sum((k(1:end-1).*sqrt((x(2:end)-x(1:end-1)).^2+(y(2:end)-y(1:end-1)).^2)-r(1:end-1)).^2)
grad_x = gradient(s,x) % Gradient with respect to x vector
grad_y = gradient(s,y) % Gradient with respect to y vector
The symbolic sum and gradients can be evaluated and converted to floating point with:
% n random data values for k, x, y, and r
K = rand(1,n);
X = rand(1,n);
Y = rand(1,n);
R = rand(1,n);
% Substitute in data for symbolic variables
S = double(subs(s,{[k,x,y,r]},{[K,X,Y,R]}))
GRAD_X = double(subs(grad_x,{[k,x,y,r]},{[K,X,Y,R]}))
GRAD_Y = double(subs(grad_y,{[k,x,y,r]},{[K,X,Y,R]}))
The gradient function is the one overloaded for symbolic variables (type help sym/gradient) or see the more detailed documentation online).
Yes, you could indeed do this with a loop, considering that x, y, k, and r are already defined.
n = length(x);
s = 0;
for j = 2 : n
s = s + k(j-1) * (sqrt((x(j) - x(j-1)).^2 + (y(j) - y(j-1)).^2) - r(j-1)).^2
end
You should derive the gradient analytically and then plug in numbers. It should not be too hard to expand these terms and then find derivatives of the resulting polynomial.
Vectorized solution is something like (I wonder why do you use sqrt().^2):
is = 2:n;
result = sum( k(is - 1) .* abs((x(is) - x(is-1)).^2 + (y(is) - y(is-1)).^2 - r(is-1)));
You can either compute gradient symbolically or rewrite this code as a function and make a standard +-eps calculation. If you need a gradient to run optimization (you code looks like a fitness function) you could use algorithms that calculate them themselves, for example, fminsearch can do this

Calling generic functions on rows of a matrix

I'd like to compute kernel matrices efficiently for generic kernel functions in
Matlab. This means I need to compute k(x,y) for every row x of X
and every row y of Y. Here is some matlab code that computes what I'd
like, but it is rather slow,
function K=compute_kernel( k_func, X, Y )
m = size(X,1);
n = size(Y,1);
K = zeros(m,n);
for i = 1:m
for j = 1:n
K(i,j) = k_func(X(i,:)', Y(j,:)');
end
end
end
Is there any other approach to this problem, e.g. some bsxfun variant that
calls a function on every row taken from X and Y?
pdist2(X,Y, dist_func) unfortunately computes dist_func(X, Y(i,:)), instead of dist_func(X(i,:), Y(i,:)). So the actual function I need is,
function K=compute_kernel( k_func, X, Y )
% Woohoo! Efficient way to compute kernel
size(X)
size(Y)
m = size(X,1);
n = size(Y,1);
for i = 1:n
K(:,i) = pdist2( Y(i,:), X, k_func);
end
It's not as nice as just using pdist2, but is still much more efficient than the previous case.
Have you tired pdist2 with custom distance function?
P.S.
It is best not to use i and j as variables in Matlab

Auto-covariance and Cross Covariance Function in Matlab without using imbuilt functions

x and y are 1x100000 vectors.
I have calculated the mean and variance of x and y. When I want to calculate the autocovariance and cross covariance function the simulation lasts maybe 5 minutes because of my loops. It is not allowed to use xcorr, xcov, mean, cov, var etc.
Please help me.
Thanks in advance.
%%Mean of Vector x
Nx=length(x);
mx= sum(x)/Nx;
%%Mean of Vector y
Ny=length(y);
my=sum(y)/Ny;
%%Variance of x
varx=0;
for i=1:Nx
varx=varx+(abs(x(i)-mx)^(2));
end
varx=varx/Nx;
%%Variance of y
vary=0;
for j=1:Ny
vary=vary+(abs(y(j)-my)^(2));
end
vary=vary/Ny;
%%Auto-Covariance function of x
for k=1:Nx
Cxx(k)=0;
for i=1:(Nx-k+1)
Cxx(k)=Cxx(k)+(x(i+k-1)-mx)*conj((x(i)-my));
end
end
%%Auto-Covariance function of y
for s=1:Ny
Cyy(s)=0;
for j=1:(Ny-s+1)
Cyy(s)=Cyy(s)+(y(j+s-1)-my)*conj((y(j)-mx));
end
end
Use the fact that FFT(corr(x, y)) = FFT(x) * conj(FFTy)):
corrxy = ifft(fft(x) .* conj(fft(y)));
corrxy = [corrxy(end - length(x) + 2:end); corrxy(1:length(x))];
To get the cross-covariance just multiply the correlation by the standard deviations:
covarxy = corrxy * sqrt(varx) * sqrt(vary);
To get the autocovariance, compute the cross covariance between x and itself.
Doing a re-write of this code:
%%Auto-Covariance function of x
for k=1:Nx
Cxx(k)=0;
for i=1:(Nx-k+1)
Cxx(k)=Cxx(k)+(x(i+k-1)-mx)*conj((x(i)-my));
end
end
The following code takes out the inner for-loop:
% x is a [Nx x 1] vector (lets say Nx = 50)
Cxx = zeros(Nx,1); % [Nx x 1] vector of zeros
for k = 1:Nx,
a = (x(k:Nx) -mx); % If k=3, then x(3:50) and a is [Nx-k+1 x 1]
b = (x(1:Nx-k+1)-my); % If k=3, then x(1:48) and b is [Nx-k+1 x 1]
Cxx(k) = a'*conj(b); % Cxx(k) is always 1x1. (*) is a matrix multiply
end
Since x is a really large vector, and the way to take out the the last for-loop for k=1:Nx is to make a [Nx x Nx] matrix, I'm going to leave it at the above answer for now. Plus, if you have the parfor function in the Parallel Computing Toolbox then you can parallelize it to make it run even faster.