Why is my script returning NaN for values of an array ONLY when used in a for loop?

44 views (last 30 days)
The problem I am having is that I'm trying to process some data and make some graphs out of it, but some of the arrays that I create will return NaN at specific indices, even though I know that there should not be a problem. I know this because I do the calculation outside of the loop (commenting out the loop, and setting the loop variable to the specific value with which I'm having the issue, then running the script again), and I get the expected result. Does it have something to do with the loop? I'm almost certain that it isn't the data, based on the fact that I can do the calculation outside of the loop and have no problems.
filenames = {'shoulder_cal_1', 'shoulder_cal_2', 'shoulder_cal_3', 'shoulder_cal_4', 'shoulder_cal_5', 'shoulder_cal_6'};
% filenames = {'elbow_cal_1', 'elbow_cal_2', 'elbow_cal_3', 'elbow_cal_4', 'elbow_cal_5', 'elbow_cal_6'};
motor_volts = 6; % Set to 6 for shoulder, set to 7 for elbow
motor_torque = 10; % Set to 10 for shoulder, set to 11 for elbow
world_force_x = 8;
world_force_y = 9;
x_offset = 0.0; % from computer, to convert to coordinates with
y_offset = -0.65; % origin at the motor (in meters)
count = 0;
% for j = 1; % For debugging
for j = (1:length(filenames)); % Option that's actually used
count = count + 1;
disp(count);
file = strcat('File name that I know works');
data = dlmread(file);
data_length = size(data,1);
voltages = ones(1,51);
avg_forces = ones(1,51);
avg_actual_torques = ones(1,51);
avg_motor_torques = ones(1,51);
index = 0;
% for k = 0.300; % For debugging NaN
for k = (0.0000:0.1000:5.0000); % All of the possible voltage values (from volts_torque2 program)
index = index + 1;
force_mag_vals = [];
actual_torque_vals = [];
motor_torque_vals = [];
for i = (1:data_length);
if data(i, motor_volts) == k;
x_pos = (data(i, 2)/1000.0) + x_offset; % /1000 to convert mm to m
y_pos = (data(i, 3)/1000.0) + y_offset;
force_mag = sqrt(data(i, world_force_x)^2 + data(i, world_force_y)^2);
force_mag_vals = [force_mag_vals force_mag];
motor_torque_vals = [motor_torque_vals data(i, motor_torque)];
torque_calc = data(i, world_force_y)*x_pos - data(i, world_force_x)*y_pos;
actual_torque_vals = [actual_torque_vals torque_calc];
end
end
% Calculates the average of the desired quantity at a specific voltage level
avg_forces(index) = mean(force_mag_vals);
avg_motor_torques(index) = mean(motor_torque_vals);
avg_actual_torques(index) = mean(actual_torque_vals);
voltages(index) = k;
end
% % Creation of various graphs that I know work
end
I believe that when the script returns NaN in avg_forces, it is because it performs mean(force_mag_vals) but force_mag_vals is empty for some reason. Perhaps there is another reason. Can anyone see anything obvious as to why my script is doing this?
  2 Comments
rkepp12
rkepp12 on 30 Jun 2016
Edited: rkepp12 on 30 Jun 2016
I should emphasize more: I am able to get the values that I need when I turn off the loop in the above code and just set k to the values for which I am having problems. It is only when I am looping through values of k that NaN pops up in the vectors avg_forces, avg_motor_torques, and avg_actual_torques.
rkepp12
rkepp12 on 30 Jun 2016
Another comment on debugging: I have figured out that for these particular values, when the loop is initiated, values do not get added to the "vals" vectors for some reason. So when I take a mean later on, it just returns NaN. Does anyone know why values would not be added when k = (0.0:0.1000:5.000) but are added when k = 0.3000 only?

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 30 Jun 2016
You are testing for floating point equality instead of testing for a value "close enough". Different methods of calculating floating point values can end up with slightly different bottom bits. For example, linspace() uses a different algorithm than : does, in order to adjust for accumulated round-off error.
Because of accumulated round-off error,
k = 0.0000:0.1000:5.0000
is not the same as
k = (0:1:50) / 10;
differing at
0.3, 0.6, 0.7, 1.2, 1.4, 1.7, 1.9, 2.3, 2.4, 2.6, 2.7, 3.1, 3.6
You should be testing for equality to within a tolerance. You might want to use ismembertol()

More Answers (1)

Samuel Vergara
Samuel Vergara on 30 Jun 2016
Hi. I think you have a problem reading some files information. Make sure that "data" variable is a numeric matrix. You can run your program until this:
data = dlmread(file);
And then check the values in the workspace. Regards,
  1 Comment
rkepp12
rkepp12 on 30 Jun 2016
Thanks for the response! I tried checking the data in the following way, and it seems to turn out okay. I used a few ways to confirm that all of the entries in the matrix are numbers:
if isnan(data) == zeros(size(data))
disp('Data is okay')
end
When I did this, it returns 'Data is okay'. Then, I did the following:
if isnumeric(data) == ones(size(data))
disp('Data is okay')
end
And once again, it displayed 'Data is okay'. Is there a better way to test for if the values in the matrix are not numeric?

Sign in to comment.

Categories

Find more on Graphics Object Programming in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!