<?xml version="1.0" encoding="UTF-8"?>
<quiz>
  <question type="stack">
    <name>
      <text>Find bases for subspaces of matrix</text>
    </name>
    <questiontext format="html">
      <text><![CDATA[<p>
  Let
  \[
  	A = {@AA@} \xrightarrow{\text{RREF}} {@AA_rref@}.
  \]
  Find bases for the row, column and null space of \(A\).
</p>
<p>
  Give your answers as sets of column vectors, e.g. <code>{c(1,2,3,4),c(2,3,4,5)}</code>
</p>
<ul>
  <li>
    <p>
      Basis for \(\operatorname{row}(A) = \) [[input:stu_row]] [[validation:stu_row]] [[feedback:prt_row]]
    </p>
  </li>
  <li>
    <p>
      Basis for \(\operatorname{col}(A) = \) [[input:stu_col]] [[validation:stu_col]] [[feedback:prt_col]]
    </p>
  </li>
  <li>
    <p>
      Basis for \(\operatorname{null}(A) = \) [[input:stu_null]] [[validation:stu_null]] [[feedback:prt_null]]
    </p>
  </li>
</ul>
[[hint title="How might I check my answers?"]]
<p>
  Firstly, check that your sets are linearly independent. Bases are not allowed to have linearly dependent vectors! Then you can check some of the following:
</p>
<ul>
  <li>The row space and column space of a matrix will always have the same dimension.</li>
  <li>The rank-nullity theorem tells us that the dimension of the row space and the dimension of the null space add up to the number of columns in the matrix.</li>
  <li>The row space and null space are orthogonal, so every basis vector for the row space must be orthogonal to every basis vector in the null space (and vice versa).</li>
</ul>
[[/hint]]]]></text>
    </questiontext>
    <generalfeedback format="html">
      <text/>
    </generalfeedback>
    <defaultgrade>1</defaultgrade>
    <penalty>0.5</penalty>
    <hidden>0</hidden>
    <idnumber/>
    <stackversion>
      <text>2025042500</text>
    </stackversion>
    <questionvariables>
      <text><![CDATA[stack_linear_algebra_declare(true);
stack_include_contrib("vectorspaces.mac");

rv():= rand([-1,1])*rand([1,2,3,1/2,1/3,1/4,2/3,3/4]);
AA_rref: rand([
  matrix([1,0,rv(),rv()],[0,1,rv(),rv()],[0,0,0,0]),
  matrix([1,rv(),0,rv()],[0,0,1,rv()],[0,0,0,0]),
  matrix([1,rv(),rv(),0],[0,0,0,1],[0,0,0,0]),
  matrix([1,rv(),rv(),rv()],[0,0,0,0],[0,0,0,0]),
  matrix([0,1,rv(),rv()],[0,0,0,0],[0,0,0,0])
]);
AA: apply(matrix,map(scale_nicely,args(AA_rref)));
AA: rowop(AA,2,1,rand([-2,-1,1,2]));
AA: rowop(AA,3,1,rand([-2,-1,1,2]));
[r1,r2,r3]: random_permutation([1,2,3]);
AA: rowop(AA,r1,r2,rand([-2,-1,1,2]));
AA: rowop(AA,r2,r3,rand([-2,-1,1,2]));

sol_row: setify(map(lambda([ex],apply(c,scale_nicely(list_matrix_entries(ex)))),args(rowspace(AA))));
sol_col: setify(map(lambda([ex],apply(c,scale_nicely(list_matrix_entries(ex)))),args(columnspace(AA))));
sol_null: setify(map(lambda([ex],apply(c,scale_nicely(list_matrix_entries(ex)))),args(nullspace(AA))));

validate_set_of_vecs(ex):= block(
  if not(setp(ex)) then return("Your answer should be a set of column vectors")
  else block(
    set_ops: setify(map(safe_op,listify(ex))),
    if ev(emptyp(setdifference(set_ops,{"c","r","matrix"})),simp) then return("") else return("Your answer should be a set of column vectors")
  )
);]]></text>
    </questionvariables>
    <specificfeedback format="html">
      <text/>
    </specificfeedback>
    <questionnote format="moodle_auto_format">
      <text><![CDATA[\(A = {@AA@} \xrightarrow{\text{RREF}} {@AA_rref@}\)<br>
<ul>
  <li>
    <p>
      \(\operatorname{row}(A) = {@sol_row@}\)
    </p>
  </li>
  <li>
    <p>
      \(\operatorname{col}(A) = {@sol_col@}\)
    </p>
  </li>
  <li>
    <p>
      \(\operatorname{null}(A) = {@sol_null@}\)
    </p>
  </li>
</ul>]]></text>
    </questionnote>
    <questiondescription format="html">
      <text/>
    </questiondescription>
    <questionsimplify>1</questionsimplify>
    <assumepositive>0</assumepositive>
    <assumereal>0</assumereal>
    <prtcorrect format="html">
      <text><![CDATA[<span style="font-size: 1.5em; color:green;"><i class="fa fa-check"></i></span> Correct answer, well done.]]></text>
    </prtcorrect>
    <prtpartiallycorrect format="html">
      <text><![CDATA[<span style="font-size: 1.5em; color:orange;"><i class="fa fa-adjust"></i></span> Your answer is partially correct.]]></text>
    </prtpartiallycorrect>
    <prtincorrect format="html">
      <text><![CDATA[<span style="font-size: 1.5em; color:red;"><i class="fa fa-times"></i></span> Incorrect answer.]]></text>
    </prtincorrect>
    <decimals>.</decimals>
    <scientificnotation>*10</scientificnotation>
    <multiplicationsign>onum</multiplicationsign>
    <sqrtsign>1</sqrtsign>
    <complexno>i</complexno>
    <inversetrig>cos-1</inversetrig>
    <logicsymbol>lang</logicsymbol>
    <matrixparens>[</matrixparens>
    <isbroken>0</isbroken>
    <variantsselectionseed/>
    <input>
      <name>stu_col</name>
      <type>algebraic</type>
      <tans>sol_col</tans>
      <boxsize>30</boxsize>
      <strictsyntax>1</strictsyntax>
      <insertstars>0</insertstars>
      <syntaxhint/>
      <syntaxattribute>0</syntaxattribute>
      <forbidwords/>
      <allowwords/>
      <forbidfloat>1</forbidfloat>
      <requirelowestterms>0</requirelowestterms>
      <checkanswertype>0</checkanswertype>
      <mustverify>1</mustverify>
      <showvalidation>3</showvalidation>
      <options>validator:validate_set_of_vecs,checkvars:3</options>
    </input>
    <input>
      <name>stu_null</name>
      <type>algebraic</type>
      <tans>sol_null</tans>
      <boxsize>30</boxsize>
      <strictsyntax>1</strictsyntax>
      <insertstars>0</insertstars>
      <syntaxhint/>
      <syntaxattribute>0</syntaxattribute>
      <forbidwords/>
      <allowwords/>
      <forbidfloat>1</forbidfloat>
      <requirelowestterms>0</requirelowestterms>
      <checkanswertype>0</checkanswertype>
      <mustverify>1</mustverify>
      <showvalidation>3</showvalidation>
      <options>validator:validate_set_of_vecs,checkvars:3</options>
    </input>
    <input>
      <name>stu_row</name>
      <type>algebraic</type>
      <tans>sol_row</tans>
      <boxsize>30</boxsize>
      <strictsyntax>1</strictsyntax>
      <insertstars>0</insertstars>
      <syntaxhint/>
      <syntaxattribute>0</syntaxattribute>
      <forbidwords/>
      <allowwords/>
      <forbidfloat>1</forbidfloat>
      <requirelowestterms>0</requirelowestterms>
      <checkanswertype>0</checkanswertype>
      <mustverify>1</mustverify>
      <showvalidation>3</showvalidation>
      <options>validator:validate_set_of_vecs,checkvars:3</options>
    </input>
    <prt>
      <name>prt_col</name>
      <value>1.0000000</value>
      <autosimplify>0</autosimplify>
      <feedbackstyle>1</feedbackstyle>
      <feedbackvariables>
        <text>stu_col_l: args(stu_col);
simp:true;
stu_col_f: make_list_of_lists(stu_col_l);
check_form: vec_convertedp(stu_col_f);
check_row_vecs: member(r,get_ops(stu_col_l));</text>
      </feedbackvariables>
      <node>
        <name>0</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>check_form and not(check_row_vecs)</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>=</truescoremode>
        <truescore>0</truescore>
        <truepenalty/>
        <truenextnode>1</truenextnode>
        <trueanswernote>prt_col-1-T</trueanswernote>
        <truefeedback format="html">
          <text/>
        </truefeedback>
        <falsescoremode>=</falsescoremode>
        <falsescore>0</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt_col-1-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is in an unexpected form.<br></p><p dir="ltr" style="text-align: left;">[[if test="check_row_vecs"]]</p><p>You have entered one or more of your basis vectors as row vectors. Typically in linear algebra we assume that all vectors are column vectors.</p>[[/if]]<br><p></p>]]></text>
        </falsefeedback>
      </node>
      <node>
        <name>1</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>subspace_equivp(stu_col_f,make_list_of_lists(sol_col))</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>+</truescoremode>
        <truescore>0</truescore>
        <truepenalty/>
        <truenextnode>2</truenextnode>
        <trueanswernote>prt_col-2-T</trueanswernote>
        <truefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer spans the subspace.&nbsp;<br></p>]]></text>
        </truefeedback>
        <falsescoremode>-</falsescoremode>
        <falsescore>1</falsescore>
        <falsepenalty/>
        <falsenextnode>2</falsenextnode>
        <falseanswernote>prt_col-2-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer does not span the subspace. Either you are missing one or more basis vectors, or you have included one or more vectors that are not in the subspace.&nbsp;<br></p>]]></text>
        </falsefeedback>
      </node>
      <node>
        <name>2</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>lin_indp(stu_col_f)</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>+</truescoremode>
        <truescore>1</truescore>
        <truepenalty/>
        <truenextnode>-1</truenextnode>
        <trueanswernote>prt_col-3-T</trueanswernote>
        <truefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is linearly independent, good job!<br></p>]]></text>
        </truefeedback>
        <falsescoremode>-</falsescoremode>
        <falsescore>0</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt_col-3-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is linearly dependent, so it is not a basis.&nbsp;<br></p>]]></text>
        </falsefeedback>
      </node>
    </prt>
    <prt>
      <name>prt_null</name>
      <value>1.0000000</value>
      <autosimplify>0</autosimplify>
      <feedbackstyle>1</feedbackstyle>
      <feedbackvariables>
        <text>stu_null_l: args(stu_null);
