Need help resolving this error message
1 回表示 (過去 30 日間)
古いコメントを表示
I keep getting this error message in my code and am not sure how to fix it. Can someone please edit the code to resolve this?
% Define Variables
global seg_length m g k b_type num_nodes beam_init connect_mat row_index col_index seg_length_matrix
seg_length = 0.1; % segment length (m)
m = 2; % node mass (kg)
g = 9.81; % acceleration due to gravity (m/s^2)
k = 10000; % spring constant
b_type = 1;
% A2
% User Input
num_nodes = input('Enter the number of nodes. Please make sure your input is an even number greater than 4:');
% Error statement if input is incorrect
if isempty(num_nodes) || num_nodes <= 4 || rem(num_nodes, 2) ~= 0
error('Invalid input. Please enter an even number greater than 4.');
end
% A3
% Populating coordinates of initial beam in a 2D array
beam_init = zeros(num_nodes, 2);
for i = 1:num_nodes
if mod(i, 2) == 0
beam_init(i,1) = (i-2)*seg_length/2;
beam_init(i,2) = -0.1;
else
beam_init(i,1) = (i-1)*seg_length/2;
beam_init(i,2) = 0;
end
end
% A4
% Create a connectivity matrix that describes the connectivity between the nodes
connect_mat = zeros(num_nodes, num_nodes);
for i = 1:num_nodes
connect_mat(i,i+1) = 1;
connect_mat(i,i+2) = 1;
end
connect_mat = connect_mat(1:num_nodes,1:num_nodes);
% A5
% Display the connectivity matrix using image function
figure;
image(connect_mat, 'CDataMapping', 'scaled');
title('Connectivity Matrix');
axis off
% A6
% Define matrix of segment lengths of the beam
seg_length_matrix = zeros(num_nodes, num_nodes);
for i = 1:num_nodes
if mod(i,2) == 0
seg_length_matrix(i,i+1) = seg_length*sqrt(2);
seg_length_matrix(i,i+2) = seg_length;
else
seg_length_matrix(i,i+1) = seg_length;
seg_length_matrix(i,i+2) = seg_length;
end
end
seg_length_matrix = seg_length_matrix(1:num_nodes,1:num_nodes);
% A7
[row_index, col_index] = find(seg_length_matrix > 0, 2*num_nodes-3);
% A10
% Displaying the initial beam plot
figure
a = plot_beam(beam_init);
title('Initial Beam Plot')
% Part B
A = [];
b = [];
Aeq = [];
beq = [];
if b_type == 1
lb = -Inf([num_nodes*2,1]);
lb(1) = 0; lb(2) = 0;
lb(num_nodes-1) = beam_init(num_nodes,1);
lb(num_nodes) = beam_init(num_nodes,1);
lb(num_nodes+1) = 0;
lb(num_nodes+2) = -seg_length;
lb(end-1) = 0;
lb(end) = -seg_length;
ub = Inf([num_nodes*2,1]);
ub(1) = 1e-5; ub(2) = 1e-5;
ub(num_nodes-1) = beam_init(num_nodes,1)+1e-5;
ub(num_nodes) = beam_init(num_nodes,1)+1e-5;
ub(num_nodes+1) = 1e-5;
ub(num_nodes+2) = -seg_length+1e-5;
ub(end-1) = 1e-5;
ub(end) = -seg_length+1e-5;
elseif b_type == 0
lb = -Inf([num_nodes*2,1]);
lb(1) = 0; lb(2) = 0;
lb(num_nodes+1) = 0;
lb(num_nodes+2) = -seg_length;
ub = Inf([num_nodes*2,1]);
ub(1) = 1e-5; ub(2) = 1e-5;
ub(num_nodes+1) = 1e-5;
ub(num_nodes+2) = -seg_length+1e-5;
end
beam_eqm = fmincon(@calc_energy, beam_init, A, b, Aeq, beq, lb, ub);
figure
plot_beam(beam_eqm);
title('Equilibrium Beam', 'fontsize', 17);
text = '\nThe energy in the intial beam is %4.3f J\n'; fprintf(text, calc_energy(beam_init));
text = 'The energy in the equilibrium beam is %4.3f J\n'; fprintf(text, calc_energy(beam_eqm));
%A8)
% Computing the segment lengths of a beam given its node coordinates
function segment_lengths = updated_segment_lengths(node_coordinates)
% Calculates the lengths of each segment in the beam from the node coordinates
num_nodes = size(node_coordinates, 1);
segment_lengths = zeros(num_nodes, num_nodes);
for i = 1:num_nodes
for j = i+1:num_nodes
segment_lengths(i,j) = norm(node_coordinates(i,:) - node_coordinates(j,:));
segment_lengths(j,i) = segment_lengths(i,j);
end
end
end
function a = plot_beam(beam)
% Get necessary global variables
global row_index col_index beam_init seg_length_matrix num_nodes connect_mat
% Calculate change in segment lengths
seg_length_function = updated_segment_lengths(beam); % Call function to calculate segment lengths for current beam
seg_length_change = seg_length_function - seg_length_matrix; % Calculate change in segment lengths
% Create change in segment length matrix
seg_length_change_matrix = zeros(num_nodes,num_nodes);
for i = 1:size(row_index,1)
seg_length_change_matrix(row_index(i),col_index(i)) = seg_length_change(row_index(i),col_index(i)); % Populate matrix with changes in segment lengths
end
seg_length_change_matrix = round(seg_length_change_matrix,10); % Round matrix to 10 decimal places
% Create graph
c = graph(connect_mat,'upper'); % Create graph using connection matrix and set upper triangle of matrix as edges
beam_row_ind = beam(:,1); % Get beam row indices
beam_col_ind = beam(:,2); % Get beam column indices
% Plot graph
a = plot(c, 'XData', beam_row_ind, 'YData', beam_col_ind, 'EdgeAlpha', 1, 'EdgeColor', 'k', 'LineWidth', 4, 'NodeColor', 'k', 'NodeFontSize', 1, 'MarkerSize', 10); % Plot graph with specified properties
hold on;
axis off;
longest_beam = max(beam_init);
shortest_beam = min(beam);
x_start = 0;
x_end = longest_beam(1);
y_start = shortest_beam(2) - 0.1;
y_end = 0.125;
line_props = {'LineWidth', 3};
xlim([x_start, x_end]);
ylim([y_start, y_end]);
line([x_start, x_end], [0, 0], 'Color', 'k', line_props{:});
line([x_start, x_start], [y_start, 0], 'Color', 'k', line_props{:});
line([x_end, x_end], [y_start, 0], 'Color', 'k', line_props{:});
% Add legend
txt = {'Black: No change', 'Blue: Tension', 'Red: Compression'};
text(0.03, -0.2, txt); % Add text to specified location
% Highlight edges based on change in segment lengths
[row_ind_neg, col_ind_neg] = find(seg_length_change_matrix < 0); % Find row and column indices of negative changes in segment length
[row_ind_pos, col_ind_pos] = find(seg_length_change_matrix > 0); % Find row and column indices of positive changes in segment length
for i = 1:size(row_ind_neg,1)
highlight(a, [row_ind_neg(i), col_ind_neg(i)], 'EdgeColor', 'r'); % Highlight edges with negative changes in segment length with red color
end
for i = 1:size(row_ind_pos,1)
highlight(a, [row_ind_pos(i), col_ind_pos(i)], 'EdgeColor', 'b'); % Highlight edges with positive changes in segment length with blue color
end
end
function Energy = calc_energy(beam_init)
global connect_mat seg_lengths g m k
Energy = g*m*sum(beam_init(:,2)) + sum(1/2*sum(k*((connect_mat.*(updated_segment_lengths(beam_init))-seg_lengths).^2)));
end
0 件のコメント
回答 (1 件)
Walter Roberson
2023 年 4 月 10 日
global seg_length m g k b_type num_nodes beam_init connect_mat row_index col_index seg_length_matrix
You create a global named seg_length
global connect_mat seg_lengths g m k
You use a global named seg_lengths . With a final s . You do not initialize a global seg_lengths (with a final s) anywhere, so it will be empty.
We recommend that you fix this by getting rid of global variables.
2 件のコメント
Walter Roberson
2023 年 4 月 10 日
I already posted the link showing how to handle the situation: pass the values of the variables down as many levels of required.