Genetic algorithm (n-queens problem) in MATLAB is stuck - matlab

I need to solve the n-queens problem in MATLAB and I have tried with the code attached below.
The problem that I have is that, at some point of the simulation the "checks" of the populations get stuck in a certain value (close to zero but not zero as I need). This happens 90% of the time, the other 10% gives a solution very fast (in a very few iterations). Maybe some parts are not well optimized but that is my best try. Feel free to ask anything about it, sorry if the comments are in spanish, thank you.
This is the code I used, if you run it multiple times, just a few of them will give you a solution.
% No siempre da soluciones, se suele quedar estancado con muy pocos jaques
% por población.
clc, clear
% Parámetros y vectores iniciales
N = 10000; % Número de iteraciones
n = 8; % Número de reinas
l = 8; % Longitud de cada lado del tablero
% Condición para que no haya más reinas que lados del tablero
while n > l
n = n-1;
end
pob = 5; % Número de población
f = #(x) n*l - x; % Función de aptitud, entre mayor cantidad de jaques, menor será la puntuación.
tableros = cell(1,pob+2); % Celda en donde se guardarán los vectores de cada población
posiciones = cell(1,pob+2);
hijo1 = zeros(n,2);
hijo2 = zeros(n,2);
hijo1(1:n,1) = 0:n-1;
hijo2 = hijo1;
[posiciones_iniciales, tableros_iniciales, cont_jaques, puntuacion] = pob_inicial(pob, n, l, f);
posiciones = posiciones_iniciales;
% Padres
[valoresMayores, padres] = mink(cont_jaques,2);
cont = 1;
resultado = 0;
while cont ~= N
pc = randi([1,n]); % Punto de cruzamiento
hijo1 = posiciones{padres(1)};
hijo2 = posiciones{padres(2)};
hijo1(pc+1:n,2) = posiciones{padres(2)}(pc+1:n,2);
hijo2(pc+1:n,2) = posiciones{padres(1)}(pc+1:n,2);
if rand > 0.2 % Probabilidad de mutación del 80% del hijo 1
m = randi([1,n]);
hijo1(m, 2) = randi([0,n-1]);
end
if rand > 0.2 % Probabilidad de mutación del 80% del hijo 1
m = randi([1,n]);
hijo2(m, 2) = randi([0,n-1]);
end
posiciones{pob + 1} = hijo1;
posiciones{pob + 2} = hijo2;
% Posiciones de los tableros (para el cálculo de los jaques)
for ii = 1:pob+2
tableros{ii} = zeros(l,l); % Tablero (si en la casilla hay un 1, significa que en esa posición hay una reina)
for k = 1:n
tableros{ii}(posiciones{ii}(k,1)+1, posiciones{ii}(k,2)+1) = 1;
end
% Checar los jaques de los tableros iniciales
n_jaques = jaques(posiciones{ii}(:,2)', l, ii, tableros);
cont_jaques(ii) = n_jaques;
% Prueba de aptitud
puntuacion(ii) = f(cont_jaques(ii));
end
% Eliminados (los de menor aptitud)
[valoresMenores, eliminados] = maxk(cont_jaques, 2);
posiciones(:, eliminados) = [];
cont_jaques(eliminados) = [];
puntuacion(eliminados) = [];
% Padres
[valoresMayores, padres] = mink(cont_jaques, 2);
% Checar si hay soluciones
for jj = 1:pob
if cont_jaques(jj) == 0
resultado = 1;
break
end
end
if resultado == 1
break
else
cont = cont + 1;
end
end
if cont == N
fprintf('No se ha encontrado solución en %d iteraciones. \n', N)
else
fprintf('Se encontró la solución despues de %d iteraciones. \n', cont)
end
for ii = 1:pob
if cont_jaques(ii) == 0
subplot(2, 3, 2)
tablero(l)
title('Tablero inicial', ii)
reinas(posiciones_iniciales{ii}(:,1),posiciones_iniciales{ii}(:,2), n, 'red')
subplot(2, 3, 5)
tablero(l)
title('Tablero final', ii)
reinas(posiciones{ii}(:,1),posiciones{ii}(:,2), n, 'green')
end
end
%% Función que genera las poblaciones iniciales aleatoriamente
function [posiciones_iniciales, tableros_iniciales, cont_jaques, puntuacion] = pob_inicial(pob, n, l, f)
% pob: Número de población
% n: Número de reinas
% l: Lado del tablero
% f: Función de aptitud
tableros_iniciales = cell(1,pob); % Celda en donde se guardarán los vectores de cada población
posiciones_iniciales = cell(1,pob); % Celda en donde se guardarán los vectores de cada población
cont_jaques = zeros(1,pob); % Vector de contador de jaques de cada tablero
puntuacion = zeros(1,pob); % Vector que guarda las puntuaciones de aptitud
for ii = 1:pob
% Poblaciones iniciales aleatorias
r = randi([0,l-1],1,n);
for jj = 0:n-1
posiciones_iniciales{ii}(jj+1,1) = jj;
posiciones_iniciales{ii}(jj+1,2) = r(jj+1);
end
% Posiciones del tablero
tableros_iniciales{ii} = zeros(l,l); % Tablero (si en la casilla hay un 1, significa que en esa posición hay una reina)
for k = 1:n
tableros_iniciales{ii}(posiciones_iniciales{ii}(k,1)+1, posiciones_iniciales{ii}(k,2)+1) = 1;
end
% Checar los jaques de los tableros iniciales
n_jaques = jaques(posiciones_iniciales{ii}(:,2), l, ii, tableros_iniciales);
cont_jaques(ii) = n_jaques;
% Prueba de aptitud
puntuacion(ii) = f(cont_jaques(ii));
end
end
%% Función de comprobación de jaques
function n_jaques = jaques(ry, l, n_tablero, celda_tableros)
% Función que comprueba cuántas reinas hay en jaque dado un tablero
n_jaques = 0;
% Verticales
By = unique(ry);
n_repetidos_y = histc(ry, By);
c_unicos_y = size(n_repetidos_y);
for jj = 1:c_unicos_y(2)
if n_repetidos_y(jj) > 1
combinatoria_y = factorial(n_repetidos_y(jj))/(factorial(n_repetidos_y(jj) - 2));
n_jaques = n_jaques + combinatoria_y; % Se suman la cantidad de jaques posibles de la columna
end
end
% Diagonales con pendiente negativa
for k = 0:l
% Diagonales con k positiva
diagonal1 = diag(celda_tableros{n_tablero},k);
n_reinas_d1 = numel(find(diagonal1==1));
if n_reinas_d1 == 2
n_jaques = n_jaques + 1;
elseif n_reinas_d1 > 2
combinatoria_d1 = factorial(n_reinas_d1)/(factorial(2)*(factorial(n_reinas_d1 - 2)));
n_jaques = n_jaques + combinatoria_d1;
end
% Diagonales con k negativa
end
for k = -1:-1:-l
diagonal2 = diag(celda_tableros{n_tablero},k);
n_reinas_d2 = numel(find(diagonal2==1));
if n_reinas_d2 == 2
n_jaques = n_jaques + 1;
elseif n_reinas_d2 > 2
combinatoria_d2 = factorial(n_reinas_d2)/(factorial(2)*(factorial(n_reinas_d2 - 2)));
n_jaques = n_jaques + combinatoria_d2;
end
end
% Diagonales con pendiente positiva
for k = 0:l
% Diagonales con k positiva
diagonal1 = diag(fliplr(celda_tableros{n_tablero}),k);
n_reinas_d1 = numel(find(diagonal1==1));
if n_reinas_d1 == 2
n_jaques = n_jaques + 1;
elseif n_reinas_d1 > 2
combinatoria_d1 = factorial(n_reinas_d1)/(factorial(2)*(factorial(n_reinas_d1 - 2)));
n_jaques = n_jaques + combinatoria_d1;
end
% Diagonales con k negativa
end
for k = -1:-1:-l
diagonal2 = diag(fliplr(celda_tableros{n_tablero}),k);
n_reinas_d2 = numel(find(diagonal2==1));
if n_reinas_d2 == 2
n_jaques = n_jaques + 1;
elseif n_reinas_d2 > 2
combinatoria_d2 = factorial(n_reinas_d2)/(factorial(2)*(factorial(n_reinas_d2 - 2)));
n_jaques = n_jaques + combinatoria_d2;
end
end
end
%% Función de gráfica del tablero
function tablero(l)
% Función que crea un tablero de lado l
x1=0; x2=l;
y1=0; y2=l;
x = [x1, x2, x2, x1, x1];
y = [y1, y1, y2, y2, y1];
plot(x, y, 'k-', 'LineWidth', 1.5);
hold on
xlim([-1, l+1]);
ylim([-1, l+1]);
% Grid
for i = 1:l
plot([0,l],[i,i], 'k-', 'LineWidth', 1.5)
plot([i,i],[0,l],'k-', 'LineWidth', 1.5)
end
end
%% Función de gráfica de las reinas
function reinas(rx,ry,n,color)
% Función que grafica n cantidad de reinas en las posiciones en x y y dadas por los vectores rx y ry.
for n = 1:n
g_reinas = plot(rx(n)+0.5,ry(n)+0.5, 'or');
g_reinas.MarkerFaceColor = [color];
g_reinas.MarkerSize = 6;
g_reinas.MarkerEdgeColor = [color];
% legend(reinas,'Reinas')
end
hold off
end

Perhaps using a random function to find all populations does not allow you to find all solutions quickly.
You could search through all possible permutations n! of the column indexes, example of the different arrangements of the column indexes are (1. 5. 8. 6. 3. 7. 2. 4)
And
(1. 6. 8. 3. 7. 4. 2. 5)
which in the first case correspond to positions of the queens (1,1);(2,5);(3,8);(4,6);(5,3);(6,7);(7,2) ;(8,4).
Or use an optimized solution like this one that doesn't evaluate all permutations but jumps are made if certain conditions are met.
This code has been tested with SCILAB but should also work in MATLAB:
n=8;
count=0;
Index_col=ones(1,n);
i = 2;
while (1 == 1)
ck_var = 1;
while(ck_var == 1);
ck_var = 0;
for j=1:i-1
if ((Index_col(1,i) == Index_col(1,j)) || (abs(Index_col(1,i) - Index_col(1,j)) == i - j))
if (Index_col(1,i) < n)
Index_col(1,i)=Index_col(1,i)+1;
ck_var = 1;
else
ck_var = 2;
end
break;
end
end
end
if (i == n || ck_var == 2)
if (ck_var == 0)
// print board
for jc=1:n
Board(jc,:)=zeros(1,n);
Board(jc,Index_col(1,jc))=1;
end
Board
//
count=count+1;
end
while (Index_col(1,i) == n && i > 1)
i=i-1;
end
if (Index_col(1,1) == n && i == 1)
break;
else
Index_col(1,i)=Index_col(1,i)+1;
Index_col(1,i+1:n) = 1;
i = 2;
end
else
i=i+1;
end
end
count

Related

Problem with Octave and imnoise (nonconformant arguments (op1 is 11x1, op2 is 9x1))

I have a problem that is complicating my life with octave, I am working with a bee algorithm, to work with it, first I use "imnoise" to add noise to the image, but the problem is that when I add noise, for some reason when trying to perform operations with the original image and the image with noise, it tells me that these images have different sizes.
Noise add
clc;
pkg load image;
I=imread('emigray.jpg');
%I=rgb2gray(I);
sigmaNoise = 0.250;
Inoisy = imnoise(I, "gaussian",0.05);
imwrite(Inoisy,'sucia.jpg');
size(I);
size(Inoisy);
ABCPAR(50,50,0,'emigray.jpg','sucia.jpg');
Before executing the bee algorithm, it calculates the rmse but there is where it throws the error that the images have different sizes.
function [mse, rmse] = RMSE(signal1, signal2)
originalRowSize = size(signal1,1);
originalColSize = size(signal1,2);
originalRowSize
originalColSize
size(signal2,1)
size(signal2,2)
signal1 = signal1(:);
signal2 = signal2(:);
size(signal1)
size(signal2)
mse = sum((signal1 - signal2).^2)./(originalRowSize*originalColSize);
rmse = sqrt(mse);
The error.
error: operator -: nonconformant arguments (op1 is 11x1, op2 is 9x1)
error: called from
RMSE at line 15 column 9
ABCPAR at line 52 column 23
filtro at line 12 column 1
I don't know how to solve it, every thing I try doesn't work, help, thank you very much for your help.
ABCPAR is the bee algorithm and the error is because it uses the value of mse and does not find it, because that is where the error in RMSE was generated.
ABCPAR
function [GlobalOpt, GlobalParams, conv]=ABCPAR(Np, gmax,opti, I, Inoisy)
O = size(I)
N = size(Inoisy)
I
Inoisy
if(opti==0)
GlobalOpt=inf;
else
GlobalOpt=0;
end
%Inicializo los vectores de par�metros
vector_numIt=1:100;
vector_dt=0.1:0.01:0.2;
vector_k=1:0.5:30;
range=[1 100 1 11 1 59];
%Parametros iniciales
d=3; %dimensiones
%Np=250; %tama�o poblacion
fuente_comida=round(Np/2); %Fuentes de comida
limit=5; %criterio de abandono
Aux=1;
Rango=zeros(1,3);
for i=1:d
Rango(i)=range(1,Aux+1)-range(1,Aux);
Aux=Aux+2;
end
%Poblacion inicial aleatoria
%Poblacion=(rand(fuente_comida,d)*Rango)+range(1)
Poblacion=zeros(fuente_comida,d)
for i=1:d
Poblacion(:,i)=round((rand(fuente_comida,1)*Rango(i))+1);
end
%Calcula fitness de la funci�n objetivo para la poblaci�n inicial
for ii=1:fuente_comida
IFiltrada=difusionAnisotropicaPM(Inoisy, vector_numIt(Poblacion(ii,1)), vector_dt(Poblacion(ii,2)), vector_k(Poblacion(ii,3)));
variable = 'size 1'
size(IFiltrada)
if(opti==0)
ValFit(ii)=RMSE(I,IFiltrada);
Fitness(ii)=ValFit(ii);
else
ValFit(ii)=snr(I,IFiltrada);
Fitness(ii)=ValFit(ii);
end
end
%inicializar contadores de prueba
prueba=zeros(1,fuente_comida);
%Se actualiza la fuente donde se encontr� la mejor fuente de comida
if(opti==0)
MejorInd=find(ValFit==min(ValFit));
else
MejorInd=find(ValFit==max(ValFit));
end
MejorInd=MejorInd(end);
GlobalOpt=ValFit(MejorInd);
GlobalParams=Poblacion(MejorInd,:); %Se refiere a la Ubicaci�n del mejor individuo
g=1; %contador de generaciones
while((g<=gmax))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%Fase de abeja obrera%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:fuente_comida
%Parametro a modificar determinado aleatoriamente
Param2Change=fix(rand*d)+1;
%Se utiliza una solucion aleatoria para producir una nueva solucion mutante, ambas deben ser diferentes
vecino=fix(rand*(fuente_comida))+1;
%Por si justo el vecino es el mismo
while(vecino==i)
vecino=fix(rand*(fuente_comida))+1;
end
soluciones=Poblacion(i,:);
%es aplicado: v_{ij}=x_{ij}+\phi_{ij}*(x_{kj}-x_{ij})
soluciones(Param2Change)=round(Poblacion(i,Param2Change)+(Poblacion(i,Param2Change)-Poblacion(vecino,Param2Change))*(rand-0.5)*2);
if(soluciones(Param2Change)<1)
soluciones(Param2Change)=1;
end
if(soluciones(Param2Change)>range(2*Param2Change))
soluciones(Param2Change)=range(2*Param2Change);
end
IFiltrada=difusionAnisotropicaPM(Inoisy, vector_numIt(soluciones(1)), vector_dt(soluciones(2)), vector_k(soluciones(3)));
variable = 'size 2'
size(IFiltrada)
if(opti==0)
ValFitSol=RMSE(I,IFiltrada);
FitnessSol=ValFit(ii);
else
ValFitSol=snr(I,IFiltrada);
FitnessSol=ValFit(ii);
end
%Se aplica un criterio de selecci�n Greedy entre la solucion
%actual y la producida(mutante), se conserva la mejor entre ellas
if(opti==0)
if(FitnessSol<Fitness(i))
Poblacion(i,:)=soluciones;
Fitness(i)=FitnessSol;
ValFit(i)=ValFitSol;
prueba(i)=0;
else
prueba(i)=prueba(i)+1; %se incrementa el contador de prueba
end
else
if(FitnessSol>Fitness(i))
Poblacion(i,:)=soluciones;
Fitness(i)=FitnessSol;
ValFit(i)=ValFitSol;
prueba(i)=0;
else
prueba(i)=prueba(i)+1; %se incrementa el contador de prueba
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%Fin fase Abeja obrera%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%se calculan probabilidades utilizando los valores de fitness normalizados
probab=(0.9.*Fitness./max(Fitness))+0.1;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%Fase de abeja observadora%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i=1;
t=0;
while t<fuente_comida
%Las abejas observadoras ver�n la danza de las obreras y eligiran una buena fuente
if rand<probab(i)
t=t+1;
%el parametro a modificar se selecciona aleatoriamente
Param2Change=fix(rand*d)+1;
%es utilizada una solucion aleatoria para producr una nueva solucion caldidato, deber�n ser diferentes entre si
while(vecino==i)
vecino=fix(rand*(fuente_comida))+1;
end
soluciones=Poblacion(i,:);
%Se aplica: v_{ij}=x_{ij}+\phi_{ij}*{kj}-x_{ij})
soluciones(Param2Change)=round(Poblacion(i,Param2Change)+(Poblacion(i,Param2Change)-Poblacion(vecino,Param2Change))*(rand-0.5)*2);
%Si el parametro generado est� fuera de los limites, es llevado al limite m�s proximo
if(soluciones(Param2Change)<1)
soluciones(Param2Change)=1;
end
if(soluciones(Param2Change)>range(2*Param2Change))
soluciones(Param2Change)=range(2*Param2Change);
end
IFiltrada=difusionAnisotropicaPM(Inoisy, vector_numIt(soluciones(1)), vector_dt(soluciones(2)), vector_k(soluciones(3)));
variable = 'size 3'
size(IFiltrada)
if(opti==0)
ValFitSol=RMSE(I,IFiltrada);
FitnessSol=ValFit(ii);
else
ValFitSol=snr(I,IFiltrada);
FitnessSol=ValFit(ii);
end
%Se aplica un criterio de selecci�n Greedy entre la solucion
%actual y la producida(mutante), se conserva la mejor entre ellas
if(opti==0)
if(FitnessSol<Fitness(i))
Poblacion(i,:)=soluciones;
Fitness(i)=FitnessSol;
ValFit(i)=ValFitSol;
prueba(i)=0;
else
prueba(i)=prueba(i)+1; %se incrementa el contador de prueba
end
else
if(FitnessSol>Fitness(i))
Poblacion(i,:)=soluciones;
Fitness(i)=FitnessSol;
ValFit(i)=ValFitSol;
prueba(i)=0;
else
prueba(i)=prueba(i)+1; %se incrementa el contador de prueba
end
end
end
i=i+1;
%Si supera la cantidad de fuentes de comida vuelve a empezar
if (i==(fuente_comida)+1)
i=1;
end
end
if(opti==0)
%Se incrementa la mejor fuente de comida
ind=find(ValFit==min(ValFit));
ind=ind(end);
if (ValFit(ind)<GlobalOpt)
GlobalOpt=ValFit(ind);
GlobalParams=Poblacion(ind,:);
end
else
%Se incrementa la mejor fuente de comida
ind=find(ValFit==max(ValFit));
ind=ind(end);
if (ValFit(ind)>GlobalOpt)
GlobalOpt=ValFit(ind);
GlobalParams=Poblacion(ind,:);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Fin de la fase de la abeja observadora%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Fase de la abeja exploradora%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%if(opti==0)
%else
%end
%se determinan las fuentes de comida cuyo valor de l�mite es alcanzado
ind=find(prueba==max(prueba));
ind=ind(end);
if(prueba(ind)>limit)
prueba(ind)=0;
soluciones=zeros(1,d);
for i=1:d
soluciones(i)=round((Rango(i)).*rand(1,1)+1);
end
if(opti==0)
IFiltrada=difusionAnisotropicaPM(Inoisy, vector_numIt(soluciones(1)), vector_dt(soluciones(2)), vector_k(soluciones(3)));
variable = 'size 4'
size(IFiltrada)
ValFitSol=RMSE(I,IFiltrada);
FitnessSol=ValFit(ii);
else
IFiltrada=difusionAnisotropicaPM(Inoisy, vector_numIt(soluciones(1)), vector_dt(soluciones(2)), vector_k(soluciones(3)));
variable = 'size 5'
size(IFiltrada)
ValFitSol=snr(I,IFiltrada);
FitnessSol=ValFit(ii);
end
Poblacion(ind,:)=soluciones;
Fitness(ind)=FitnessSol;
ValFit(ind)=ValFitSol;
end
conv(g)=GlobalOpt
Poblacion
g=g+1; %se incrementa la iteracion
%clc
%se despliegan la posicion y fitness del mejor individuo
%disp(g)
%disp(GlobalOpt)
%disp(GlobalParams)
end
return;
end
difusionAnisotropicaPM
function Ifiltrada = difusionAnisotropicaPM(Inoisy, numIt, dt, k)
Ifiltrada = double(Inoisy);
[xDim, yDim] = size(Ifiltrada);
in = [1 1:xDim-1];
is = [2:xDim xDim];
ie = [1 1:yDim-1];
io = [2:yDim yDim];
for it = 1: numIt
gn = Ifiltrada(in,:) - Ifiltrada;
gs = Ifiltrada(is,:) - Ifiltrada;
ge = Ifiltrada(:,ie) - Ifiltrada;
go = Ifiltrada(:,io) - Ifiltrada;
cn = lorenciana(gn,k);
cs = lorenciana(gs,k);
ce = lorenciana(ge,k);
co = lorenciana(go,k);
Ifiltrada = Ifiltrada + dt.*(gn.*cn + gs.*cs + ge.*ce + go.*co);
end
Ifiltrada = uint8(Ifiltrada);
end
function g = lorenciana(grad,k)
g = 1./(1+ (grad./k).^2);
end
snr
function v = snr(x,y)
x = double(x);
y = double(y);
% snr - signal to noise ratio
%
% v = snr(x,y);
%
% v = 20*log10( norm(x(:)) / norm(x(:)-y(:)) )
%
% x is the original clean signal (reference).
% y is the denoised signal.
%
% Copyright (c) 2008 Gabriel Peyre
v = 20.*log10(norm(x(:))./norm(x(:)-y(:)));
Sizes output
O =
1 11
N =
1 9
I = emigray.jpg
Inoisy = sucia.jpg
Poblacion =
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
variable = size 1
ans =
1 9
originalRowSize = 1
originalColSize = 11
ans = 1
ans = 9
ans =
11 1
ans =
9 1
error: operator -: nonconformant arguments (op1 is 11x1, op2 is 9x1)
error: called from
RMSE at line 15 column 9
ABCPAR at line 52 column 23
filtro at line 12 column 1
You need to call ABCPAR as follows:
ABCPAR(50,50,0,I,Inoisy);
You pass in file names, but this function does not expect file names, it expects arrays. So it uses the names as if they were data, hence the sizes of 1x9 and 1x11, which correspond to the sizes of the file names.

