Related
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
I've encountered a serious problem whan compiling my math work on matlab so can someone help me with this error so this is the matlab code:
% Main program for solving the system F C
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear X;
clear x;
clear y;
clear z;
clear U;
clear V;
clear W;
clear MSx;
clear MSy;
clear MSz;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Données du problème
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N = input('Donner le nombre des points de discretisation dans le temp N=');
a = 0;
b = 50;
T = b-a;
k = T/N;
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x = 1;
y = 1.5;
z = 0.3;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
t = zeros(N+1,1);
for n = 1:N+1
t(n) = (n-1)*k;
end
MSx = zeros(N+1,1);
MSy = zeros(N+1,1);
MSz = zeros(N+1,1);
%
MSx(1,1) = x;
MSy(1,1) = y;
MSz(1,1) = z;
%
U = x;
V = y;
W = z;
%
X = zeros(3,1);
X = [U; V; W];
%
T1 = 0.2*N/T;
T2 = 0.5*N/T;
%
for n = 1:T1
t(n) = (n-1)*k;
%
Un = U;
Vn = V;
Wn = W;
%
X = [Un; Vn; Wn];
%
U = U + k*MSy(n,1)-k*8*MSx(n,1);
%
V = V+k*MSz(n,1)-k*1.02*MSy(n,1);
%
W = W+ k*[cos(sqrt(2)*t(n))+cos(sqrt(3)*t(n))+1/(1+t(n)^2)-(1/(1+t(n)^2)-3.02)*MSz(n,1)+(9.02*(1/(1+t(n)^2)-1)-1.02)*MSy(n,1)- 64*(1/(1+t(n)^2)-1)*MSx(n,1)-0.0004*sin(sqrt(2)*t(n))*(MSy(n,1)-8*MSx(n,1))
-0.0001*cos(sqrt(3)*t(n))*(abs(MSx(1,1)+1)-abs(MSx(1,1)-1)+abs(MSx(1,1)+1)-abs(MSx(1,1)-1))];
%
MSx(n+1,1) = U;
MSy(n+1,1) = V;
MSz(n+1,1) = W;
end
%U = MSx(T1+1,1);
%V = MSy(T1+1,1);
%W = MSz(T1+1,1);
%
for n = T1+1:T2
t(n) = (n-1)*k;
%
Un = U;
Vn = V;
Wn = W;
%
X = [Un; Vn; Wn];
%
U = U+k*(MSy(n,1)-8*MSx(n,1));
V = V+k*(MSz(n,1)-1.02*MSy(n,1));
W = W+ k*[cos(sqrt(2)*t(n))+cos(sqrt(3)*t(n))+1/(1+t(n)^2)-(1/(1+t(n)^2)-3.02)*MSz(n,1)+(9.02*(1/(1+t(n)^2)-1)-1.02)*MSy(n,1)- 64*(1/(1+t(n)^2)-1)*MSx(n,1)-0.0004*sin(sqrt(2)*t(n))*(MSy(n,1)-8*MSx(n,1))
-0.0001*cos(sqrt(3)*t(n))*(abs(MSx(1,1)+1)-abs(MSx(1,1)-1)+abs(MSx(n-T1,1)+1)-abs(MSx(n-T1,1)-1))] ;
%
%
MSx(n+1,1) = U;
MSy(n+1,1) = V;
MSz(n+1,1) = W;
end
%V = MSy(T2+1,1);
%W = MSz(T2+1,1);
%
for n = T2+1:N
t(n) = (n-1)*k;
%
Un = U;
Vn = V;
Wn = W;
%
X = [Un;Vn;Wn];
%
U = U+k*(MSy(n,1)-8*MSx(n,1));
%
V = V+k*(MSz(n,1)-1.02*MSy(n,1));
%
W = W+ k*[cos(sqrt(2)*t(n))+cos(sqrt(3)*t(n))+1/(1+t(n)^2)-(1/(1+t(n)^2)-3.02)*MSz(n,1)+(9.02*(1/(1+t(n)^2)-1)-1.02)*MSy(n,1)- 64*(1/(1+t(n)^2)-1)*MSx(n,1)-0.0004*sin(sqrt(2)*t(n))*(MSy(n,1)-8*MSx(n,1))
-0.0001*cos(sqrt(3)*t(n))*(abs(MSx(n-T2,1)+1)-abs(MSx(n-T2,1)-1)+abs(MSx(n-T1,1)+1)-abs(MSx(n-T1,1)-1))];
%
MSx(n+1,1) = U;
MSy(n+1,1) = V;
MSz(n+1,1) = W;
end
%
tv = t(1:1:N+1,1);
tv1 = t(1:1:N+1,1);
Su = MSx(1:1:N+1,1);
Sv = MSy(1:1:N+1,1);
Sw = MSz(1:1:N+1,1);
plot(tv,Su,'-')
hold all
plot(tv,Sv,'-')
hold all
plot (tv, Sw,'-')
So when it ask me to give an input like:
"Donner le nombre des points de discretisation dans le temp N="
I give it a number like 50000 so it gives me that error :
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
Error in third (line 75)
MSz(n+1,1) = W;
It is because your W is not a singleton, which means a scalar in this case.
You wrote W as
W = W+ k*[cos(sqrt(2)*t(n))+cos(sqrt(3)*t(n))+1/(1+t(n)^2)-(1/(1+t(n)^2)-3.02)*MSz(n,1)+(9.02*(1/(1+t(n)^2)-1)-1.02)*MSy(n,1)- 64*(1/(1+t(n)^2)-1)*MSx(n,1)-0.0004*sin(sqrt(2)*t(n))*(MSy(n,1)-8*MSx(n,1))
-0.0001*cos(sqrt(3)*t(n))*(abs(MSx(1,1)+1)-abs(MSx(1,1)-1)+abs(MSx(1,1)+1)-abs(MSx(1,1)-1))];
If you want to change line in the middle of an expression, you need to add three dots, i.e. ... at the end of the line.
So you need to replace the line with:
W = W+ k*[cos(sqrt(2)*t(n))+cos(sqrt(3)*t(n))+1/(1+t(n)^2)-(1/(1+t(n)^2)-3.02)*MSz(n,1)+(9.02*(1/(1+t(n)^2)-1)-1.02)*MSy(n,1)- 64*(1/(1+t(n)^2)-1)*MSx(n,1)-0.0004*sin(sqrt(2)*t(n))*(MSy(n,1)-8*MSx(n,1))...
-0.0001*cos(sqrt(3)*t(n))*(abs(MSx(1,1)+1)-abs(MSx(1,1)-1)+abs(MSx(1,1)+1)-abs(MSx(1,1)-1))];
You also have a multiplicity of this problem further down.
I'm trying to perform content-based image retrieval (CBIR) using k-means clustering. I use the PCA function princomp() with a feature vector length of 190.
I have 500 test images in color taken from here. There's 5 categories in total. When I run my code I only get 3 clusters and the images look very different. What am I doing wrong?
Here is my code:
% construction of feature vector
set = [hsvHist autoCorrelogram Moments_Couleur meanAmplitude msEnergy OndelettesMoments];
% add name of image
dataset(k, :) = [set str2double(name)];
handlse.CaracVt = dataset.';
dlmwrite('f:/hellonewday', handlse.CaracVt);
% ACP function
[COEFF, SCORE, latent] = princomp(handlse.CaracVt());
laten = cumsum(latent)./sum(latent)
list = []; o = 1; c = 0;
for kn = 1:length(laten)
if (isempty(list))
list(o, :) = laten(kn);
o = o + 1;
else
for i = 1:length(list)
kki = abs(laten(kn) - list(i));
if (kki > 0.006)
c = c + 1;
end;
end;
if (c == length(list))
list(o, :) = laten(kn);
o = o + 1;
end;
end;
c = 0;
end;
handlse.NmbreCluster = length(list);
disp('The amount of clusters is: ');
disp(handlse.NmbreCluster);
handlse.CaracVt = handlse.CaracVt.';
mat = handlse.CaracVt;
mat(:, end) = [];
[kMeansClusters, c] = kmeans(mat, handlse.NmbreCluster);
dlmwrite('f:/clusters', kMeansClusters);
dlmwrite('f:/centres', c);
disp('kMeansClusters for each image: ');
disp(kMeansClusters);
c = c.';
ko = 1;
for i = 1:handlse.NmbreCluster
array = zeros(1, 191);
c(i, 191) = 0;
array(:, 1) = c(i);
for kp = 1:length(kMeansClusters)
if (i == kMeansClusters(kp))
ko = ko + 1;
array(ko, :) = handlse.CaracVt(kp, :);
end
end;
myArray{i} = array;
ko = 1;
end;
disp(myArray);
uisave('myArray', 'dataset');
I'm trying to vectorize the 2 inner nested for loops, but I can't come up with a way to do this. The FS1 and FS2 functions have been written to accept argument for N_theta and N_e, which is what the loops are iterating over
%% generate regions
for raw_r=1:visual_field_width
for raw_c=1:visual_field_width
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r^2+c^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
for nt=1:N_theta
for ne=1:N_e
regions(raw_r, raw_c, nt, ne) = ...
FS_1(nt-1,a,N_theta) * ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
end
end
end
end
Ideally, I could replace the two inner nested for loops by:
regions(raw_r,raw_c,:,:) = FS_1(:,a,N_theta) * FS_2(:,N_e,e0_in_deg,e_max);
But this isn't possible. Maybe I'm missing an easy fix or vectorization technique? e0_in_deg and e_max are parameters.
The FS_1 function is
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)/N;
theta = theta + w/4;
if n==0 && theta>(3/2)*pi
theta = theta - 2*pi;
end
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
the FS_2 function is
function g = FS_gne(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
and the FS_f function is
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
I had to assume values for the constants, and then used ndgrid to find the possible configurations and sub2ind to get the indices. Doing this I removed all loops. Let me know if this produced the correct values.
function RunningFunction
%% generate regions
visual_field_width = 10;
center_r = 2;
center_c = 3;
deg_per_pixel = 17;
N_theta = 2;
N_e = 5;
e0_in_deg = 35;
e_max = 17;
[raw_r, raw_c, nt, ne] = ndgrid(1:visual_field_width, 1:visual_field_width, 1:N_theta, 1:N_e);
ind = sub2ind(size(raw_r), raw_r, raw_c, nt, ne);
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r.^2+c.^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
regions(ind) = ...
FS_1(nt-1,a,N_theta) .* ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
regions = reshape(regions, size(raw_r));
end
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)./N;
theta = theta + w/4;
theta(n==0 & theta>(3/2)*pi) = theta(n==0 & theta>(3/2)*pi) - 2*pi;
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
end
function g = FS_2(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
end
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
end
I am struggling to convert a function, which I require for my civil engineering project, from symbolic expression. I need to use fzero to find the root of the function. Here H should be the variable and I need to find out the value of H. The function goes like
function x_c = f_x_c(s,H0,VA,Lo,qc,EAo,NF,Sj,Fj)
if (s < 0) || (s > Lo)
disp('The value of s is invalid')
disp(['s = ' num2str(s)]);
return
end
C1 = H/qc;
if NF == 0
n = 0;
sn = 0;
sum_Fj = 0;
end
if NF >= 1
Sj_Q = [0; Sj; Lo];
%Determine n and sn if 0 <= s < Lo:
if s < Lo
STOP = 0;
k = 0;
while STOP == 0
k = k + 1;
if (s >= Sj_Q(k,1)) && (s < Sj_Q((k + 1),1))
STOP = 1;
end
end
n = k - 1;
sn = Sj_Q(k,1);
end
%Determine n and sn if s = Lo:
if s == Lo
n = NF;
sn = Sj(NF,1);
end
sum_Fj = sum(Fj(1:n,1));
end
x_c = (H/EAo)*s;
x_c = x_c + C1*asinh((qc*s - VA + sum_Fj)/H) + ...
- C1*asinh((qc*sn - VA + sum_Fj)/H);
for j = 1:n
sk = Sj_Q((j + 1),1);
sk_1 = Sj_Q(j,1);
sum_Fj = sum(Fj(1:(j - 1)));
x_c = x_c + ...
+ C1*asinh((qc*sk - VA + sum_Fj)/H) + ...
- C1*asinh((qc*sk_1 - VA + sum_Fj)/H);
end
I want to use this f_x_c.m file in the main file where I will find the roots of this equation.
Could someone guide me how I can do that?
I have tried doing it using the following code but I wasn't successful.
if (s < 0) || (s > Lo)
disp('The value of s is invalid')
disp(['s = ' num2str(s)]);
return
end
C1 = #(H) (H/qc);
if NF == 0
n = 0;
sn = 0;
sum_Fj = 0;
end
if NF >= 1
Sj_Q = [0; Sj; Lo];
%Determine n and sn if 0 <= s < Lo:
if s < Lo
STOP = 0;
k = 0;
while STOP == 0
k = k + 1;
if (s >= Sj_Q(k,1)) && (s < Sj_Q((k + 1),1))
STOP = 1;
end
end
n = k - 1;
sn = Sj_Q(k,1);
end
%Determine n and sn if s = Lo:
if s == Lo
n = NF;
sn = Sj(NF,1);
end
sum_Fj = sum(Fj(1:n,1));
end
x_c =#(H) (H/EAo)*s;
x_c =#(H) (x_c(H) + (C1(H))*asinh((qc*s - VA + sum_Fj)/H) + ...
- (C1(H))*asinh((qc*sn - VA + sum_Fj)/H));
for j = 1:n
sk = Sj_Q((j + 1),1);
sk_1 = Sj_Q(j,1);
sum_Fj = sum(Fj(1:(j - 1)));
x_c =#(H) (x_c(H) + ...
+ C1(H)*asinh((qc*sk - VA + sum_Fj)/H) + ...
- C1(H)*asinh((qc*sk_1 - VA + sum_Fj)/H));
end
Edit:
I want to solve the following equation in the main file:
equation = f_x_c(inext_length, H0, vertical_reaction, inext_length, qc, EAo, NF, hanger_arc_length, point_hanger_force) + 1400;
% Whatever equation f_x_c returns, I have to add another number to it(like here it is 1400), then solve this equation using fzero.
So, in the main file, I wrote like:
equation = #(H) f_x_c(inext_length, H0, vertical_reaction, inext_length, qc, EAo, NF, hanger_arc_length, point_hanger_force);
equation = #(H) (equation(H) + 1400);
answer = fsolve(equation, H0);
A mock answer to your question probably looks like
function x_c = f_x_c(H,A,B,C,D)
x_c = H*A;
x_c = x_c + B*asinh(C/H) - B*asinh(D/H);
end
and a call to solver is
H = fzero(#(H)(f_x_c(H,1,1,1,1)+1400),1);