Output Argument Not Assigned During Call: Matlab - matlab

I am attempting to generate 2500 psuedo-random numbers using LCG for a project. However, when I attempt to run the code I continuously receive the error "Output argument 'p' (and maybe others) not assigned during call to lcgg'.". I was hoping someone could help me understand why p is not in the output and how I can fix this?
clear;
clc;
M = 2500;
ID = 801201076;
disp('N = '); disp(mod(ID,3));
[A,p1] = lcgg(M,30269,171,0,1);
[B,p2] = lcgg(M,30307,172,0,1);
[C,p3] = lcgg(M,30323,170,0,1);
disp('Period = '); disp(p2);
% Combine the 3 generators as in Wichmann and Hill
figure(1);
subplot(2,1,1);hist(B);title('Histogram for Uniform RDN from LCG');
subplot(2,1,2);qqplot(rand(300,1),B);title('QQplot for uniform RDN from LCG');
figure(2);
scatter(B(1:(M-1),1),B(2:M,1),4);title('Plot of sequential pairs for LCG');
D = A + B + C - fix(A + B + C); % internal Matlab uniform random number generator
u = rand(M,1); % internal Matlab uniform random number generator
figure(3);
subplot(2,1,1);scatter(u(1:(M-1),1),u(2:M,1),4);title('Plot of Sequential Pairs for Matlab Internal Generator');
subplot(2,1,2);scatter(D(1:M-1),1),D(2:M,1),4;title('Plot of sequential pairs for 3 LCG Combined')
% Calculate the period
i = 1;
j = 2;
while A(i,1) ~= A(j,1) && i < m
if j < m
j = j+1;
else
i = i+1;
j = j+1;
end
end
if i == m
p = m;
else
p = j-1;
end
A = A./m;
if M <= m
A = A(1:M,:);
end
function[A,p] = lcgg(M,m,a,c,x0)
% Generates a matrix of random numbers using lcg
% Calculate the period
% Input: M: total number of random numbers needed
% m, a, x, x0
% Output: A: M * 1 matrix of random numbers
% p: period of the LCG random number generator
A = zeros(m,1);
for i = 1:m
if i == 1
A(i,1) = lcg(m,a,c,x0);
else
A(i,1) = lcg(m,a,c,A(i-1,1));
end
end
end
% The LCG Function:
function[x] = lcg(m,a,c,x0)
% Linear Congruential Generator (LCG)
x = mod(a*x0+c, m);
end

You define a function:
function[A,p] = lcgg(...)
Within the function body you need to assign a value to both output variables, A and p. You don’t assign anything to p, hence the message.

Related

how run kmean algorithm on sift keypoint in matlab