labeling points on the chart - matlab

Goodnight.
How can I label the graph points with bits?
This is my code:
L = 1e4;
SNRdB = 0:28;
SNR = 10.^(SNRdB/10);
r = 10.^(SNRdB/10);
alpha = 0.3;
% Número máximo de iterações para um único SNR
max_run = 100;
for sk = 1:length(SNRdB)
for tk = 1:max_run
% 1 ou -1 para sinal em fase (an)
x_inp_I = sign(rand(1,L)- 0.5);
% 1 ou -1 para sinal de quadratura (bn)
x_inp_Q = sign(rand(1,L)- 0.5);
QPSK = x_inp_I + 1i .* x_inp_Q;
% Gera bits de marca d'água aleatórios (dI)
Bit_wat_I = sign(rand(1,L)- 0.5);
% Gera bits de marca d'água aleatórios (dQ)
Bit_wat_Q = sign(rand(1,L)- 0.5);
% encontrar a equação
for k = 1:L
if Bit_wat_I(k) == 1 && Bit_wat_Q(k) == 1
Bit_enviado(k) = (x_inp_I(k) .* ((sqrt(1-alpha)) + (sqrt(alpha)))) + (1i .* x_inp_Q(k) * (sqrt(1-alpha)) + (sqrt(alpha))));
end
end
end
end
The plot got this way:
I would like to label it this way:
The following code will generate a similar figure to your second image
rM = [-3 -1 1 3];
strLabel = dec2bin(0:15);
figure
set(gcf, 'Color', 'White')
hold on
nInc = 1;
for nX = rM
for nY = rM
plot(nX, nY, 'b+')
text(nX, nY-0.3, strLabel(nInc,:), ...
'HorizontalAlignment', 'Center')
nInc = nInc + 1;
end
end
xlabel('In-Phase')
ylabel('Quadrature')
title('Scatter plot')
set(gca, 'XTick', -4:4)
set(gca, 'YTick', -4:4)
axis([-4 4 -4 4])
axis square
grid off
box on

