Matlab - inputs must be scalar when using linspace
6 views (last 30 days)
Show older comments
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):
0 Comments
Answers (2)
Stephen23
on 8 Nov 2023
Edited: Stephen23
on 8 Nov 2023
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 Comments
Stephen23
on 8 Nov 2023
"I agree that this particular functionality of find() is not a good programming design."
I have no problem with FIND.
Star Strider
on 8 Nov 2023
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);
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
.
0 Comments
See Also
Categories
Find more on Earth and Planetary Science in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!