I need to run the K-Means algorithm on the key points of the Sift algorithm in MATLAB .I want to cluster the key points in the image but I do not know how to do it.
First, put the key points into X with x coordinates in the first column and y coordinates in the second column like this
X=[reshape(keypxcoord,numel(keypxcoord),1),reshape(keypycoord,numel(keypycoord),1))]
Then if you have the statistical toolbox, you can just use the built in 'kmeans' function lik this
output = kmeans(X,num_clusters)
Otherwise, write your own kmeans function:
function [ min_group, mu ] = mykmeans( X,K )
%MYKMEANS
% X = N obervations of D element vectors
% K = number of centroids
assert(K > 0);
D = size(X,1); %No. of r.v.
N = size(X,2); %No. of observations
group_size = zeros(1,K);
min_group = zeros(1,N);
step = 0;
%% init centroids
mu = kpp(X,K);
%% 2-phase iterative approach (local then global)
while step < 400
%% phase 1, batch update
old_group = min_group;
% computing distances
d2 = distances2(X,mu);
% reassignment all points to closest centroids
[~, min_group] = min(d2,[],1);
% recomputing centroids (K number of means)
for k = 1 : K
group_size(k) = sum(min_group==k);
% check empty group
%if group_size(k) == 0
assert(group_size(k)>0);
%else
mu(:,k) = sum(X(:,min_group==k),2)/group_size(k);
%end
end
changed = sum(min_group ~= old_group);
p1_converged = changed <= N*0.001;
%% phase 2, individual update
changed = 0;
for n = 1 : N
d2 = distances2(X(:,n),mu);
[~, new_group] = min(d2,[],1);
% recomputing centroids of affected groups
k = min_group(n);
if (new_group ~= k)
mu(:,k)=(mu(:,k)*group_size(k)-X(:,n));
group_size(k) = group_size(k) - 1;
mu(:,k)=mu(:,k)/group_size(k);
mu(:,new_group) = mu(:,new_group)*group_size(new_group)+ X(:,n);
group_size(new_group) = group_size(new_group) + 1;
mu(:,new_group)=mu(:,new_group)/group_size(new_group);
min_group(n) = new_group;
changed = changed + 1;
end
end
%% check convergence
if p1_converged && changed <= N*0.001
break;
else
step = step + 1;
end
end
end
function d2 = distances2(X, mu)
K = size(mu,2);
N = size(X,2);
d2 = zeros(K,N);
for j = 1 : K
d2(j,:) = sum((X - repmat(mu(:,j),1,N)).^2,1);
end
end
function mu = kpp( X,K )
% kmeans++ init
D = size(X,1); %No. of r.v.
N = size(X,2); %No. of observations
mu = zeros(D, K);
mu(:,1) = X(:,round(rand(1) * (size(X, 2)-1)+1));
for k = 2 : K
% computing distances between centroids and observations
d2 = distances2(X, mu(1:k-1));
% assignment
[min_dist, ~] = min(d2,[],1);
% select new centroids by selecting point with the cumulative dist
% value (distance) larger than random value (falls in range between
% dist(n-1) : dist(n), dist(0)= 0)
rv = sum(min_dist) * rand(1);
for n = 1 : N
if min_dist(n) >= rv
mu(:,k) = X(:,n);
break;
else
rv = rv - min_dist(n);
end
end
end
end

How to solve the "Array indices must be positive integers or logical values" when using optimization toolbox?

I am trying to implement this optimization problem through optimization toolbox:
where N = 60 files and K = 130 users when 1/K ≤ M ≤ t∗N/K, for which t∗ =3.
so I wrote this code:
clear all;
close all;
clc;
N=60;
t=3;
K=130;
for M=0:0.1:1.4
r=zeros(size(1:M));
f=le(1/K,M);
c=le(M,3*N/K);
if f || c
R2 = #(s) -(s-(s./ floor(N./s)).*M);
LB = 1;
UB = min(N, K);
options = optimoptions('fmincon','Algorithm','interior-point'); % run interior-point algorithm
[sopt, ropt] = fmincon(R2,1,[],[],[],[],LB,UB,[],options);
r(M) = -ropt;
end
end
plot(0:1.4,r(M),'r-','LineWidth',2);
xlabel('Cache Capacity (M)');
ylabel('Delivery Rate (R)');
However the output should be as shown in the graph the one of cut-set bound
The error is as follows:
Array indices must be positive integers or logical values.
Error in try (line 17)
r(M) = -ropt;
First define r outside of the for loop
r =zeros(size(0:0.1:1.4));
To index r inside the for loop you need integer, M is a float Number.
you can just define an additional index i
Also you don't need to specify r indices while plotting if you want
to plot the entire array, and remember to keep the abscissa as
0:0.1:1.4
The code is as follow
N=60;
t=3;
K=130;
i = 0;
r = zeros(size(0:0.1:1.4));
for M=0:0.1:1.4
i = i+1;
f=le(1/K,M);
c=le(M,3*N/K);
if f || c
R2 = #(s) -(s-(s./ floor(N./s)).*M);
LB = 1;
UB = min(N, K);
options = optimoptions('fmincon','Algorithm','interior-point'); % run interior-point algorithm
[sopt, ropt] = fmincon(R2,1,[],[],[],[],LB,UB,[],options);
r(i) = -ropt;
end
end
plot(0:0.1:1.4,r,'r-','LineWidth',2);
xlabel('Cache Capacity (M)');
ylabel('Delivery Rate (R)');
Alternatively you just can predefine all M elements as M = 0:0.1:1.4, then loop around using integer index, that can be used also in indexing r
The corresponding code is as follow
N=60;
t=3;
K=130;
M = 0:0.1:1.4;
r = zeros(size(M));
for i = 1:length(M)
f=le(1/K,M(i));
c=le(M(i),3*N/K);
if f || c
R2 = #(s) -(s-(s./ floor(N./s)).*M(i));
LB = 1;
UB = min(N, K);
options = optimoptions('fmincon','Algorithm','interior-point'); % run interior-point algorithm
[sopt, ropt] = fmincon(R2,1,[],[],[],[],LB,UB,[],options);
r(i) = -ropt;
end
end
plot(0:0.1:1.4,r,'r-','LineWidth',2);
xlabel('Cache Capacity (M)');
ylabel('Delivery Rate (R)');
Graph

