
I want to avoid fractions in my answer to the null space
Show older comments
My code returns the following: N(A) = {[-1/3,0,1,0]^T,[0,1/2,0,1]^T}. I want {[-1,0,3,0]^T,[0,1,0,2]^T} I don't want to just mulitple my answer by three. Is there a way to automatically get the smallest whole number.
% Define matrix A symbolically for exact arithmetic
A = sym([6 8 2 -4;
12 6 4 -3;
18 14 6 -7;
3 4 1 -2]);
%% --- Null space of A: N(A) ---
N_A = null(A); % symbolic exact nullspace
N_A = simplify(N_A); % simplify to reduce fractions and make integers if possible
%% --- Range of A^T: R(A^T) ---
R = rref(A); % row reduce A symbolically
R_rows = R(any(R,2), :); % nonzero rows form row space
R_rows = simplify(R_rows);% simplify to integer form if possible
R_At = R_rows.'; % convert to column vectors
%% --- Display results ---
disp('Basis for N(A) (symbolic, simplified):')
disp(N_A)
disp('Basis for R(A^T) (symbolic, simplified):')
disp(R_At)
Accepted Answer
More Answers (3)
Steven Lord
on 4 Oct 2025
1 vote
Insert
for i = 1:size(N_A,2)
[~,d] = numden(N_A(:,i));
N_A(:,i) = N_A(:,i)*lcm(d);
end
after computing N_A.
1 Comment
gcd to eliminate one line of code? I always get confused between lcm and gcd, so maybe gcd isn't a general solution.
A = sym([6 8 2 -4;
12 6 4 -3;
18 14 6 -7;
3 4 1 -2]);
%% --- Null space of A: N(A) ---
N_A = null(A); % symbolic exact nullspace
for i = 1:size(N_A,2)
N_A(:,i) = N_A(:,i)/gcd(N_A(:,i));
end
N_A
Umar
on 4 Oct 2025
0 votes
Hi @David,
I completely understand your frustration! You mentioned "I don't want to just multiply my answer by three" - and you're absolutely right. Multiplying by 3 would only fix the first vector [-1/3, 0, 1, 0], but your second vector [0, 1/2, 0, 1] needs to be multiplied by 2, not 3. You need an automatic way to get the smallest whole numbers for each vector independently.
The good news: Torsten's solution is exactly what you need, and I've tested it to confirm it works perfectly!
Your Original Problem
Your code returns: N(A) = {[-1/3, 0, 1, 0], [0, 1/2, 0, 1]} You want: N(A) = {[-1, 0, 3, 0], [0, 1, 0, 2]} The challenge: Each vector needs a different scaling factor (multiply by 3 for the first, multiply by 2 for the second), so a single multiplication won't work.
Solution (Tested & Verified)
Important Note: I initially thought you could use null(A, 'r') for a rational basis, but after testing, I discovered that the 'r' (or 'rational') flag only works with numeric matrices, not symbolic ones [3]. When you use sym(), the null() function doesn't accept the rational basis argument.
So Torsten's approach is actually the correct and only reliable method for symbolic matrices. Here's the complete solution:
%% Define matrix A symbolically
A = sym([6 8 2 -4;
12 6 4 -3;
18 14 6 -7;
3 4 1 -2]);
%% --- Null space of A: N(A) --- N_A = null(A); % Symbolic null space (will have fractions)
% Automatically clear fractions - THIS IS THE KEY! for i = 1:size(N_A, 2) [~, d] = numden(N_A(:, i)); % Extract denominators [1] N_A(:, i) = N_A(:, i) * lcm(d); % Scale by LCM [2] end
%% --- Range of A^T: R(A^T) --- R = rref(A); R_rows = R(any(R,2), :); R_At = R_rows.';
% Apply same technique to R(A^T) for consistency for i = 1:size(R_At, 2) [~, d] = numden(R_At(:, i)); R_At(:, i) = R_At(:, i) * lcm(d); end
%% --- Display results ---
disp('Basis for N(A) (no fractions):')
disp(N_A)
disp('Basis for R(A^T) (no fractions):')
disp(R_At)
%% --- Verification ---
disp('Verification: A * N_A = 0')
disp(simplify(A * N_A))
Verified Results
I ran your exact matrix and here are the complete results:

