Plotting an implicit function in Matlab - matlab

I have a function of 4 variables, let us say $f(x,t,w,n)$, the function $g(x,n)$ is defined as
g(x,n)=\int_a^b\int_c^d f(x,t,w,n) dt dw
where $a$, $b$, $c$, $d$ are given constants and the integral cannot be explicitly computed in a closed form. Then, $h(x,n)$ is given by
h(x,n)=\ln\frac{g(x,n)}{g(-x,n)}
I want to ploy $y=h(x,n)$ as a function of $x$ for different values of $n$ on the same plot. How can I do this. If it helps, $f(x,t,w,n)$ is of the following form
f(x,t,w,n)=\exp{-\frac{x^2+tw+wx}{n}}+\exp{-\frac{t^2+tx^2-2tx}{2n}}

I think this probably does what you want. I specify f, g, and h as anonymous functions and use the quad2d to estimate the value of the double integral.
%% Input bounds
a = 0;
b = 1;
c = 0;
d = 2;
%% Specify functions
% vectorize function as a prerequisite to using in quad2d
f = #(x,t,w,n) exp( -(x.^2 + t.*w + w.*x)./n) + exp(-(t.^2 + t.*x.^2 - 2.*t.*x)./(2.*n));
% keeps x,n fixed in function call to f(...), varies a < t < b; c < w < d
g = #(x,n) quad2d(#(t,w) f(x, t, w, n), a, b, c, d);
% wrap functions into h
h = #(x,n) log(g(x,n)/g(-x,n));
%%
figure();
hold on % keep lines
x_range = linspace(-1,1);
for n = 1:5
plotMe = zeros(1, length(x_range));
for iter = 1:length(x_range)
plotMe(iter) = h(x_range(iter), n);
end
lineHandle(n) = plot(x_range, plotMe);
end
legend(lineHandle, {
['N: ', num2str(1)],...
['N: ', num2str(2)],...
['N: ', num2str(3)],...
['N: ', num2str(4)],...
['N: ', num2str(5)]...
}...
)

Related

Changing amplitude of fourier series in matlab

The code below currently plots the fourier series for a square wave for N terms. Is there any way I could change the range from [0;1] to [-1;1]?
% Assignment of variables
syms t
% Function variables
N = 5;
T0 = 1;
w0 = 2*pi/T0;
Imin = 0;
Imax = 0.5;
% Function
ft = 1;
% First term calculation
a0 = (1/T0)*int(ft, t, Imin, Imax);
y = a0;
% Calculation of n terms
for n = 1:N
an = (2/T0)*int(ft*cos(n*w0*t), t, Imin, Imax);
bn = (2/T0)*int(ft*sin(n*w0*t), t, Imin, Imax);
y = y + an*cos(n*w0*t) + bn*sin(n*w0*t);
end
fplot(y, [-4,4], "Black")
grid on
If you are talking about the figure scale, then ylim([-1 1])
1.- The following does what you asked for:
clear all;clc;close all
syms t
assume(t>0 & t<1)
% Function variables
N = 5;
T0 = 1;
w0 = 2*pi/T0;
Imin = 0;
Imax = 1;
% Function
h1=heaviside(t-.5)
h2=heaviside(t+.5)
ht=-2*((h1-h2)+.5)
% First term calculation
a0 = (1/T0)*int(ht, t, Imin, Imax);
y = a0;
% Calculation of n terms
for n = 1:N
an = (2/T0)*int(ht*cos(n*w0*t), t, Imin, Imax);
bn = (2/T0)*int(ht*sin(n*w0*t), t, Imin, Imax);
y = y + an*cos(n*w0*t) + bn*sin(n*w0*t);
end
fplot(y, [-4,4], "Black")
grid on
2.- You allocate a specific group of code lines headed with % Function to precisely define the function.
Yet you actually define the function with Imin and Imax.
It's good practice to constrain the function definition within the lines you intend for such purpose, not to scatter the function all over the place.

Preventing using for loop in MATLAB

