Matlab Nested Radicals - matlab

Working on an assignment in MATLAB and I can't seem to figure this problem out due to the arithmetic, I've been trying it for about 6 hours now
I need to create a loop that accepts user input > 1 (done) and loops through the following (m is input)
t1 = sqrt(m);
t2 = sqrt(m-sqrt(m));
t3 = sqrt(m-sqrt(m+sqrt(m)))
t4 = sqrt(m-sqrt(m+sqrt(m-sqrt(m))))
t5 = sqrt(m-sqrt(m+sqrt(m-sqrt(m+sqrt(m)))))
and so on until the new t value minus the old t value is < 1e-12
My current code is as follows
%Nested Radicals
clear all;
clc;
%User input for m
m = input('Please enter a value for m: ');
%Error message if m is less than 1
if m <= 1
fprintf('ERROR: m must be greater than 1\n')
m = input('Please enter a value for m: ');
end
%Error message if m is not an integer
if mod(m,1) ~= 0
fprintf('m must be an integer\n')
m = input('Please enter a value for m: \n');
end
%Nested things
t_old = m;
t_new = sqrt(m);
varsign = -1;
index = 1;
loop = true;
endResult = 1e-12;
sqrts = [sqrt(m), sqrt(m-sqrt(m)), sqrt(m-sqrt(m+sqrt(m))), sqrt(m-sqrt(m+sqrt(m-sqrt(m)))), sqrt(m-sqrt(m+sqrt(m-sqrt(m+sqrt(m)))))];
fprintf('m = %d\n',m)
fprintf('t1 = %14.13f\n', t_new')
while loop
if index ~= 1
curResult = abs(sqrts(1,index) - sqrts(1, index-1));
else
curResult = abs(sqrts(1, index));
end
if curResult > endResult
if index < 5
t_new = sqrts(1, index+1);
else
t_new = sqrts(1, index);
loop=false;
end
if index
fprintf('t%d = %14.13f\n', index, t_new)
end
else
fprintf('t%d = %14.13f\n', index, t_new);
break;
end
index = index + 1;
if index > 50
fprintf('t%d = %14.13f\n', index, t_new);
break;
end
end

Unless I'm very much mistaken, you can write the expression for t(n) as follows:
t(n) = sqrt(m-sqrt(m+t(n-2));
which makes it a lot easier to loop:
%Nested Radicals
clear all;
clc;
%User input for m
m = input('Please enter a value for m: ');
%Error message if m is less than 1
if m <= 1
fprintf('ERROR: m must be greater than 1\n')
m = input('Please enter a value for m:');
end
%Error message if m is not an integer
if mod(m,1) ~= 0
fprintf('m must be an integer\n')
m = input('Please enter a value for m:');
end
%Nested things
t_old = sqrt(m);
t_new = sqrt(m-sqrt(m));
threshold = 1e-12;
k = 3;
while abs(t_new - t_old) >= threshold
temp = sqrt(m-sqrt(m+t_old));
t_old = t_new;
t_new = temp;
k = k+1;
end
fprintf('t%d = %14.13f\n', k-2, t_old);
fprintf('t%d = %14.13f\n', k-1, t_new);
fprintf('t%d - t%d = %14.13f\n', k-2, k-1, t_old - t_new);
which gives for m=9 for example:
Please enter a value for m: 9
t17 = 2.3722813232696
t18 = 2.3722813232691
t17 - t18 = 0.0000000000005

I'm not sure what you're trying to do with the sqrts variable, you should be calculating each step on the fly in your loop, since you can't possibly know how deep you need to go
m = 5; % Get m however you want to
n = 0; % Iteration counter
tol = 1e-12 % Tolerance at which to stop
dt = 1; % initialise to some value greater than 'tol' so we can start the loop
% Loop until tn is less than tolerance. Would be sensible to add a condition on n,
% like "while tn > tol && n < 1000", so the loop doesn't go on for years if the
% condition takes a trillion loops to be satisfied
while dt > tol
% Set the value of the deepest nested expression
tn = sqrt(m);
% We know how many times take sqrt, so for loop our way out of the nested function
% Initially we want the sign to be -1, then +1, -1, ...
% This is achieved using ((-1)^ii)
for ii = 1:n
tn = sqrt(m + ((-1)^ii)*tn); % Calculate next nested function out
end
% Increment iteration number
n = n + 1;
dt = abs( t_old - tn );
t_old = tn;
end
I've not done any analysis on your function, so have no idea if it's guaranteed to converge to some value <1e-12. If it isn't then you definitely need to add some maximum iteration condition as I suggest in the comments above.

Related

Berlekamp Massey Algorithm for BCH simplified binary version

I am trying to follow Lin, Costello's explanation of the simplified BM algorithm for the binary case in page 210 of chapter 6 with no success on finding the error locator polynomial.
I'm trying to implement it in MATLAB like this:
function [locator_polynom] = compute_error_locator(syndrome, t, m, field, alpha_powers)
%
% Initial conditions for the BM algorithm
polynom_length = 2*t;
syndrome = [syndrome; zeros(3, 1)];
% Delta matrix storing the powers of alpha in the corresponding place
delta_rho = uint32(zeros(polynom_length, 1)); delta_rho(1)=1;
delta_next = uint32(zeros(polynom_length, 1));
% Premilimnary values
n_max = uint32(2^m - 1);
% Initialize step mu = 1
delta_next(1) = 1; delta_next(2) = syndrome(1); % 1 + S1*X
% The discrepancy is stored in polynomial representation as uint32 numbers
value = gf_mul_elements(delta_next(2), syndrome(2), field, alpha_powers, n_max);
discrepancy_next = bitxor(syndrome(3), value);
% The degree of the locator polynomial
locator_degree_rho = 0;
locator_degree_next = 1;
% Update all values
locator_polynom = delta_next;
delta_current = delta_next;
discrepancy_rho = syndrome(1);
discrepancy_current = discrepancy_next;
locator_degree_current = locator_degree_next;
rho = 0; % The row with the maximum value of 2mu - l starts at 1
for i = 1:t % Only the even steps are needed (so make t out of 2*t)
if discrepancy_current ~= 0
% Compute the correction factor
correction_factor = uint32(zeros(polynom_length, 1));
x_exponent = 2*(i - rho);
if (discrepancy_current == 1 || discrepancy_rho == 1)
d_mu_times_rho = discrepancy_current * discrepancy_rho;
else
alpha_discrepancy_mu = alpha_powers(discrepancy_current);
alpha_discrepancy_rho = alpha_powers(discrepancy_rho);
alpha_inver_discrepancy_rho = n_max - alpha_discrepancy_rho;
% The alpha power for dmu * drho^-1 is
alpha_d_mu_times_rho = alpha_discrepancy_mu + alpha_inver_discrepancy_rho;
% Equivalent to aux mod(2^m - 1)
alpha_d_mu_times_rho = alpha_d_mu_times_rho - ...
n_max * uint32(alpha_d_mu_times_rho > n_max);
d_mu_times_rho = field(alpha_d_mu_times_rho);
end
correction_factor(x_exponent+1) = d_mu_times_rho;
correction_factor = gf_mul_polynoms(correction_factor,...
delta_rho,...
field, alpha_powers, n_max);
% Finally we add the correction factor to get the new delta
delta_next = bitxor(delta_current, correction_factor(1:polynom_length));
% Update used data
l = polynom_length;
while delta_next(l) == 0 && l>0
l = l - 1;
end
locator_degree_next = l-1;
% Update previous maximum if the degree is higher than recorded
if (2*i - locator_degree_current) > (2*rho - locator_degree_rho)
locator_degree_rho = locator_degree_current;
delta_rho = delta_current;
discrepancy_rho = discrepancy_current;
rho = i;
end
else
% If the discrepancy is 0, the locator polynomial for this step
% is passed to the next one. It satifies all newtons' equations
% until now.
delta_next = delta_current;
end
% Compute the discrepancy for the next step
syndrome_start_index = 2 * i + 3;
discrepancy_next = syndrome(syndrome_start_index); % First value
for k = 1:locator_degree_next
value = gf_mul_elements(delta_next(k + 1), ...
syndrome(syndrome_start_index - k), ...
field, alpha_powers, n_max);
discrepancy_next = bitxor(discrepancy_next, value);
end
% Update all values
locator_polynom = delta_next;
delta_current = delta_next;
discrepancy_current = discrepancy_next;
locator_degree_current = locator_degree_next;
end
end
I'm trying to see what's wrong but I can't. It works for the examples in the book, but not always. As an aside, to compute the discrepancy S_2mu+3 is needed, but when I have only 24 syndrome coefficients how is it computed on step 11 where 2*11 + 3 is 25?
Thanks in advance!
It turns out the code is ok. I made a different implementation from Error Correction and Coding. Mathematical Methods and gives the same result. My problem is at the Chien Search.
Code for the interested:
function [c] = compute_error_locator_v2(syndrome, m, field, alpha_powers)
%
% Initial conditions for the BM algorithm
% Premilimnary values
N = length(syndrome);
n_max = uint32(2^m - 1);
polynom_length = N/2 + 1;
L = 0; % The curent length of the LFSR
% The current connection polynomial
c = uint32(zeros(polynom_length, 1)); c(1) = 1;
% The connection polynomial before last length change
p = uint32(zeros(polynom_length, 1)); p(1) = 1;
l = 1; % l is k - m, the amount of shift in update
dm = 1; % The previous discrepancy
for k = 1:2:N % For k = 1 to N in steps of 2
% ========= Compute discrepancy ==========
d = syndrome(k);
for i = 1:L
aux = gf_mul_elements(c(i+1), syndrome(k-i), field, alpha_powers, n_max);
d = bitxor(d, aux);
end
if d == 0 % No change in polynomial
l = l + 1;
else
% ======== Update c ========
t = c;
% Compute the correction factor
correction_factor = uint32(zeros(polynom_length, 1));
% This is d * dm^-1
dd_sum = modulo(alpha_powers(d) + n_max - alpha_powers(dm), n_max);
for i = 0:polynom_length - 1
if p(i+1) ~= 0
% Here we compute d*d^-1*p(x_i)
ddp_sum = modulo(dd_sum + alpha_powers(p(i+1)), n_max);
if ddp_sum == 0
correction_factor(i + l + 1) = 1;
else
correction_factor(i + l + 1) = field(ddp_sum);
end
end
end
% Finally we add the correction factor to get the new locator
c = bitxor(c, correction_factor);
if (2*L >= k) % No length change in update
l = l + 1;
else
p = t;
L = k - L;
dm = d;
l = 1;
end
end
l = l + 1;
end
end
The code comes from this implementation of the Massey algorithm

Output Argument Not Assigned During Call: 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.

Implementing finding alghoritm with for loops and fmincon function

I am trying to implement this alghoritm for finding a new constraint:
In my case we take only 3 natural numbers i.e 1,2, 3.
The sets associated with those natural numbers are M1, M2 and M3. Instead of the Newton Method in II(2), I chose a solver provided by Matlab fmincon.
Here is my code that is not working!
function[s_new]= checking2(M1,M2,M3,x)
M1=linspace(0,1,10)';
M2=linspace(0,1,100)';
M3=linspace(0,1,1000)';
bool1=0;
eta = 10^-8;
pocz=[];
max=-100;
x = [0.1,0.1]'; % warunek początkowy
A = [];
b = [];
Aeq = [];
beq = [];
Set=[0,1];
g = #(x,s) 5*x(1).^2.*sin(pi.*sqrt(s))./(1+s.^2) - x(2);
g_new = #(s) -g(x,s);
for i=1:length(M1)
if g(x,M1(i,:))>eta
s_new=M1(i,:);
bool1=1;
end
end
if ~bool1
for i=1:length(M1)
if g(x,M1(i,:))>max
pocz=M1(i,:);
max=g(x,M1(i,:));
end
end
if max<-eta
bool1=1;
end
end
if ~bool1
s_maybe = fmincon(g_new,pocz,A,b,Aeq,beq,min(Set),max(Set));
if g(x,s_maybe)>eta
s_new=s_maybe;
bool1=1;
end
end
if ~bool1
for i=1:length(M2)
if g(x,M2(i,:))>eta
s_new=M2(i,:);
bool1=1;
end
end
end
if ~bool1
for i=1:length(M2)
if g(x,M2(i,:))>max
pocz=M2(i,:);
max=g(x,M2(i,:));
end
end
if max<-eta
bool1=1;
end
end
if ~bool1
s_maybe = fmincon(g_new,pocz,A,b,Aeq,beq,min(Set),max(Set));
if g(x,s_maybe)>eta
s_new=s_maybe;
bool1=1;
end
end
if ~bool1
for i=1:length(M3)
if g(x,M3(i,:))>eta
s_new=M3(i,:);
bool1=1;
end
end
end
if ~bool1
s_new = 1;
end
disp(s_new);
The problem is:
Undefined function or variable 's_new'.
Error in checking2 (line 70)
disp(s_new);
So basically everything might be wrong, but I suppose it is something with fmincon.
EDIT:
The purpose of the alghoritm is to find a minimum of an objective function f(x), satisfying all the constraints g(x,s)<=0 for all s in S, where S is an infinite set (some interval in our case).
What my alghoritm does, at first it takes some finite subset of S and calculates the minimum of f on this set, then I am trying to update S with some s_new. This alghoritm that I am trying to implement is exactly the procedure for creating s_new. Then if it works properly, I will add s_new to my subset and calculate the minimum on the new set, and so on until g(x,s)<=eta, where eta is a small number.
I rewrite the algorithm, read through the comments
clc
clear
lb = 0;
ub = 1;
% Given
l = 3;
M1=linspace(lb,ub,10)';
M2=linspace(lb,ub,100)';
M3=linspace(lb,ub,1000)';
% one boolean value for each Matrix
bool = zeros(1,3);
eta = 10^-8;
% Used as fmincon initial starting guess
pocz = nan;
% Used to store the new finding s that fits all the conditions
s_new = nan;
% Fixed x
x = [0.1,0]';
% fmincon linear constraints
A = [];
b = [];
Aeq = [];
beq = [];
% Main function
g = #(x,s) 5*x(1).^2*sin(pi*sqrt(s))/(1+s.^2) - x(2);
% Optimization concerns s only, don't include x as x is fixed
g_new = #(s) -g(x,s);
% Assuming the maximum is reached at the upper bound, used in(II)(2)
max_s = ub;
maxfun = g(x, max_s);
% Use a cell, for each iteration use a specific matrix M
M = {M1, M2, M3};
for j = 1: length(M)
% used in (II)(1)
check = 0;
step = 1;
% (I) step 1
for i = 1:length(M{j})
% Stopping criteria
if g(x, M{j}(i)) > eta
s_new = M{j}(i);
bool(j) = 1;
break;
else
% Function maximum value for next step (II)
if maxfun < g(x, M{j}(i))
maxfun = g(x, M{j}(i));
% To be used in fmincon as pocz
max_s = M{j}(i);
end
end
% To be used in (II)(1)
if maxfun < -eta
check = 1;
end
end
% End of (I)
% Put (II)(1) here step 2
if ~bool(j) && check
step = step + 1;
% Stopping criteria
if step >= l
disp('S_new not defined');
break;
end
% otherwise go to the next M
end
% (II)(2) step 3
if ~bool(j)
step = step + 1;
if maxfun >= -eta && maxfun <= eta
pocz = max_s;
bool(j) = 1;
end
end
%% EDIT: if bool(j) changed to if ~bool(j)
% (II)(2) Continue
if ~bool(j)
s_maybe = fmincon(g_new,pocz,A,b,Aeq,beq,lb,ub);
% End of (II)(2)
% (II)(2)-1 step 4
step = step + 1;
if g(x, s_maybe) > eta
s_new = s_maybe;
bool(j) = 1;
end
% End of (II)(2)-1
end
% Put (II)(2) here step 5
if ~bool(j)
step = step + 1;
% Stopping criteria
if step >= l
disp('S_new not defined');
break;
end
% otherwise go to the next M
end
end

Jacobi method to solve linear systems in MATLAB

How would you code this in MATLAB?
This is what I've tried, but it doesn't work quite right.
function x = my_jacobi(A,b, tot_it)
%Inputs:
%A: Matrix
%b: Vector
%tot_it: Number of iterations
%Output:
%:x The solution after tot_it iterations
n = length(A);
x = zeros(n,1);
for k = 1:tot_it
for j = 1:n
for i = 1:n
if (j ~= i)
x(i) = -((A(i,j)/A(i,i)) * x(j) + (b(i)/A(i,i)));
else
continue;
end
end
end
end
end
j is an iterator of a sum over each i, so you need to change their order. Also the formula has a sum and in your code you're not adding anything so that's another thing to consider. The last thing I see that you're omitting is that you should save the previous state of xbecause the right side of the formula needs it. You should try something like this:
function x = my_jacobi(A,b, tot_it)
%Inputs:
%A: Matrix
%b: Vector
%tot_it: Number of iterations
%Output:
%:x The solution after tot_it iterations
n = length(A);
x = zeros(n,1);
s = 0; %Auxiliar var to store the sum.
xold = x
for k = 1:tot_it
for i = 1:n
for j = 1:n
if (j ~= i)
s = s + (A(i,j)/A(i,i)) * xold(j);
else
continue;
end
end
x(i) = -s + b(i)/A(i,i);
s = 0;
end
xold = x;
end
end

Merge result after for function

Good morning everybody
I work to develop mathematical model to solve one of the industrial engineering problem but I have a problem in the write of the MATLAB code. So I simplified this problem in the following code. I need to merge all the result of X in one matrix after the for function used to use it in the next step (in this simple case this matrix will be 40*3)
LIST=randi([0,1],[4,3]);
for i = 1:10
j=i
V=randi([0,1],[4,3]);
for m = 1:4
for n = 1:2
if V(m,n)== 1;
X(m,n) = LIST(m,n);
elseif V(m,n)== 0;
X(m,n) = 2;
end
end
end
for m = 1:4
for n = 3
if V(m,n)== 1;
X(m,n) = LIST(m,n);
elseif V(m,n)== 0;
X(m,n) = 3;
end
end
end
X
end
Thank you for your time and your consideration
At each iteration of the outer loop (for i = 1:10) the values in the X matrix are overwritten.
In order to store all the values you need to increment the row value of the X matrix of the value of max limit of the second loop (for m = 1:4) that is 4.
You can do it by modifying the indexing of the X matrix as follows:
X(m+(i-1)*4,n)
You can make your script more "general" by identifying the limit evaluating it as the number of rows in the LIST matrix using the function size function:
[n_row,n_col]=size(LIST)
In this way
at the first iteration of the outer loop, the row index will range from 1 to 4.
at the second iteration itr will range from 1+(2-1)*4 to 4+(2-1)*4 that is from 5 to 8
and so on
This is the updated code
LIST=randi([0,1],[4,3]);
[n_row,n_col]=size(LIST)
for i = 1:10
j=i
V=randi([0,1],[4,3]);
% for m = 1:4
for m = 1:n_row
for n = 1:2
if V(m,n)== 1;
% X(m,n) = LIST(m,n);
X(m+(i-1)*n_row,n) = LIST(m,n);
elseif V(m,n)== 0;
% X(m,n) = 2
X(m+(i-1)*n_row,n) = 2;
end
end
end
% for m = 1:4
for m = 1:n_row
for n = 3
if V(m,n)== 1;
% X(m,n) = LIST(m,n)
X(m+(i-1)*n_row,n) = LIST(m,n);
elseif V(m,n)== 0;
% X(m,n) = 3;
X(m+(i-1)*n_row,n) = 3;
end
end
end
X
end
Hope this helps.
Qapla'