i'm having these error: subscripts must be either integers 1 to (2^31)-1 or logicals

I'm starting to program and choose octave couse it's the free "version" of matlab, the program they use here at my university.
So, these problem apears when i try to run my code:
error: I(0): subscripts must be either integers 1 to (2^31)-1 or logicals
and I don't know why, because when I put R in place of RR, the code works.
I thought that maybe the problem was that R-Rn isn't reeeally equal 0, but something close to it, ans thus the problem, but after doing some tests with simple numbers, I found out that it was actually 0, but maybe it's diferent for matrixes.
Please help.
oh, and don't pay attention to the notes, i'm from brazil.
clear
tic %inicio da cronometragem
f = #(x) 16*x.^6 + 8*x -6; %definir função
df = #(x) 96*x.^5 + 8; %definir derivada da função
tol = 10E-4; %define a tolerancia
xmin = -5; %menor valor para X
xmax = 5; %maior valor para X
ymin = -5; %menor valor para Y
ymax = 5; %maior valor para Y
npx = 8; %número de pontos do eixo X
npy = 8; %número de pontos do eixo Y
dx = (xmax-xmin)/npx; %calculo da distância entre os
pontos do eixo X
dy = (ymax-ymin)/npy; %calculo da distância entre os
pontos do eixo Y
A = zeros(npy+1, npx+1); %define matriz cheia de 0, do
tamanho definido por npx e npy
x = xmin:dx:xmax; %define tamanho e distancia entre os pontos de uma linha
y= ymin:dy:ymax; %define tamanho e distancia entre os pontos de uma coluna
A = x+i*y'; %preenche a matriz A com os valores desta multiplicação
[m n] = size(A); %define m e n como o tamanho da linha e coluna, respectivamente, da matriz A
I = zeros(m,n); %cria outra matriz, I, de mesmo tamanho de A, mas cheia de 0
i = 0; %numero de interações definido como 0
R = I;
for kk = 1:50 %define numero de interações do metodo de newton
An = A-f(A)./df(A); %método de newton
i = i + 1; %aumentar o numero de interação a cada vez que repete
Rn = R
R = abs((An - A)) < tol %cria uma matriz R com 1 ou 0 se a posição alcançou a tolerancia ou não
RR = R - Rn
I(RR) = i %preenche a matriz I com o numero de interação de cada posição da matriz A
A = An; %iguala A com An para que o metodo de newton possa continuar
end
imagesc(I) %forma o fractal
toc %para o cronômetro
It works for R because R is a logical array - indexing with a logical array accepts 0 as a value because 0 in logical array indexing means 'don't apply to this element'.
When you subtract your array Rn, RR becomes an array of doubles. Indexing this way cannot accept 0 as there is no 0th element.
You need to convert RR to a logical array (the function is 'logical' in MATLAB) for it to work.
When I run the code I get that RR is all zeros. In MATLAB indexes start at 1 (so zero is an invalid index). Try changing RR = R - Rn to RR = R - Rn + 1. This at least lets the code run and produce an image (although I'm not sure if the image is correct).

Save minimum during while on MATLAB

hello i' m writing a code with a while loop, during the iterations i need to save a value of the minim of a function. Now in my code i save the last value of the iteration but i want the lowest value and not the last one, how can a resolve it?? hers' s my code (i want to remember that this code's running during a while)
particelle = 30; % numero delle particelle
it = 50; % massimo numero di iterazioni
var = 5; % numero di variabili del problema
ls = 1; % limite superiore
li = 0; % limite inferiore
c2 =0.1; % parametro PSO
c1 = 0.1; % parametro PSO
w =0.9; % inerzia del PSO
% Parametri del benchmark
Io = 3.195366750697098e-9;
Iirr = 1.073577407858;
Rp = 0.783526109678138e+5;
Rs = 1.18407328046765;
n = 1.33752492449578;
% Limiti da considerare
Io_low = Io - (Io * 0.1); % valore basso togliamo il 10 per cento
Io_high = Io + (Io * 0.1); % valore alto sommiamo il 10 per cento
Iirr_low = Iirr - (Iirr * 0.1); % valore basso togliamo il 10 per cento
Iirr_high = Iirr + (Iirr * 0.1); % valore alto sommiamo il 10 per cento
Rp_low = Rp - (Rp * 0.1); % valore basso togliamo il 10 per cento
Rp_high = Rp + (Rp * 0.1); % valore alto sommiamo il 10 per cento
Rs_low = Rs - (Rs * 0.1); % valore basso togliamo il 10 per cento
Rs_high = Rs + (Rs * 0.1); % valore alto sommiamo il 10 per cento
n_low = n - (n * 0.1); % valore basso togliamo il 10 per cento
n_high = n + (n * 0.1); % valore alto sommiamo il 10 per cento
x_low = [Rs_low, n_low, Io_low, Iirr_low, Rp_low ];
x_high = [Rs_high, n_high, Io_high, Iirr_high, Rp_high];
fitness1 = #fitness; % funzione di fitness
pos = rand(particelle, var); % posizione delle particelle
vel = 1e-3*rand(particelle, var) ; % velocità delle particelle
pers = pos ; % personale delle particelle
glob = min(pers); % minimo di ogni colonna
glob = repmat(glob,particelle,1); % minimo globale uguale per ogni particella
fitness_corrente = zeros(particelle,1); % inizializziamo la matrice fitness_corrente che conterrà tutti i valori del fitness di ogni singola particella
h = zeros(particelle,var); % inizializziamo la matrice per
for i = 1: particelle
h(i,:) = x_low + (pos(i,:).*(x_high-x_low)); % normalizziao i limiti delle particelle
fitness_corrente(i,:) = fitness1(h(i,:)); % fitness della prima popolazione normalizzata
end
% assegnamo il valore di fitness di ogni particella a fitness_personale
fitness_pers = fitness_corrente;
% indidichiamo con fitness_globale il minimo valore ottenuto dalla fitness e la posizione che occupa x è la particella con ilvalore minimo di fitness
[fitness_glob, minimo] = min(fitness_pers);
%% Main
iter = 1 ; % Contatore
while ( iter < it ) % Finchè non arriviamo a 50 continua
iter = iter + 1;
% Assegnamo i nuovi valori al personale se ce ne è bisogno
for i = 1:particelle
for j = 1: var
if pos(i,j) < pers(i,j)
pers(i,j) = pos(i,j);
end
end
end
% implementiamo il valore globale
glob = min(pers); % minimo di ogni colonna
glob = repmat(glob,particelle,1); % minimo globale uguale per ogni particella
% implementiamo ancora velocità e posizione
vel = w*vel + c1*((pers-pos)) + c2*((glob-pos));
vel(vel<=-0.99) = -0.1;
pos = pos + vel;
con = 0;
% vediamo se le particelle sono all' interno
for i = 1:particelle
for k = 1:var
if pos(i,k) < li || pos(i,k) > ls
pos(i,:) = rand(1,var);
con = con +1;
end
end
end
% vediamo di nuovo il fitness della singola particella normalizzata
for i = 1: particelle
h(i,:) = x_low + (pos(i,:).*(x_high-x_low)); % normalizziao i limiti delle particelle
fitness_corrente(i,:) = fitness1(h(i,:)); % fitness della nuova popolazione
if fitness_corrente(i,:) < fitness_pers(i,:) % se il fitness della nuova popolazione è minore di quello della vecchia popolazione
fitness_pers(i,:) = fitness_corrente(i,:); % assegna il valore di quel fitness alla nuova posizione
end
end
[temporaneo, m] = min( fitness_pers); % temporaneo serve esclusivamente a vedere se il minimo è diminuito rispetto a prima
if temporaneo < fitness_glob
fitness_glob = temporaneo;
minimo = m; % riassegnamo così anche la posizione del fitness globale
end
end % fine del loop
disp(fitness_glob); % fitness minimo
disp(h(minimo,:));
This is the complete test and the function fitness is this one but you can use another with 5 variables
function [ f ] = fitness(x)
Rs = x(1);
n = x(2);
Io = x(3);
Iirr_ref = x(4);
Rp = x(5);
load datatest_bench1.txt;
V = datatest_bench1(:,1);
I = datatest_bench1(:,2);
for i=1:length(V)
Ieval(i) = I_bench1(Rs,Rp,Io,Iirr_ref,n,273.15+45,V(i));
f(i) = (Ieval(i)-I(i));
end
f = mean(abs(Ieval(i)-I(i)));
end
you can easily do this by setting your minimum as a vector that iterates with your function, for example:
for a = 1:10
number = rand(10);
minimum(a) = min(number);
end
at the end you will have the minimum as a vector that have the same length as the time you have iterated. You can then do another minimum on the vector to obtain the minimum of the whole iteration process.
In your case, you can simply put the iterator in to calling the function; if you are using while, you could put a constant (initially set to 1) and add one to it each time and use it as your vector index.
a = 1;
while (some condition)
conditions
[temp(a), m(a)] = min (fitness_pers);
a= a+1;
end

Get symbolic expression from residue result

Using the residue function, I get the result as some vector variables:
[r,p,k] = residue(b,a)
Is there any way to build a symbolic expression (on the variable of my choice, e.g. 'x') from the return result, like:
eq = residue2sym(r,p,k)
pretty(eq)
In the end I implemented it myself:
function eq = residue2sym( R,P,K )
syms s
eq = 0;
lastR = NaN;
lastP = NaN;
multiplicityCounter = 1;
for i = 1:length(R)
rc = R(i);
pc = P(i);
if(~isnan(lastP) )
if(pc == lastP && abs(lastR) < 1e-15) % Quando existe multiplicidade, o R correspondente ao primeiro P
% da multiplicidade deveria
% ser 0, mas estranhamente
% aparece como -4.4409e-16.
% O que deveria ser uma
% comparação com 0 então
% vira uma comparação para
% um módulo bem pequeno
multiplicityCounter = multiplicityCounter + 1;
else
eq = eq + lastR/(s - lastP)^multiplicityCounter;
multiplicityCounter = 1;
end
end
lastR = rc;
lastP = pc;
end
if(~isnan(lastP))
eq = eq + lastR/(s - lastP)^multiplicityCounter;
end
if(~isempty(K))
eq = eq + sum(s.^(0:length(K)));
end
eq = vpa( eq, 2);
end