I have written the below MATLAB code. I want to know how can I optimize it without using for loop.
Any help will be very appreciated.
MATLAB code:
%Some parameters:
s = 50;
k = 50;
r = 0.1;
v = 0.2;
t = 2;
n=10000;
% Calculate CT by calling EurCall function
CT = EurCall(s, k, r, v, t, n);
%Function EurCall to be called
function C = EurCall(s, k, r, v, t, n)
X = zeros(n,1);
hh = zeros(n,1);
for ii = 1 : n
X(ii) = normrnd(0, 1);
SS = s*exp((r - v^2/2)*t + v*X(ii)*sqrt(t));
hh(ii) = exp(-r*t)*max(SS - k, 0);
end %end for loop
C = (1/n) * sum(hh);
end %end function
Vectorized Approach:
Here is a vectorized approach that I think replicates the same functionality as the original script. Instead of looping this example declares X as a vector of size n by 1. By using element-wise multiplication .* we can effectively calculate the remaining vectors SS and hh without need to loop through the indices. In this case SS and hh will also be vectors of size n by 1. I do agree with comment above that MATLAB's for-loops are no longer inherently slow.
%Some parameters:
s = 50;
k = 50;
r = 0.1;
v = 0.2;
t = 2;
n=10000;
% Calculate CT by calling EurCall function
[CT] = EurCall(s, k, r, v, t, n);
%Function EurCall to be called
function [C] = EurCall(s, k, r, v, t, n)
X = zeros(n,1);
hh = zeros(n,1);
mu = 0; sigma = 1;
%Creating a vector of normal random numbers of size (n by 1)%
X = normrnd(mu,sigma,[n 1]);
SS = s*exp((r - v^2/2)*t + v.*X.*sqrt(t));
hh = exp(-r*t)*max(SS - k, 0);
C = (1/n) * sum(hh);
end %end function
Ran using MATLAB R2019b

Error using feval Undefined function or variable 'Sfun'

