Other ... Index exceeds matrix dimensions - matlab

I'm really a noobie in Matlab, and i was making a program in it. This program just tries to read a binary number, for example (00011), the first 3 characters dictate what operation it will make, and the rest are the ones that are going to enter the operation (add, multiply, etc.). But an error keeps killing me, the "index exceeds matrix dimensions", i understand that matlab autmatically applies dimensions to a matrix, and this keeps me bugging on my back ...
here's the code.
function res = decPGL(varargin)
persistent rInicial
global r alto
if isempty(varargin)
res = rInicial;
elseif isequal(varargin{1},'r') || isequal(varargin{1},'R')
rInicial = varargin{2};
res = rInicial;
else
alto = 0; % bandera que termina el programa
programa = varargin{1}; % vector del programa completo
ins = 1; % número de instrucción que se va a ejecutar
r = rInicial; % estado inicial de registros
while ins<=length(programa) && ~alto
unPaso(programa(ins));
ins = ins + 1;
end
res = r;
end
function unPaso(segmento)
% executes a segment of the program
global r alto
hh4 = ihighh(segmento,4);
i = ilow(ihighh(segmento,2),2)+1;
j = ilow(segmento,2)+1;
if hh4 <= 5
switch hh4
case 0
r(i) = r(i) + r(j);
case 1
r(i) = r(i) - r(j);
case 2
r(i) = r(i) * r(j);
case 3
if r(j) ~= 0
r(i) = r(i)/r(j);
end
case 4
r(i) = j;
case 5
t = r(i);
r(i) = r(j);
r(j) = t;
end
elseif hh4==6
switch i
case 1
r(j) = exp(r(j));
case 2
r(j) = log(abs(r(j)));
case 3
r(j) = r(j)^2;
case 4
r(j) = sqrt(abs(r(j)));
end
elseif hh4==7
switch i
case 1
r(j) = -r(j);
case 2
r(j) = sin(r(j));
case 3
r(j) = cos(r(j));
case 4
r(1) = r(j);
alto = 1;
end
end
The problem is in the "r" variable, when is in the switch and a case is chosen, marks the error "Index exceeds matrix dimensions".
Any ideas or suggestions to solve this?
Thanks in advance.
PS: Forgot to put the ihighh code and the i low ... sorry ... here it is ....
%%ihigh
function res = ihigh(p, m, varargin)
if length(varargin)>=1
B = varargin{1};
else
B = 2;
end
res = p - mod(p,B.^m);
%%ihighh
function res = ihighh(p, m, varargin)
if length(varargin)>=1
B = varargin{1};
else
B = 2;
end
res = ihigh(p,m,B)./(B.^m);
%%ilow
function res = ilow(p, m, varargin)
if length(varargin)>=1
B = varargin{1};
else
B = 2;
end
res = mod(p,B.^m);

I think your code is incomplete. But anyhow, it is more useful if you debug your code yourself.
In MATLAB this can be done easily by the dbstop if error command. Then run your program and it will switch to debug mode whenever an uncaught error occurs. You should then manually investigate the size of r and what index you try to access. These will not match, so you should determine whether the matrix is too small or your index is in a wrong range and correct for that.
To quit from debug mode, enter the command dbquit and to prevent MATLAB from switching to debug mode automatically, just run dbclear if error.
More information on the debugger can be found in the MATLAB documentation.

Related

NULLSPACE - RREF Command in Matlab bugs