MATLAB: Not Enough Input Arguements

I've attempted to run this code multiple times and have had zero luck since I added in the last for loop. Before the error, the vector k wouldn't update so the vector L was the same number repeated.
I can't figure out why I am getting the 'Not enough input arguments' error when it was working fine beforehand.
Any help would be much appreciated!
% Set up parameters of the functions
omega = 2*pi/10; % 1/s
g = 9.81; % m/s^2
h = 20; % m
parms = [omega, g, h];
% Set up the root finding variables
etol = 1e-6; % convergence criteria
iter = 100; % maximum number of iterations
f = #my_fun; % function pointer to my_func
fp = #my_fprime; % function pointer to my_fprime
k0 = kguess(parms); % initial guess for root
% Find the root
[k, error, n_iterations] = newtraph(f, fp, k0, etol, iter, parms);
% Get the wavelength
if n_iterations < iter
% Converged correctly
L = 2 * pi / k;
else
% Did not converge
disp('ERROR: Maximum number of iterations exceeded')
return
end
wave = load('wavedata.dat');
dt = 0.04; %s
%dh = 0.234; %water depth in meters
wave = wave*.01; %covnverts from meters to cm
nw = wave([926:25501],1);
a = length(nw);
t = 0;
spot = 1;
points = zeros(1,100);
for i = 1:a-1
t=t+dt;
if nw(i) < 0
if nw(i+1) > 0
points(spot)=t;
spot=spot+1;
t=0;
end
end
end
omega = 2*pi./points; %w
l = length(points);
L = zeros(1,509);
k = zeros(1,509);
for j = 1:l
g = 9.81; % m/s^2
h = 0.234; % m
parms = [omega(j), g, h];
% Set up the root finding variables
etol = 1e-6; % convergence criteria
iter = 100; % maximum number of iterations
f = #my_fun; % function pointer to my_func
fp = #my_fprime; % function pointer to my_fprime
k0(j) = kguess(parms); % initial guess for root
% Find the root
[k(j), error, n_iterations] = newtraph(f, fp, k0(j), etol, iter, parms);
% Get the wavelength
if n_iterations < iter
% Converged correctly
L(j) = 2 * pi / k(j);
else
% Did not converge
disp('ERROR: Maximum number of iterations exceeded')
return
end
end
function [ f ] = my_fun(k,parms)
%MY_FUN creates a function handle for linear dispersion
% Detailed explanation goes here
w = parms(1) ;
g = parms(2);
h = parms(3);
f = g*k*tanh(k*h)-(w^2);
end
function [ fp ] = my_fprime(k,parms)
%MY_FPRIME creates a function handle for first derivative of linear
% dispersion.
g = parms(2);
h = parms(3);
% w = 2*pi/10; % 1/s
% g = 9.81; % m/s^2
% h = 20; % m
fp = g*(k*h*((sech(k*h)).^2) + tanh(k*h));
end
function [ k, error, n_iterations ] = newtraph( f, fp, k0, etol, iterA, parms )
%NEWTRAPH Estimates the value of k using the newton raphson method.
if nargin<3,error('at least 3 input arguments required'),end
if nargin<4|isempty(etol),es=etol;end
if nargin<5|isempty(iterA),maxit=iterA;end
iter = 0;
k = k0;
%func =#f;
%dfunc =#fp;
while (1)
xrold = k;
k = k - f(k)/fp(k);
iter = iter + 1;
if k ~= 0, ea = abs((k - xrold)/k) * 100; end
if ea <= etol | iter >= iterA, break, end
end
error = ea;
n_iterations = iter;
end
In function newtraph at line 106 (second line in the while(1) loop), you forgot to pass parms to the function call f:
k = k - f(k)/fp(k);
should become
k = k - f(k,parms)/fp(k,parms);