I have always used R, so I am quite new to Matlab and running into some troubleshooting issues. I am running some code for a tensor factorization method (available here: https://github.com/caobokai/tBNE). To start I tried to run the demo code, which generates simulated data to run the method with, which results in the following error(s):
Error using feval
Undefined function or variable 'Sfun'.
Error in OptStiefelGBB (line 199)
[F, G] = feval(fun, X , varargin{:}); out.nfe = 1;
Error in tbne_demo>tBNE_fun (line 124)
S, #Sfun, opts, B, P, X, L, D, W, Y, alpha, beta);
Here is the block of code I am running:
clear
clc
addpath(genpath('./tensor_toolbox'));
addpath(genpath('./FOptM'));
rng(5489, 'twister');
m = 10;
n = 10;
k = 10; % rank for tensor
[X, Z, Y] = tBNE_data(m, n, k); % generate the tensor, guidance and label
[T, W] = tBNE_fun(X, Z, Y, k);
[~, y1] = max(Y, [], 2);
[~, y2] = max(T{3} * W, [], 2);
fprintf('accuracy %3.2e\n', sum(y1 == y2) / n);
function [X, Z, Y] = tBNE_data(m, n, k)
B = randn(m, k);
S = randn(n, k);
A = {B, B, S};
X = ktensor(A);
Z = randn(n, 4);
Y = zeros(n, 2);
l = ceil(n / 2);
Y(1 : l, 1) = 1;
Y(l + 1 : end, 2) = 1;
X = tensor(X);
end
function [T, W] = tBNE_fun(X, Z, Y, k)
% t-BNE computes brain network embedding based on constrained tensor factorization
%
% INPUT
% X: brain networks stacked in a 3-way tensor
% Z: side information
% Y: label information
% k: rank of CP factorization
%
% OUTPUT
% T is the factor tensor containing
% vertex factor matrix B = T{1} and
% subject factor matrix S = T{3}
% W is the weight matrix
%
% Example: see tBNE_demo.m
%
% Reference:
% Bokai Cao, Lifang He, Xiaokai Wei, Mengqi Xing, Philip S. Yu,
% Heide Klumpp and Alex D. Leow. t-BNE: Tensor-based Brain Network Embedding.
% In SDM 2017.
%
% Dependency:
% [1] Matlab tensor toolbox v 2.6
% Brett W. Bader, Tamara G. Kolda and others
% http://www.sandia.gov/~tgkolda/TensorToolbox
% [2] A feasible method for optimization with orthogonality constraints
% Zaiwen Wen and Wotao Yin
% http://www.math.ucla.edu/~wotaoyin/papers/feasible_method_matrix_manifold.html
%% set algorithm parameters
printitn = 10;
maxiter = 200;
fitchangetol = 1e-4;
alpha = 0.1; % weight for guidance
beta = 0.1; % weight for classification loss
gamma = 0.1; % weight for regularization
u = 1e-6;
umax = 1e6;
rho = 1.15;
opts.record = 0;
opts.mxitr = 20;
opts.xtol = 1e-5;
opts.gtol = 1e-5;
opts.ftol = 1e-8;
%% compute statistics
dim = size(X);
normX = norm(X);
numClass = size(Y, 2);
m = dim(1);
n = dim(3);
l = size(Y, 1);
D = [eye(l), zeros(l, n - l)];
L = diag(sum(Z * Z')) - Z * Z';
%% initialization
B = randn(m, k);
P = B;
S = randn(n, k);
S = orth(S);
W = randn(k, numClass);
U = zeros(m, k); % Lagrange multipliers
%% main loop
fit = 0;
for iter = 1 : maxiter
fitold = fit;
% update B
ete = (S' * S) .* (P' * P); % compute E'E
b = 2 * ete + u * eye(k);
c = 2 * mttkrp(X, {B, P, S}, 1) + u * P + U;
B = c / b;
% update P
ftf = (S' * S) .* (B' * B); % compute F'F
b = 2 * ftf + u * eye(k);
c = 2 * mttkrp(X, {B, P, S}, 2) + u * B - U;
P = c / b;
% update U
U = U + u * (P - B);
% update u
u = min(rho * u, umax);
% update S
tic;
[S, out] = OptStiefelGBB(...
S, #Sfun, opts, B, P, X, L, D, W, Y, alpha, beta);
tsolve = toc;
fprintf(...
['[S]: obj val %7.6e, cpu %f, #func eval %d, ', ...
'itr %d, |ST*S-I| %3.2e\n'], ...
out.fval, tsolve, out.nfe, out.itr, norm(S' * S - eye(k), 'fro'));
% update W
H = D * S;
W = (H' * H + gamma * eye(k)) \ H' * Y;
% compute the fit
T = ktensor({B, P, S});
normresidual = sqrt(normX ^ 2 + norm(T) ^ 2 - 2 * innerprod(X, T));
fit = 1 - (normresidual / normX);
fitchange = abs(fitold - fit);
if mod(iter, printitn) == 0
fprintf(' Iter %2d: fitdelta = %7.1e\n', iter, fitchange);
end
% check for convergence
if (iter > 1) && (fitchange < fitchangetol)
break;
end
end
%% clean up final results
T = arrange(T); % columns are normalized
fprintf('factorization error %3.2e\n', fit);
end
I know that there is little context here, but my suspicion is that I need to have Simulink, as Sfun is a Simulink related function(?). The script requires two toolboxes: tensor_toolbox, and FOptM.
Available at:
https://www.sandia.gov/~tgkolda/TensorToolbox/index-2.6.html
https://github.com/andland/FOptM
Thank you so much for your help,
Paul
Although SFun is an often used abbreviation for a Simulink S-Function, in this case the error has nothing to do with Simulink, and the name is a coincidence. (There is no Simulink related function specifically called Sfun, it is just a general term.)
Your error message has #Sfun in it, which is a way in MATLAB of creating a function handle to an (m-code) function called Sfun. I'd summize from the code you've shown that this is a cost function used in the optimization.
If you look at the code that your code is based on (tBNE_fun.m) you'll see that there is a function at the end of the file called Sfun. It is this that you are missing.

Unable to create 3D function using mesh

So I have a script which executes coordinate descent algorithm for a quadratic function. I also created a function to make different plots, this is the first part I add. The code executes without any error, but I'm unable to see the surface, I can only see the path of my algorithm descending.
The function updater:
function [f,delta] = fcalculator (Q, x0, c, p)
a = size(x0);
n = a(2);
f = (x0*Q*x0') - (c * x0') + p ;
delta = (Q*x0')- c';
endfunction
The main program:
clear all, close all,
fprintf(' 0 = probleme specifique \n 1 = probleme random \n 2 = Tapez votre propre probleme\n')
choix = input ('Choix : ');
n=0;
if (choix == 0)
[Q, x0, c, p] = quadfunctiongenerator(n,choix)
maxiter = input ( 'Nombre de iterations :');
[x, z] = coordinatedescent(Q,c,p,x0,maxiter);
visualizer(x, z, Q, c, p);
else
n = input ('Choix des dimensions: n = ');
[Q, x0, c, p] = quadfunctiongenerator(n,choix);
endif
The module to create the plots:
function [x1, x2, fuf] = visualizer(x, z, Q, c, p)
clf;
% Pour le cas le plus general, apres on fera:
% iters = 1:size(x)(1);
% plot(iters,x(:,1))
if size(x)(2)
% Afficher les iterees:
plot3(x(:,1), x(:,2), z)
hold on;
% fcalculator (Q, x0, c, p)
% Display the function's surface:
%% Calculate limits:
x1_low = x(1,1);
x1_hi = x(size(x)(1),1) + x1_low;
x2_low = x(1,2);
x2_hi = x(size(x)(1),2) + x2_low;
% Resolution will be the number of points:
resolution = 100;
x1 = (linspace(x1_low, x1_hi, resolution))';
x2 = (linspace(x2_low, x2_hi, resolution))';
f = [];
[xx, yy] = meshgrid (x1, x2);
for i=1:resolution
for j=1:resolution
[_tmp, _] = fcalculator(Q, [x1(i),x2(j)], c, p);
f(i,j) = _tmp;
endfor
endfor
_string = sprintf('%d ', size(x1));
fprintf('Answer: %s\n', _string);
_string = sprintf('%d ', size(x2));
fprintf('Answer: %s\n', _string);
_string = sprintf('%d ', size(f));
fprintf('Answer: %s\n', _string);
mesh(x1, x2, f);
endif
endfunction
I believe the problem is my call to mesh() as I didn't use the variables xx and yy created when calling meshgrid() but the dimensions of x1, x2 and f are the same as those of the variables used to create the famous sombrero plot:
tx = ty = linspace (-8, 8, 41)';
[xx, yy] = meshgrid (tx, ty);
r = sqrt (xx .^ 2 + yy .^ 2) + eps;
tz = sin (r) ./ r;
mesh (tx, ty, tz);
Am I supposed to create f as an elementwise operation as shown in the sombrero plot example?
Is there any octave function to help me create the surface of the function I am optimizing?
I found the problem. The call to mesh() was correct. The problem was the definition of the boundaries.
x1_low = x(1,1);
x1_hi = x(size(x)(1),1) + x1_low;
x2_low = x(1,2);
x2_hi = x(size(x)(1),2) + x2_low;
Yielded x1_low == x1_hi. The code was replaced with:
x1_low = min(x(:,1));
x1_hi = max(x(:,1));
x2_low = min(x(:,2));
x2_hi = max(x(:,2));
Which yielded the desired surface.

How to deal with recursive loop in MATLAB?

I am trying to compute x1^i * x2^j * x3^k * ......
This is my code so far:
for l = 1:N
f = 1;
for i = 0:2
for j = 0:2-i
for k = 0:2-j
for m = 0:2-k
g(l,f) = x1(l)^i*x2(l)^j*x3(l)^k*x4(l)^m;
f = f+1;
end
end
end
end
end
How can I do this easier or without a loop?
I do not have MATLAB on hand here, but what I'd do is make a vector X = [x1, x2, ..., xn] of bases and a vector P = [i, j, k, ..., z] of powers, and then compute prod(power(X, P)).
power() does an element-wise power function, and prod takes the product of every element in the vector.