Can someone help me debug this Matlab code? Like I have a matrix A, and I need to find A^k by diagonalization method. Below is my original code, but there is a problem with this part:
m = (M - R(i,1)*eye(NumRowsR));
disp(rref(m));
t = null(rref(m));
disp(t);
This part can't give me the nullspace of matrix t after reduced for some reasons (I recently did some research on the Internet and see some people said about the bug of rref and null). The problem is that it keeps showing me elementary matrix
1 0 0
0 1 0
0 0 1
for the eigenvalues. Does anyone know how to fix it? I will be very much appreciated!
Below is my original code, for a better view:
syms x NumRowsM NumColsM NumRowsR NumColsR NumRowst NumColst k numeigen
M = input('Input a square matrix M: ');
k = input('Input the power of matrix M: ');
[NumRowsM, NumColsM]=size(M);
if (NumRowsM ~= NumColsM)
disp('Not valid input. Matrix must be a square matrix!')
else
%Find eigenvalues:
R = solve(det(M - x*eye(NumRowsM)), x);
[NumRowsR, NumColsR] = size(R);
if (or(NumRowsR == 0,NumColsR == 0))
disp('No eigenvalues. The matrix is not diagonalizable')
else
numeigen = 0;
F = zeros(NumRowsR, NumRowsR);
d = zeros(NumRowsR,1);
for i = 1:NumRowsR
m = (M - R(i,1)*eye(NumRowsR));
disp(rref(m));
t = null(rref(m));
disp(t);
[NumRowst, NumColst] = size(t);
if (NumColst == 0)
if (i == NumRowsR && numeigen > NumRowsR)
disp('Matrix not diagonalizable due to invalid eigenvalue');
return
else
continue
end
else
numeigen = numeigen + 1;
if (NumColst == 1)
for j = 1:NumRowsR
[n, d(j)] = numden(sym(t(j,1)));
end
for j = 1:NumRowsR
F(j,i) = sym(t(j,1)) * lcm(sym(d));
end
else
for k = 1:NumColst
for j = 1:NumRowsR
[n, d(j)] = numden(sym(t(j,k)));
end
for j = 1:NumRowsR
F(j,k) = sym(t(j,k)) * lcm(sym(d));
end
end
end
end
end
disp(F);
D = (F\M)*F;
disp('The power k of the matrix M is: ');
T = F*(D^k)/(F);
disp(T)
end
end

Getting out of multiple for loops in MATLAB

I have a homework exercise that asks for a script that finds smallest 3-digit Armstrong Number.
I wrote my script. It works fine for finding these numbers, but I don’t know how to stop at first Armstrong number.
Here is my code
a=0;
b=0;
c=0;
for x1=1:1:9
a=x1^3;
for x2=0:1:9
b=x2^3;
for x3=0:1:9
c=x3^3;
d=(x1*100 + x2*10 + x3);
if (a+b+c) == (d)
disp(d)
end
end
end
end
It normally prints 153 370 371 407.
If I use break after disp it just gets out of first for and not all, and prints 153 370 407.
You can stop loops with the keyword break. However, this just stops one loop. You have now to options
set some kind of flag and check it in every loop to terminate (break) it (aka: the proper way)
use return (aka: the nasty way)
Option 1
a = 0;
b = 0;
c = 0;
FLAG_STOP = false;
for x1 = 1:9
a = x1^3;
for x2 = 0:9
b = x2^3;
for x3 = 0:9
c = x3^3;
d = (x1*100 + x2*10 + x3);
if (a+b+c) == (d)
disp(d)
% set flag
FLAG_STOP = true;
break
end
end
if FLAG_STOP
break
end
end
if FLAG_STOP
break
end
end
Option 2
a word of warning:
(...) it does not just exit the loop; it exits the script or function and
returns control to the invoking program or command prompt.
i.e. all statements after return will be ignored -- with no matter whether they are part of a loop or not
a = 0;
b = 0;
c = 0;
for x1 = 1:9
a = x1^3;
for x2 = 0:9
b = x2^3;
for x3 = 0:9
c = x3^3;
d = (x1*100 + x2*10 + x3);
if (a+b+c) == (d)
disp(d)
return % <<<<<<<<<<<<
end
end
end
end
If you don't want to use return as recommended in #max's answer you may use try/catch and error to handle such cases:
try
a = 0;
b = 0;
c = 0;
for x1 = 1:9
a = x1^3;
for x2 = 0:9
b = x2^3;
for x3 = 0:9
c = x3^3;
d = (x1*100 + x2*10 + x3);
if (a+b+c) == (d)
disp(d)
error("") ;
end
end
end
end
catch
end

single perceptron not converging