Error in FDM for a coupled PDEs

Here is the code which is trying to solve a coupled PDEs using finite difference method,
clear;
Lmax = 1.0; % Maximum length
Wmax = 1.0; % Maximum wedth
Tmax = 2.; % Maximum time
% Parameters needed to solve the equation
K = 30; % Number of time steps
n = 3; % Number of space steps
m =30; % Number of space steps
M = 2;
N = 1;
Pr = 1;
Re = 1;
Gr = 5;
maxn=20; % The wave-front: intermediate point from which u=0
maxm = 20;
maxk = 20;
dt = Tmax/K;
dx = Lmax/n;
dy = Wmax/m;
%M = a*B1^2*l/(p*U)
b =1/(1+M*dt);
c =dt/(1+M*dt);
d = dt/((1+M*dt)*dy);
%Gr = gB*(T-T1)*l/U^2;
% Initial value of the function u (amplitude of the wave)
for i = 1:n
if i < maxn
u(i,1)=1.;
else
u(i,1)=0.;
end
x(i) =(i-1)*dx;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for j = 1:m
if j < maxm
v(j,1)=1.;
else
v(j,1)=0.;
end
y(j) =(j-1)*dy;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k = 1:K
if k < maxk
T(k,1)=1.;
else
T(k,1)=0.;
end
z(k) =(k-1)*dt;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Value at the boundary
%for k=0:K
%end
% Implementation of the explicit method
for k=0:K % Time loop
for i=1:n % Space loop
for j=1:m
u(i,j,k+1) = b*u(i,j,k)+c*Gr*T(i,j,k+1)+d*[((u(i,j+1,k)-u(i,j,k))/dy)^(N-1)*((u(i,j+1,k)-u(i,j,k))/dy)]-d*[((u(i,j,k)-u(i,j-1,k))/dy)^(N-1)*((u(i,j,k)-u(i,j-1,k))/dy)]-d*[u(i,j,k)*((u(i,j,k)-u(i-1,j,k))/dx)+v(i,j,k)*((u(i,j+1,k)-u(i,j,k))/dy)];
v(i,j,k+1) = dy*[(u(i-1,j,k+1)-u(i,j,k+1))/dx]+v(i,j-1,k+1);
T(i,j,k+1) = T(i,j,k)+(dt/(Pr*Re))*{(T(i,j+1,k)-2*T(i,j,k)+T(i,j-1,k))/dy^2-Pr*Re{u(i,j,k)*((T(i,j,k)-T(i-1,j,k))/dx)+v(i,j,k)*((T(i,j+1,k)-T(i,j,k))/dy)}};
end
end
end
% Graphical representation of the wave at different selected times
plot(x,u(:,1),'-',x,u(:,10),'-',x,u(:,50),'-',x,u(:,100),'-')
title('graphs')
xlabel('X')
ylabel('Y')
But I am getting this error
Subscript indices must either be real positive integers or logicals.
I am trying to implement this
with boundary conditions
Can someone please help me out!
Thanks
To be quite honest, it looks like you started with something that's way over your head, just typed everything down in one go without thinking much, and now you are surprised that it doesn't work...
In the future, please break down problems like these into waaaay smaller chunks that you can individually plot, check, test, etc. Better yet, try simpler problems first (wave equation, heat equation, ...), gradually working your way up to this.
I say this so harshly, because there were quite a number of fairly basic things wrong with your code:
you've used braces ({}) and brackets ([]) exactly as they are written in the equation. In MATLAB, braces are a constructor for a special container object called a cell array, and brackets are used to construct arrays and matrices. To group things like in the equation, you always have to use parentheses (()).
You had quite a number of parentheses wrong, which became apparent when I re-grouped and broke up those huge unintelligible lines into multiple lines that humans can actually read with understanding
you forgot to take the absolute values in the 3rd and 4th terms of u
you looped over k = 0:K and j = 1:m and then happily index everything with k and j-1. MATLAB is 1-based, meaning, the first element of anything is element 1, and indexing with 0 is an error
you've initialized 3 vectors u, v and T, but then index those in the loop as if they are 3D arrays
Now, I've managed to come up with the following code, which runs OK and at least more or less agrees with the equations shown. But I think it still doesn't make much sense because I get only zeros out (except for the initial values).
But, with this feedback, you should be able to correct any problems left.
Lmax = 1.0; % Maximum length
Wmax = 1.0; % Maximum wedth
Tmax = 2.; % Maximum time
% Parameters needed to solve the equation
K = 30; % Number of time steps
n = 3; % Number of space steps
m = 30; % Number of space steps
M = 2;
N = 1;
Pr = 1;
Re = 1;
Gr = 5;
maxn = 20; % The wave-front: intermediate point from which u=0
maxm = 20;
maxk = 20;
dt = Tmax/K;
dx = Lmax/n;
dy = Wmax/m;
%M = a*B1^2*l/(p*U)
b = 1/(1+M*dt);
c = dt/(1+M*dt);
d = dt/((1+M*dt)*dy);
%Gr = gB*(T-T1)*l/U^2;
% Initial value of the function u (amplitude of the wave)
u = zeros(n,m,K+1);
x = zeros(n,1);
for i = 1:n
if i < maxn
u(i,1)=1.;
else
u(i,1)=0.;
end
x(i) =(i-1)*dx;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
v = zeros(n,m,K+1);
y = zeros(m,1);
for j = 1:m
if j < maxm
v(1,j,1)=1.;
else
v(1,j,1)=0.;
end
y(j) =(j-1)*dy;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
T = zeros(n,m,K+1);
z = zeros(K,1);
for k = 1:K
if k < maxk
T(1,1,k)=1.;
else
T(1,1,k)=0.;
end
z(k) =(k-1)*dt;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Value at the boundary
%for k=0:K
%end
% Implementation of the explicit method
for k = 2:K % Time loop
for i = 2:n % Space loop
for j = 2:m-1
u(i,j,k+1) = b*u(i,j,k) + ...
c*Gr*T(i,j,k+1) + ...
d*(abs(u(i,j+1,k) - u(i,j ,k))/dy)^(N-1)*((u(i,j+1,k) - u(i,j ,k))/dy) - ...
d*(abs(u(i,j ,k) - u(i,j-1,k))/dy)^(N-1)*((u(i,j ,k) - u(i,j-1,k))/dy) - ...
d*(u(i,j,k)*((u(i,j ,k) - u(i-1,j,k))/dx) +...
v(i,j,k)*((u(i,j+1,k) - u(i ,j,k))/dy));
v(i,j,k+1) = dy*(u(i-1,j,k+1)-u(i,j,k+1))/dx + ...
v(i,j-1,k+1);
T(i,j,k+1) = T(i,j,k) + dt/(Pr*Re) * (...
(T(i,j+1,k) - 2*T(i,j,k) + T(i,j-1,k))/dy^2 - Pr*Re*(...
u(i,j,k)*((T(i,j,k) - T(i-1,j,k))/dx) + v(i,j,k)*((T(i,j+1,k) - T(i,j,k))/dy))...
);
end
end
end
% Graphical representation of the wave at different selected times
figure, hold on
plot(x, u(:, 1), '-',...
x, u(:, 10), '-',...
x, u(:, 50), '-',...
x, u(:,100), '-')
title('graphs')
xlabel('X')
ylabel('Y')

