MATLAB Answers

# Why I cannot get rid of Nan columns

2 views (last 30 days)
Jingyi Liu on 13 Oct 2020
Commented: Image Analyst on 14 Oct 2020
function [Q, R] = grams(A)
[m, n] = size(A);
Q = zeros(m,n);
Asave = A;
if norm(A(:,1)) < sqrt(eps)
error('The first Column of A is zero vector')
end
Q(:,1) = A(:,1)/norm(A(:,1));
for j = 2:n
for k = 1:j-1
mult = (A(:, j)'*Q(:, k)) / (Q(:, k)'*Q(:, k));
A(:, j) = A(:, j) - mult*Q(:, k);
end
%if norm(A(:, j)) < sqrt(eps)
%error('Columns of A are linearly dependent.')
%end
Q(:, j) = A(:, j) / norm(A(:, j));
end
%if norm(Q'(:,n)) <sqrt(eps)
%B = zeros(m, n-1);
%B(:,1:n-1) = Q'(:,1:n-1);
%end
R = Q'*Asave;
for i = 2:n
if norm(R(:,i))<sqrt(eps)
R (:,i) = [];
end
end

#### 0 Comments

Sign in to comment.

### Answers (2)

Mohammad Sami on 13 Oct 2020
Edited: Mohammad Sami on 13 Oct 2020
The issue is in the if statements. You are doing a vector comparison, which will return a logical vector. If statement requires a scalar value. To convert it to a logical scalar use function all or any.
For example
if true
if all(norm(A(:,1)) < sqrt(eps))
error('The first Column of A is zero vector')
end
%%%%%%%other code
if all(norm(R(:,i))<sqrt(eps))
R (:,i) = [];
end
end

#### 2 Comments

Walter Roberson on 14 Oct 2020
If statement requires a scalar value.
That is not correct.
if and while are considered true if all the elements to be tested are non-zero. To put that another way, they are considered false if even one element being tested is 0. false is 0.
Effectively, if and while have a built-in all()
However, testing a non-scalar is often a sign that the programmer did not realize that a non-scalar was possible at that point, so it is often a sign that the code will not work as intended for non-scalar values.
Sometimes, programmers who are aware that the test is effectively all(), will rely upon that behavior, knowing that non-scalars are possible at that point in the code. That kind of code is permitted, but it is not recommended: code that explicitly uses all() or any() is much much more readable to other people.
Mohammad Sami on 14 Oct 2020
Thanks Walter. I was not aware of the behaviour.

Sign in to comment.

Image Analyst on 13 Oct 2020
To get rid of columns with a nan anywhere in the column, you can do this:
% Create sample data with some nans in there.
A = magic(9);
A(2,3) = nan;
A(3,5) = nan;
A(6,7) = nan
goodColumns = ~any(isnan(A), 1) % Columns without nan in any of the rows.
AGood = A(:, goodColumns)
Of course you can assign it back to A instead of AGood if you want to replace the original A.
You'll see:
A =
47 58 69 80 1 12 23 34 45
57 68 NaN 9 11 22 33 44 46
67 78 8 10 NaN 32 43 54 56
77 7 18 20 31 42 53 55 66
6 17 19 30 41 52 63 65 76
16 27 29 40 51 62 NaN 75 5
26 28 39 50 61 72 74 4 15
36 38 49 60 71 73 3 14 25
37 48 59 70 81 2 13 24 35
goodColumns =
1×9 logical array
1 1 0 1 0 1 0 1 1
AGood =
47 58 80 12 34 45
57 68 9 22 44 46
67 78 10 32 54 56
77 7 20 42 55 66
6 17 30 52 65 76
16 27 40 62 75 5
26 28 50 72 4 15
36 38 60 73 14 25
37 48 70 2 24 35

#### 4 Comments

Show 1 older comment
Image Analyst on 13 Oct 2020
You forgot to attach your data and function code (with my suggestion coded in there), so how can I fix it for you???
Jingyi Liu on 14 Oct 2020
Sorry.....
Even though I changed some code at the very last part, I think I couldn't change the output. Not just get rid of the Nan, I even could not add 1 to everything.
I am really new to this , maybe made some silly mistakes.
Please help me
Thank you so much
Appreciate your time and patient
function [Q, R] = grams(A)
[m, n] = size(A);
Q = zeros(m,n);
Asave = A;
if norm(A(:,1)) < sqrt(eps)
error('The first Column of A is zero vector')
end
Q(:,1) = A(:,1)/norm(A(:,1));
for j = 2:n
for k = 1:j-1
mult = (A(:, j)'*Q(:, k)) / (Q(:, k)'*Q(:, k));
A(:, j) = A(:, j) - mult*Q(:, k);
end
%if norm(A(:, j)) < sqrt(eps)
%error('Columns of A are linearly dependent.')
%end
Q(:, j) = A(:, j) / norm(A(:, j));
end
R = Q'*Asave;
goodColumns = ~any(isnan(R), 1);
AGood = R(:, goodColumns);
Image Analyst on 14 Oct 2020
Jingyi, you still forgot to attach your data like I directly asked for. What are you passing in for A?
Why should I expect any column of R to have a nan in it? I imagine it won't always have nans in them. It might have nans in them only for certain A matrices. So what A did you pass in that gave a nan in R?
And you compute AGood but don't do anything with it. You return Q and R. Do you want R to be the good columns of R, like
R = R(:, goodColumns); % Instead of AGood.

Sign in to comment.

### Community Treasure Hunt

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

Start Hunting!