Skip to main content
Engineering LibreTexts

14.2: Well-Determined Fully Specified System

  • Page ID
    122656
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\dsum}{\displaystyle\sum\limits} \)

    \( \newcommand{\dint}{\displaystyle\int\limits} \)

    \( \newcommand{\dlim}{\displaystyle\lim\limits} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \(\newcommand{\longvect}{\overrightarrow}\)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Finding the Solution of a Well-Determined, Fully Specified Nth-Order Linear System in Python

    A linear system of equations is a set of n linear equations with n unknown variables. A system is considered well-determined and fully specified if it has exactly one unique solution. This typically means:

    1. Number of Equations = Number of Variables: There are as many independent equations as there are unknown variables.
    2. Non-Singular Coefficient Matrix: The determinant of the coefficient matrix is non-zero. If the determinant is zero, the matrix is singular, and the system either has no solutions or infinitely many solutions.

    General Form

    An n-th order linear system can be represented in matrix form as:

    \[Ax = b\]

    Where:

    • \(A\) is the \(n \times n\) coefficient matrix containing the coefficients of the variables.
    • \(x\) is the \(n \times 1\) variable vector containing the unknown variables \(\left (x_1​,x_2​,…,x_n​ \right ) \).
    • \(b\) is the \(n \times 1\) constant vector containing the constants on the right-hand side of the equations.

    For example, a 3rd order system would look like:

    \[ \begin{align}
    \begin{split}
    a_{11} x_1 + a_{12} x_2 + a_{13} x_3 & = b_1 \\
    a_{21} x_1 + a_{22} x_2 + a_{23} x_3 & = b_2 \\
    a_{31} x_1 + a_{32} x_2 + a_{33} x_3 & = b_3
    \end{split}
    \end{align} \]

    In matrix form:

    \[ \begin{bmatrix}
    a_{11} & a_{12} & a_{13} \\
    a_{21} & a_{22} & a_{23} \\
    a_{31} & a_{32} & a_{33}
    \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} = \begin{bmatrix} b_1 \\ b_2 \\ b_3 \end{bmatrix} \] ​​​

    Solving in Python with NumPy

    Python's NumPy library provides highly optimized functions for numerical operations, including solving linear systems. The most straightforward and recommended method is using numpy.linalg.solve(). This function efficiently computes the solution x for the equation \(Ax = b\).

    Why numpy.linalg.solve?

    • Efficiency: It uses advanced numerical algorithms (like LU decomposition) that are much more efficient and numerically stable than explicitly calculating the inverse of A and multiplying it by b (i.e., \(x = A^{−1}b\) ), especially for large systems.
    • Robustness: It handles various cases and provides error messages if the matrix is singular or ill-conditioned.

    Steps to Solve:

    1. Import NumPy: Start by importing the numpy library.
    2. Define Coefficient Matrix (A): Create a NumPy array representing the coefficient matrix A.
    3. Define Constant Vector (b): Create a NumPy array representing the constant vector b.
    4. Solve the System: Use numpy.linalg.solve(A, b) to get the solution vector x.
    5. Interpret Results: The returned vector x contains the values of the unknown variables.

    If the coefficient matrix A is singular (i.e., its determinant is zero), numpy.linalg.solve will raise a LinAlgError, indicating that the system does not have a unique solution.

    Example \(\PageIndex{1}\)

    A Well Determined Non-Singular System 

    import numpy as np
    
    # --- Example 1: Well-Determined System (as before) ---
    print("--- Example 1: Well-Determined System ---")
    # Let's consider a 3x3 linear system:
    # 2x + 3y - z = 1
    # 4x - y + 2z = 8
    # x + 2y + 5z = 10
    
    A_well_determined = np.array([
        [2, 3, -1],
        [4, -1, 2],
        [1, 2, 5]
    ])
    b_well_determined = np.array([1, 8, 10])
    
    print("Coefficient Matrix (A_well_determined):\n", A_well_determined)
    print("\nConstant Vector (b_well_determined):\n", b_well_determined)
    
    try:
        det_A_well_determined = np.linalg.det(A_well_determined)
        print(f"\nDeterminant of A_well_determined: {det_A_well_determined:.4f}")
        if np.isclose(det_A_well_determined, 0):
            print("Warning: The determinant is close to zero. The matrix might be singular or ill-conditioned.")
        else:
            print("The matrix A_well_determined is non-singular, indicating a unique solution exists.")
    
        x_well_determined = np.linalg.solve(A_well_determined, b_well_determined)
        print("\nSolution Vector (x_well_determined):\n", x_well_determined)
        verification_well_determined = A_well_determined @ x_well_determined
        print("\nVerification (A_well_determined * x_well_determined):\n", verification_well_determined)
        print("Is A_well_determined * x_well_determined approximately equal to b_well_determined?", np.allclose(verification_well_determined, b_well_determined))
        
    except np.linalg.LinAlgError as e:
        print(f"\nError: Could not solve the system for A_well_determined. {e}")
        print("This usually means the coefficient matrix is singular (determinant is zero).")
    except Exception as e:
        print(f"\nAn unexpected error occurred for A_well_determined: {e}")
    
    --- Example 1: Well-Determined System ---
    Coefficient Matrix (A_well_determined):
     [[ 2  3 -1]
     [ 4 -1  2]
     [ 1  2  5]]
    
    Constant Vector (b_well_determined):
     [ 1  8 10]
    
    Determinant of A_well_determined: -81.0000
    The matrix A_well_determined is non-singular, indicating a unique solution exists.
    
    Solution Vector (x_well_determined):
     [1.17283951 0.12345679 1.71604938]
    
    Verification (A_well_determined * x_well_determined):
     [ 1.  8. 10.]
    Is A_well_determined * x_well_determined approximately equal to b_well_determined? True
    

     

    Example \(\PageIndex{2}\)

    A Well Determined Singular Valued System 

    print("\n\n--- Example 2: Singular Matrix ---")
    # Consider a system where one row is a linear combination of others.
    # This makes the matrix singular and the system either has no solution or infinite solutions.
    # Example:
    # x + y = 2
    # 2x + 2y = 4  (This is just 2 times the first equation)
    # x - y = 0
    
    A_singular = np.array([
        [1, 1],
        [2, 2]
    ])
    b_singular_consistent = np.array([2, 4]) # Consistent system (infinite solutions)
    b_singular_inconsistent = np.array([2, 5]) # Inconsistent system (no solutions)
    
    print("Coefficient Matrix (A_singular):\n", A_singular)
    print("\nConstant Vector (b_singular_consistent):\n", b_singular_consistent)
    print("Constant Vector (b_singular_inconsistent):\n", b_singular_inconsistent)
    
    try:
        det_A_singular = np.linalg.det(A_singular)
        print(f"\nDeterminant of A_singular: {det_A_singular:.4f}")
    
        if np.isclose(det_A_singular, 0):
            print("The determinant is zero. The matrix A_singular is singular.")
            print("This system does not have a unique solution.")
        else:
            print("The matrix A_singular is non-singular, indicating a unique solution exists.")
    
        # Attempt to solve with the consistent singular system
        print("\nAttempting to solve A_singular * x = b_singular_consistent:")
        x_singular_consistent = np.linalg.solve(A_singular, b_singular_consistent)
        print("Solution Vector (x_singular_consistent):\n", x_singular_consistent) # This line will not be reached
    except np.linalg.LinAlgError as e:
        print(f"\nCaught LinAlgError for A_singular * x = b_singular_consistent: {e}")
        print("As expected, numpy.linalg.solve raises an error for a singular matrix.")
    except Exception as e:
        print(f"\nAn unexpected error occurred for A_singular * x = b_singular_consistent: {e}")
    
    print("\nAttempting to solve A_singular * x = b_singular_inconsistent:")
    try:
        # Attempt to solve with the inconsistent singular system
        x_singular_inconsistent = np.linalg.solve(A_singular, b_singular_inconsistent)
        print("Solution Vector (x_singular_inconsistent):\n", x_singular_inconsistent) # This line will not be reached
    
    except np.linalg.LinAlgError as e:
        print(f"\nCaught LinAlgError for A_singular * x = b_singular_inconsistent: {e}")
        print("As expected, numpy.linalg.solve raises an error for a singular matrix, regardless of consistency.")
    except Exception as e:
        print(f"\nAn unexpected error occurred for A_singular * x = b_singular_inconsistent: {e}")
    
    --- Example 2: Singular Matrix ---
    Coefficient Matrix (A_singular):
     [[1 1]
     [2 2]]
    
    Constant Vector (b_singular_consistent):
     [2 4]
    Constant Vector (b_singular_inconsistent):
     [2 5]
    
    Determinant of A_singular: 0.0000
    The determinant is zero. The matrix A_singular is singular.
    This system does not have a unique solution.
    
    Attempting to solve A_singular * x = b_singular_consistent:
    
    Caught LinAlgError for A_singular * x = b_singular_consistent: Singular matrix
    As expected, numpy.linalg.solve raises an error for a singular matrix.
    
    Attempting to solve A_singular * x = b_singular_inconsistent:
    
    Caught LinAlgError for A_singular * x = b_singular_inconsistent: Singular matrix
    As expected, numpy.linalg.solve raises an error for a singular matrix, regardless of consistency.
    

    Summary

    A well-determined, fully specified nth-order linear system has a unique solution. In Python, the most efficient and robust way to solve such a system (represented as \(Ax=b\) ) is by using the numpy.linalg.solve() function from the NumPy library.

    Here's a summary of the steps involved:

    1. Represent the System: Define the coefficient matrix A and constant vector b as NumPy arrays.
    2. Solve with numpy.linalg.solve(): Pass the coefficient matrix A and the constant vector b to np.linalg.solve(A, b). This function will return the solution vector x.
    3. Handle Errors: If the matrix A is singular (i.e., its determinant is zero, meaning no unique solution exists), numpy.linalg.solve() will raise a LinAlgError. It's good practice to wrap the call in a try-except block to gracefully handle this issue.

    The NumPy linalg solve method is preferred over calculating the inverse of A explicitly  \(x=A^{−1}b\) because numpy.linalg.solve() is more numerically stable and computationally efficient, especially for larger systems.


    This page titled 14.2: Well-Determined Fully Specified System was last modified on Thu, 08 Jan 2026 22:04:59 GMT and is shared under a CC BY-SA 4.0 license and was authored, remixed, and/or curated by Carl Greco.