I am programming a simple perceptron in matlab but it is not converging and I can't figure out why.
The goal is to binary classify 2D points.
%P1 Generate a dataset of two-dimensional points, and choose a random line in
%the plane as your target function f, where one side of the line maps to +1 and
%the other side to -1. Let the inputs xn 2 R2 be random points in the plane,
%and evaluate the target function f on each xn to get the corresponding output
%yn = f(xn).
clear all;
clc
clear
n = 20;
inputSize = 2; %number of inputs
dataset = generateRandom2DPointsDataset(n)';
[f , m , b] = targetFunction();
signs = classify(dataset,m,b);
weights=ones(1,2)*0.1;
threshold = 0;
fprintf('weights before:%d,%d\n',weights);
mistakes = 1;
numIterations = 0;
figure;
plotpv(dataset',(signs+1)/2);%mapping signs from -1:1 to 0:1 in order to use plotpv
hold on;
line(f(1,:),f(2,:));
pause(1)
while true
mistakes = 0;
for i = 1:n
if dataset(i,:)*weights' > threshold
result = 1;
else
result = -1;
end
error = signs(i) - result;
if error ~= 0
mistakes = mistakes + 1;
for j = 1:inputSize
weights(j) = weights(j) + error*dataset(i,j);
end
end
numIterations = numIterations + 1
end
if mistakes == 0
break
end
end
fprintf('weights after:%d,%d\n',weights);
random points and signs are fine since plotpv is working well
The code is based on that http://es.mathworks.com/matlabcentral/fileexchange/32949-a-perceptron-learns-to-perform-a-binary-nand-function?focused=5200056&tab=function.
When I pause the infinite loop, this is the status of my vairables:
I am not able to see why it is not converging.
Additional code( it is fine, just to avoid answers asking for that )
function [f,m,b] = targetFunction()
f = rand(2,2);
f(1,1) = 0;
f(1,2) = 1;
m = (f(2,2) - f(2,1));
b = f(2,1);
end
function dataset = generateRandom2DPointsDataset(n)
dataset = rand(2,n);
end
function values = classify(dataset,m,b)
for i=1:size(dataset,1)
y = m*dataset(i,1) + b;
if dataset(i,2) >= y, values(i) = 1;
else values(i) = -1;
end
end
end

how to evaluate a derivative of a function in matlab in one point? Error "dimensions must agree"

I have a function called funcion(x) which does:
function fx = funcion(x)
fx = cos(x); %%
return;
then in my other function (they are both in the same script) called newtonRaph i'm doing this:
function raiz = newtonRaph(xi,imax, tol)
syms x;
iter = 0;
xold = xi;
x = xold;
df = diff(cos(x),x);
er = 0.9;
while (er>tol)&&(iter<imax)
dfr = (subs(df,x,xold));
nuevo = 0.222/dfr;
if(dfr ==0)
disp('dfr was 0...');
break;
else
iter = iter+1;
evaluacion = funcion(x);
xnew = xold - (evaluacion/dfr); %Newton-Raphson formula
if(xnew~=0)&& (iter>1)
er = abs((xnew-xold)/xnew); %
end
xold = xnew;
x = xold;
end
end
root = xnew;
As you can see, i added a test line that does new = 0.222/dfr just to try and see what's happening with the derivative.
I don't know what is it that i'm doing wrong, but every time i run this, it tells me
??? Error using ==> mldivide
Matrix dimensions must agree.
Error in ==> newtonRaph at 16
nuevo = 0.222/dfr;
I would be really thankful if anyone could tell me what to do.
If dfr is not a scalar, and you only want to divide 0.222 by all the elements in it, then you should write nuevo = 0.222./dfr with a . before the /.

how to update axes in guide - matlab

i write a code using GUI and Mfile in MATHLAB. in my program i have a board.each time, computer put a marble and rotate the board then get a marble place and rotate direction of the board from user and After each of these things, i want it shows the result in axes1 in GUI. but it doesen't work in line 9 in the code below:
% some codes...
1. while(currentDepth < 7)
2. if(mod(currentDepth,2) ~= (plrC-1))
3. plat(currentDepth);
4. drawTable(); % show the result in axes1 --> it works
5. else
6. getMarble();
7. drawTable(); % show the result in axes1 --> it works
8. rotate();
9. drawTable(); % show the result in axes1 --> it dosen't work
10. end
11. end
% some codes...
.
function drawTable()
global board;
% some codes...
imshow(board,[0 4]);
end
do you have any idea?
it's rotate function. th board is divided into 4 parts just 1 part rotates.
function rotate()
global board;
block = 0;
vector = 'non';
while(block<1 || block>4)
block = str2double(cell2mat(inputdlg('chose a block: 1/2/3/4','board rotation')));
end
switch block
case 1
k=1; z=1;
case 2
k=1; z=4;
case 3
k=4; z=1;
case 4
k=4; z=4;
end
while(~strcmp(vector,'left') && ~strcmp(vector,'right'))
vector = questdlg('rotate left or right','Rotation','left','right','right');
end
if(strcmp(vector,'left'))
board(k:k+2,z:z+2)=rot90(board(k:k+2,z:z+2));
else
board(k:k+2,z:z+2)=rot90(board(k:k+2,z:z+2),3);
end
end
ok now here we have a simplified code. make a new GUI with an axes then run the code below from 'OpeningFnc'. you will see my problem.
function test()
currentDepth = 1;
plrC = 1;
plrO = 2;
board = zeros(6);
while(currentDepth < 40)
if(mod(currentDepth,2) == 1)
plat();
drawTable(); % show the result in axes1 --> it works
else
getMarble();
drawTable(); % show the result in axes1 --> it works
rotate();
drawTable(); % show the result in axes1 --> it dosen't work
end
currentDepth = currentDepth +1;
end
function plat()
for a=1:5000
for b=1:5000
for c=1:50
m = a + b;
end
end
end
row = 1;
column = 1;
while(board(row,column) ~= 0)
row = randi(6);
column = randi(6);
end
board(row,column) = plrC;
row = randi([1 4]);
column = randi([1 4]);
board(row:row+2,column:column+2)=rot90(board(row:row+2,column:column+2));
end
function drawTable()
board(board==0) = board(board==0)+4;
B = zeros(305);
B(:,152:154) = 3;
B(152:154,:) = 3;
for i=1:6
for j=1:6
x = (i*5)+1+(i-1)*45;
y = (j*5)+1+(j-1)*45;
B(x:x+44,y:y+44) = board(i,j);
end
end
imshow(B,[0 4]);
board(board==4) = board(board==4)*0;
end
function getMarble()
board(board==0) = board(board==0)+4;
b = zeros(305);
b(:,152:154) = 3;
b(152:154,:) = 3;
for i=1:6
for j=1:6
x = (i*5)+1+(i-1)*45;
y = (j*5)+1+(j-1)*45;
b(x:x+44,y:y+44) = board(i,j);
end
end
imshow(b,[0 4]);
i = 0;
while(i~=4)
[x,y] = ginput(1);
if(x<0 || x>305 || y<0 || y>305)
i = 0;
else
i = b(ceil(y),ceil(x));
end
end
y = ceil(y/50);
x = ceil(x/50);
board(y,x) = plrO;
end
function rotate()
block = 0;
vector = 'non';
while(block<1 || block>4)
block = str2double(cell2mat(inputdlg('chose a block: 1/2/3/4','board rotation')));
end
switch block
case 1
k=1; z=1;
case 2
k=1; z=4;
case 3
k=4; z=1;
case 4
k=4; z=4;
end
while(~strcmp(vector,'left') && ~strcmp(vector,'right'))
vector = questdlg('rotate left or right','Rotation','left','right','right');
end
if(strcmp(vector,'left'))
board(k:k+2,z:z+2)=rot90(board(k:k+2,z:z+2));
else
board(k:k+2,z:z+2)=rot90(board(k:k+2,z:z+2),3);
end
end
end
as ThP said, i have to add drawnow() function at the end of drawTable.