simp:true;
stu_null_f: make_list_of_lists(stu_null_l);
check_form: vec_convertedp(stu_null_f);
check_row_vecs: member(r,get_ops(stu_null_l));</text>
      </feedbackvariables>
      <node>
        <name>0</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>check_form and not(check_row_vecs)</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>=</truescoremode>
        <truescore>0</truescore>
        <truepenalty/>
        <truenextnode>1</truenextnode>
        <trueanswernote>prt_null-1-T</trueanswernote>
        <truefeedback format="html">
          <text/>
        </truefeedback>
        <falsescoremode>=</falsescoremode>
        <falsescore>0</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt_null-1-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is in an unexpected form.&nbsp;</p><p dir="ltr" style="text-align: left;">[[if test="check_row_vecs"]]</p><p>You have entered one or more of your basis vectors as row vectors. Typically in linear algebra we assume that all vectors are column vectors, even in this instance where you are finding a basis for the null space.</p>[[/if]]<br><p></p>]]></text>
        </falsefeedback>
      </node>
      <node>
        <name>1</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>subspace_equivp(stu_null_f,make_list_of_lists(sol_null))</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>+</truescoremode>
        <truescore>0</truescore>
        <truepenalty/>
        <truenextnode>2</truenextnode>
        <trueanswernote>prt_null-2-T</trueanswernote>
        <truefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer spans the subspace.&nbsp;<br></p>]]></text>
        </truefeedback>
        <falsescoremode>-</falsescoremode>
        <falsescore>1</falsescore>
        <falsepenalty/>
        <falsenextnode>2</falsenextnode>
        <falseanswernote>prt_null-2-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer does not span the subspace. Either you are missing one or more basis vectors, or you have included one or more vectors that are not in the subspace.&nbsp;<br></p><p dir="ltr" style="text-align: left;">Remember that the null space of a matrix is the set of vectors \(\{\underline{\mathbf{x}}: A\underline{\mathbf{x}} = \underline{\mathbf{0}}\), or in plain English, all vectors that result in zero when multiplied by \(A\).&nbsp;</p>]]></text>
        </falsefeedback>
      </node>
      <node>
        <name>2</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>lin_indp(stu_null_f)</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>+</truescoremode>
        <truescore>1</truescore>
        <truepenalty/>
        <truenextnode>-1</truenextnode>
        <trueanswernote>prt_null-3-T</trueanswernote>
        <truefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is linearly independent, good job!<br></p>]]></text>
        </truefeedback>
        <falsescoremode>-</falsescoremode>
        <falsescore>0</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt_null-3-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is linearly dependent, so it is not a basis.&nbsp;<br></p>]]></text>
        </falsefeedback>
      </node>
    </prt>
    <prt>
      <name>prt_row</name>
      <value>1.0000000</value>
      <autosimplify>0</autosimplify>
      <feedbackstyle>1</feedbackstyle>
      <feedbackvariables>
        <text>stu_row_l: args(stu_row);
