Why I cannot get rid of Nan columns

1 view (last 30 days)
Jingyi Liu
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

Answers (2)

Mohammad Sami
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
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
Mohammad Sami on 14 Oct 2020
Thanks Walter. I was not aware of the behaviour.

Sign in to comment.


Image Analyst
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
Jingyi Liu
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
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.

Categories

Find more on Dynamic System Models 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!