Matlab - inputs must be scalar when using linspace

4 ビュー (過去 30 日間)
Dylan
Dylan 2023 年 11 月 8 日
編集済み: Dyuman Joshi 2023 年 11 月 8 日
I am creating a matlab project that can read a dataset that contains initial velocity, angle, and weight. The function below will read the data, calculate the maximum height and total distance that a rocketship will travel with these variables. However, when I go to plot them I use linspace inside the for loop and Matlab returns an error saying that there was an error using linspace because inputs must be scalar and I racked my brain for hours and can't figure out how to fix it. If anyone knows how to fix it, thank you, here is the function:
function [maxHeight, finalDistance, compareHeight] = calculateProjectile(Trajectory1)
% dataset should be a matrix with columns: velocity (m/s), weight (kg), angle (degrees)
% Constants
g = 9.7979; % Acceleration due to gravity (m/s^2)
requiredHeight = 150000; % Height needed to enter low Earth orbit (m)
requiredVelocity = 7890; % Velocity needed to enter low Earth orbit (m/s)
% Extracting data from the dataset
velocity = Trajectory1(:, 1); % m/s
weight = Trajectory1(:, 2); % kg
angle = deg2rad(Trajectory1(:, 3)); % Convert degrees to radians
% Calculate maximum height
maxHeight = (velocity.^2 .* sin(angle).^2) / (2 * g);
% Calculate final distance
finalDistance = (velocity.^2 .* sin(2 * angle)) / g;
% Compare maximum height with required height for orbit
compareHeight = maxHeight >= requiredHeight;
% Compare initial velocity with required velocity for orbit
compareVelocity = velocity >= requiredVelocity;
% Plot the trajectories
figure;
% Plot for spaceships that didn't enter low Earth orbit
subplot(1,2,1);
for i = find(~compareHeight)
%error
t = linspace(0, (2 * velocity(i) .* sin(angle(i))) / g, 100);
x = velocity(i) * cos(angle(i)) * t;
y = velocity(i) * sin(angle(i)) * t - (1/2) * g * t.^2;
plot(x, y);
hold on;
end
line([0, max(finalDistance)], [requiredHeight, requiredHeight], 'Color', 'r', 'LineStyle', '--');
xlabel('Distance (m)');
ylabel('Height (m)');
title('Trajectories (Not in Orbit)');
grid on;
hold off;
% Plot for spaceships that entered low Earth orbit
subplot(1,2,2);
for i = find(compareHeight)
%error
t = linspace(0, (2 * velocity(i) .* sin(angle(i))) / g, 100);
x = velocity(i) * cos(angle(i)) * t;
y = velocity(i) * sin(angle(i)) * t - (1/2) * g * t.^2;
plot(x, y);
hold on;
end
line([0, max(finalDistance)], [requiredHeight, requiredHeight], 'Color', 'r', 'LineStyle', '--');
xlabel('Distance (m)');
ylabel('Height (m)');
title('Trajectories (In Orbit)');
grid on;
hold off;
% Display results
disp('Results:');
disp(['Maximum Height (m): ', num2str(maxHeight)]);
disp(['Final Distance (m): ', num2str(finalDistance)]);
disp(['Comparison with Orbit Height (1 if true, 0 if false): ', num2str(compareHeight)]);
disp(['Comparison with Orbit Velocity (1 if true, 0 if false): ', num2str(compareVelocity)]);
end
And here is the code i use to run it:
data = readmatrix('Trajectory1.xlsx'); % Assuming data.csv is properly formatted
calculateProjectile(data);
This is the file I am reading (sorry, located at top):

回答 (2 件)

Stephen23
Stephen23 2023 年 11 月 8 日
編集済み: Stephen23 2023 年 11 月 8 日
replace this line
for i = find(~compareHeight)
with
for i = reshape(find(~compareHeight),1,[])
The cause is an awful, useless, endlessly bug-causing design-decision of TMW: FOR actually loops over the columns of the array you provide it with. So if you provide it with a column vector (like the output from FIND) then it will iterate exactly once and the loop iterator will be that column vector. Thus in your code i is a non-scalar columm vector... and so is the 2nd input to LINSPACE.
This is a useless, ugly, counter productive "feature" of FOR that no one uses, forces all of us to write more complex code to avoid this "feature" (e.g. reshaping the output of FIND), and causes far more bugs than the three times in the history of MATLAB that anyone has actually used this "feature". But sadly we all have to keep it in mind everytime we write a FOR loop.
  3 件のコメント