Can't recover the parameters of a model using ode45

I am trying to simulate the rotation dynamics of a system. I am testing my code to verify that it's working using simulation, but I never recovered the parameters I pass to the model. In other words, I can't re-estimate the parameters I chose for the model.
I am using MATLAB for that and specifically ode45. Here is my code:
% Load the input-output data
[torque outputs] = DataLogs2();
u = torque;
% using the simulation data
Ixx = 1.00;
Iyy = 2.00;
Izz = 3.00;
x0 = [0; 0; 0];
Ts = .02;
t = 0:Ts:Ts * ( length(u) - 1 );
[ T, x ] = ode45( #(t,x) rotationDyn( t, x, u(1+floor(t/Ts),:), Ixx, Iyy, Izz), t, x0 );
w = x';
N = length(w);
q = 1; % a counter for the A and B matrices
% The Algorithm
for k=1:1:N
w_telda = [ 0 -w(3, k) w(2,k); ...
w(3,k) 0 -w(1,k); ...
-w(2,k) w(1,k) 0 ];
if k == N % to handle the problem of the last iteration
w_dash(:,k) = (-w(:,k))/Ts;
else
w_dash(:,k) = (w(:,k+1)-w(:,k))/Ts;
end
a = kron( w_dash(:,k)', eye(3) ) + kron( w(:,k)', w_telda );
A(q:q+2,:) = a; % a 3N*9 matrix
B(q:q+2,:) = u(k,:)'; % a 3N*1 matrix % u(:,k)
q = q + 3;
end
% Forcing J to be diagonal. This is the case when we consider our quadcopter as two thin uniform
% rods crossed at the origin with a point mass (motor) at the end of each.
A_new = [A(:, 1) A(:, 5) A(:, 9)];
vec_J_diag = A_new\B;
J_diag = diag([vec_J_diag(1), vec_J_diag(2), vec_J_diag(3)])
eigenvalues_J_diag = eig(J_diag)
error = norm(A_new*vec_J_diag - B)
where my dynamic model is defined as:
function [dw, y] = rotationDyn(t, w, tau, Ixx, Iyy, Izz, varargin)
% The output equation
y = [w(1); w(2); w(3)];
% State equation
% dw = (I^-1)*( tau - cross(w, I*w) );
dw = [Ixx^-1 * tau(1) - ((Izz-Iyy)/Ixx)*w(2)*w(3);
Iyy^-1 * tau(2) - ((Ixx-Izz)/Iyy)*w(1)*w(3);
Izz^-1 * tau(3) - ((Iyy-Ixx)/Izz)*w(1)*w(2)];
end
Practically, what this code should do, is to calculate the eigenvalues of the inertia matrix, J, i.e. to recover Ixx, Iyy, and Izz that I passed to the model at the very begining (1, 2 and 3), but all what I get is wrong results.
Is the problem with using ode45?
Well the problem wasn't in the ode45 instruction, the problem is that in system identification one can create an n-1 samples-signal from an n samples-signal, thus the loop has to end at N-1 in the above code.