simp:true;
stu_row_f: make_list_of_lists(stu_row_l);
check_form: vec_convertedp(stu_row_f);
check_row_vecs: member(r,get_ops(stu_row_l));</text>
      </feedbackvariables>
      <node>
        <name>0</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>check_form and not(check_row_vecs)</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>=</truescoremode>
        <truescore>0</truescore>
        <truepenalty/>
        <truenextnode>1</truenextnode>
        <trueanswernote>prt_row-1-T</trueanswernote>
        <truefeedback format="html">
          <text/>
        </truefeedback>
        <falsescoremode>=</falsescoremode>
        <falsescore>0</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt_row-1-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is in an unexpected form.</p>
[[if test="check_row_vecs"]]
<p>
  You have entered one or more of your basis vectors as row vectors. Typically in linear algebra we assume that all vectors are column vectors, even in this instance where you are finding a basis for a row space.
</p>
[[/if]]]]></text>
        </falsefeedback>
      </node>
      <node>
        <name>1</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>subspace_equivp(stu_row_f,make_list_of_lists(sol_row))</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>+</truescoremode>
        <truescore>0</truescore>
        <truepenalty/>
        <truenextnode>2</truenextnode>
        <trueanswernote>prt_row-2-T</trueanswernote>
        <truefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer spans the subspace.&nbsp;</p>]]></text>
        </truefeedback>
        <falsescoremode>-</falsescoremode>
        <falsescore>1</falsescore>
        <falsepenalty/>
        <falsenextnode>2</falsenextnode>
        <falseanswernote>prt_row-2-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer does not span the subspace. Either you are missing one or more basis vectors, or you have included one or more vectors that are not in the subspace.&nbsp;</p>]]></text>
        </falsefeedback>
      </node>
      <node>
        <name>2</name>
        <description/>
        <answertest>AlgEquiv</answertest>
        <sans>lin_indp(stu_row_f)</sans>
        <tans>true</tans>
        <testoptions/>
        <quiet>0</quiet>
        <truescoremode>+</truescoremode>
        <truescore>1</truescore>
        <truepenalty/>
        <truenextnode>-1</truenextnode>
        <trueanswernote>prt_row-3-T</trueanswernote>
        <truefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is linearly independent, good job!</p>]]></text>
        </truefeedback>
        <falsescoremode>-</falsescoremode>
        <falsescore>0</falsescore>
        <falsepenalty/>
        <falsenextnode>-1</falsenextnode>
        <falseanswernote>prt_row-3-F</falseanswernote>
        <falsefeedback format="html">
          <text><![CDATA[<p dir="ltr" style="text-align: left;">Your answer is linearly dependent, so it is not a basis.&nbsp;<br></p>]]></text>
        </falsefeedback>
      </node>
    </prt>
    <deployedseed>1534564982</deployedseed>
    <deployedseed>243643012</deployedseed>
    <deployedseed>338482333</deployedseed>
    <deployedseed>855711513</deployedseed>
    <deployedseed>712935610</deployedseed>
    <deployedseed>2081310832</deployedseed>
    <deployedseed>173013070</deployedseed>
    <deployedseed>1350373951</deployedseed>
    <qtest>
      <testcase>1</testcase>
      <description>Test case assuming the teacher's input gets full marks.</description>
      <testinput>
        <name>stu_col</name>
        <value>sol_col</value>
      </testinput>
      <testinput>
        <name>stu_null</name>
        <value>sol_null</value>
      </testinput>
      <testinput>
        <name>stu_row</name>
        <value>sol_row</value>
      </testinput>
      <expected>
        <name>prt_col</name>
        <expectedscore>1.0000000</expectedscore>
        <expectedpenalty>0.0000000</expectedpenalty>
        <expectedanswernote>prt_col-3-T</expectedanswernote>
      </expected>
      <expected>
        <name>prt_null</name>
        <expectedscore>1.0000000</expectedscore>
        <expectedpenalty>0.0000000</expectedpenalty>
        <expectedanswernote>prt_null-3-T</expectedanswernote>
      </expected>
      <expected>
        <name>prt_row</name>
        <expectedscore>1.0000000</expectedscore>
        <expectedpenalty>0.0000000</expectedpenalty>
        <expectedanswernote>prt_row-3-T</expectedanswernote>
      </expected>
    </qtest>
    <qtest>
      <testcase>2</testcase>
      <description/>
      <testinput>
        <name>stu_col</name>
        <value>setify(ev(map(lambda([ex],apply(c,ex)),args(transpose(AA))),simp))</value>
      </testinput>
      <testinput>
        <name>stu_null</name>
        <value>{c(0,0,0,0)}</value>
      </testinput>
      <testinput>
        <name>stu_row</name>
        <value>setify(ev(map(lambda([ex],apply(c,ex)),args(AA)),simp))</value>
      </testinput>
      <expected>
        <name>prt_col</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty/>
        <expectedanswernote>prt_col-3-F</expectedanswernote>
      </expected>
      <expected>
        <name>prt_null</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty/>
        <expectedanswernote>prt_null-3-F</expectedanswernote>
      </expected>
      <expected>
        <name>prt_row</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty/>
        <expectedanswernote>prt_row-3-F</expectedanswernote>
      </expected>
    </qtest>
    <qtest>
      <testcase>3</testcase>
      <description/>
      <testinput>
        <name>stu_col</name>
        <value>setify(map(lambda([ex],apply(r,args(ex))),args(sol_col)))</value>
      </testinput>
      <testinput>
        <name>stu_null</name>
        <value>setify(map(lambda([ex],apply(r,args(ex))),args(sol_null)))</value>
      </testinput>
      <testinput>
        <name>stu_row</name>
        <value>setify(map(lambda([ex],apply(r,args(ex))),args(sol_row)))</value>
      </testinput>
      <expected>
        <name>prt_col</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty/>
        <expectedanswernote>prt_col-1-F</expectedanswernote>
      </expected>
      <expected>
        <name>prt_null</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty/>
        <expectedanswernote>prt_null-1-F</expectedanswernote>
      </expected>
      <expected>
        <name>prt_row</name>
        <expectedscore>0.0000000</expectedscore>
        <expectedpenalty/>
        <expectedanswernote>prt_row-1-F</expectedanswernote>
      </expected>
    </qtest>
  </question>
</quiz>