Stephen23
Stephen23 2023 年 11 月 8 日
"I agree that this particular functionality of find() is not a good programming design."
I have no problem with FIND.
Dyuman Joshi
Dyuman Joshi 2023 年 11 月 8 日
My bad, typo.

サインインしてコメントする。


Star Strider
Star Strider 2023 年 11 月 8 日
The problem is that the original ‘i’ value in each loop returned a vector, and that vector became the subscript for the ‘velocity’ and ‘angle’ arguments.
I changed your code (in both instances) to start the loops with:
i1 = find(~compareHeight);
for i2 = 1:numel(i1)
...
end
(or whatever is appropriate for them, siunce that differs between the loops) and that solve the original problem.
The remaining problem is the ‘maxHeight’ is a column vector, and that won’t work in the concatenation. I leave that for you to resolve.
data = readmatrix('Trajectory1.xlsx'); % Assuming data.csv is properly formatted
calculateProjectile(data);
Results:
Error using horzcat
Dimensions of arrays being concatenated are not consistent.

Error in solution>calculateProjectile (line 78)
disp(['Maximum Height (m): ', num2str(maxHeight)]);
function [maxHeight, finalDistance, compareHeight] = calculateProjectile(Trajectory1)
% dataset should be a matrix with columns: velocity (m/s), weight (kg), angle (degrees)
% Constants
g = 9.7979; % Acceleration due to gravity (m/s^2)
requiredHeight = 150000; % Height needed to enter low Earth orbit (m)
requiredVelocity = 7890; % Velocity needed to enter low Earth orbit (m/s)
% Extracting data from the dataset
velocity = Trajectory1(:, 1); % m/s
weight = Trajectory1(:, 2); % kg
angle = deg2rad(Trajectory1(:, 3)); % Convert degrees to radians
% Calculate maximum height
maxHeight = (velocity.^2 .* sin(angle).^2) / (2 * g);
% Calculate final distance
finalDistance = (velocity.^2 .* sin(2 * angle)) / g;
% Compare maximum height with required height for orbit
compareHeight = maxHeight >= requiredHeight;
% Compare initial velocity with required velocity for orbit
compareVelocity = velocity >= requiredVelocity;
% Plot the trajectories
figure;
% Plot for spaceships that didn't enter low Earth orbit
subplot(1,2,1);
i1 = find(~compareHeight);
for i2 = 1:numel(i1)
%error
i = i1(i2);
% Vq = velocity(i)
% Aq = angle(i)
t = linspace(0, (2 * velocity(i) .* sin(angle(i))) / g, 100);
x = velocity(i) * cos(angle(i)) * t;
y = velocity(i) * sin(angle(i)) * t - (1/2) * g * t.^2;
plot(x, y);
hold on;
end
line([0, max(finalDistance)], [requiredHeight, requiredHeight], 'Color', 'r', 'LineStyle', '--');
xlabel('Distance (m)');
ylabel('Height (m)');
title('Trajectories (Not in Orbit)');
grid on;
hold off;
% Plot for spaceships that entered low Earth orbit
subplot(1,2,2);
i3 = find(compareHeight);
for i4 = 1:numel(i3)
%error
i = i3(i4);
% Vq = velocity(i)
% Aq = angle(i)
t = linspace(0, (2 * velocity(i) .* sin(angle(i))) / g, 100);
x = velocity(i) * cos(angle(i)) * t;
y = velocity(i) * sin(angle(i)) * t - (1/2) * g * t.^2;
plot(x, y);
hold on;
end
line([0, max(finalDistance)], [requiredHeight, requiredHeight], 'Color', 'r', 'LineStyle', '--');
xlabel('Distance (m)');
ylabel('Height (m)');
title('Trajectories (In Orbit)');
grid on;
hold off;
% Display results
disp('Results:');
% % maxHeight
disp(['Maximum Height (m): ', num2str(maxHeight)]);
disp(['Final Distance (m): ', num2str(finalDistance)]);
disp(['Comparison with Orbit Height (1 if true, 0 if false): ', num2str(compareHeight)]);
disp(['Comparison with Orbit Velocity (1 if true, 0 if false): ', num2str(compareVelocity)]);
end
.

カテゴリ

Help Center および File ExchangeParticle & Nuclear Physics についてさらに検索

製品


リリース

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by