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.
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!