Result Analysis
Basis for N(A) - No fractions, exact integers:
[-1, 0] [ 0, 1] [ 3, 0] [ 0, 2]
This gives you exactly what you wanted: N(A) = {[-1, 0, 3, 0], [0, 1, 0, 2]} Notice how the algorithm automatically applied:
- Vector 1: Scaled by 3 (to clear the 1/3 denominator) -> [-1/3, 0, 1, 0] multiplied by 3 = [-1, 0, 3, 0]
- Vector 2: Scaled by 2 (to clear the 1/2 denominator) -> [0, 1/2, 0, 1] multiplied by 2 = [0, 1, 0, 2]
Each vector received its optimal scaling factor automatically - no manual "multiply by 3" needed!
Basis for R(A^T) - All integers:
[3, 0] [0, 2] [1, 0] [0, -1]
The same fraction-clearing technique applied to R(A^T) ensures all basis vectors are integers. This makes your output clean and consistent across both null space and range calculations.
Verification: A multiplied by N(A) = 0 (Perfect!)
[0, 0] [0, 0] [0, 0] [0, 0]
The zero matrix confirms that our integer basis vectors are indeed in the null space of A. This verification is crucial - it proves mathematically that our fraction-clearing didn't change the fundamental subspace, only the representation of the basis vectors.
Why This Is The Smart Approach
This solution addresses your exact concern: "*Is there a way to automatically get the smallest whole number?"*
Critical Discovery: After testing various approaches, including null(A, 'r') and null(A, 'rational'), I found that: * The 'rational' flag only works with numeric matrices [3] * Even with numeric matrices, it returns floating-point approximations (like 0.3333), not exact integers * For symbolic matrices (which you're using with sym()), the only way to get exact integers is to use the numden + lcm approach
How it works:
1. numden(N_A(:, i)) extracts all denominators from column i [1] * Column 1 has denominators: [3, 1, 1, 1] * Column 2 has denominators: [1, 2, 1, 1] 2. lcm(d) finds the least common multiple of those denominators [2] * Column 1: LCM([3,1,1,1]) = 3 -> multiply first vector by 3 * Column 2: LCM([1,2,1,1]) = 2 -> multiply second vector by 2 3. Each vector gets its own optimal scaling - not a fixed value like "multiply by 3"
This is exactly what you meant by "automatically get the smallest whole number" - the LCM ensures each vector is scaled by the minimal factor needed to clear all fractions!
Why Steven and Torsten's Answers Were Spot-On
After exploring alternatives (including the 'rational' basis option which doesn't work for symbolic matrices [3]), I can confirm: * Steven Lord correctly identified that numden and lcm are the key functions [1][2] * Torsten provided the exact implementation you need - it's the definitive solution for symbolic workflows The beauty of this approach: * Automatic - no manual calculation needed * Optimal - uses the smallest multiplier for each vector * General - works for any symbolic null space * Clean - just 4 lines of code to insert after null(A) * Works with symbolic math - unlike the 'r' flag which only works with numeric matrices
Final Recommendation
Simply insert these 4 lines after computing your null space: for i = 1:size(N_A, 2) [~, d] = numden(N_A(:, i)); N_A(:, i) = N_A(:, i) * lcm(d); end
And you'll automatically get the smallest integer basis vectors - no guessing, no arbitrary multiplications!
Hope this completely resolves your issue!
References:
[1] MATLAB Documentation: numden - Extract numerator and denominator https://www.mathworks.com/help/symbolic/sym.numden.html "numden converts A to a rational form where the numerator and denominator are relatively prime polynomials with integer coefficients."
[2] MATLAB Documentation: lcm - Least common multiple https://www.mathworks.com/help/symbolic/sym.lcm.html "The least common multiple (LCM) of symbolic expressions is the smallest expression divisible by all input expressions."
[3] MATLAB Documentation: null - Null space of matrix https://www.mathworks.com/help/matlab/ref/null.html "The rational basis for the null space null(A,"rational") is obtained from the reduced row echelon form of A, as calculated by rref." (Note: This option is only available for numeric matrices, not symbolic matrices. The symbolic null function does not accept this argument.)
1 Comment
Umar
on 5 Oct 2025
Hi @ Catalytic,
Rather than flagging, I would encourage you to consider contributing your insights or providing an alternative method for solving the problem for @David Cole. MathWorks' goal is to foster collaboration and learning, so offering suggestions and clarifications would help us all improve and build more effective solutions together.
I’m looking forward to your feedback on this updated approach and hope we can collaborate to refine and share solutions with the community.
Categories
Find more on C Shared Library Integration 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!
