// Numbas version: finer_feedback_settings {"name": "Invertibility via eigenvalues", "extensions": ["linear-algebra", "linalg2"], "custom_part_types": [{"source": {"pk": 2, "author": {"name": "Christian Lawson-Perfect", "pk": 7}, "edit_page": "/part_type/2/edit"}, "name": "List of numbers", "short_name": "list-of-numbers", "description": "

The answer is a comma-separated list of numbers.

\n

The list is marked correct if each number occurs the same number of times as in the expected answer, and no extra numbers are present.

\n

You can optionally treat the answer as a set, so the number of occurrences doesn't matter, only whether each number is included or not.

", "help_url": "", "input_widget": "string", "input_options": {"correctAnswer": "join(\n if(settings[\"correctAnswerFractions\"],\n map(let([a,b],rational_approximation(x), string(a/b)),x,settings[\"correctAnswer\"])\n ,\n settings[\"correctAnswer\"]\n ),\n settings[\"separator\"] + \" \"\n)", "hint": {"static": false, "value": "if(settings[\"show_input_hint\"],\n \"Enter a list of numbers separated by {settings['separator']}.\",\n \"\"\n)"}, "allowEmpty": {"static": true, "value": true}}, "can_be_gap": true, "can_be_step": true, "marking_script": "bits:\nlet(b,filter(x<>\"\",x,split(studentAnswer,settings[\"separator\"])),\n if(isSet,list(set(b)),b)\n)\n\nexpected_numbers:\nlet(l,settings[\"correctAnswer\"] as \"list\",\n if(isSet,list(set(l)),l)\n)\n\nvalid_numbers:\nif(all(map(not isnan(x),x,interpreted_answer)),\n true,\n let(index,filter(isnan(interpreted_answer[x]),x,0..len(interpreted_answer)-1)[0], wrong, bits[index],\n warn(wrong+\" is not a valid number\");\n fail(wrong+\" is not a valid number.\")\n )\n )\n\nis_sorted:\nassert(sort(interpreted_answer)=interpreted_answer,\n multiply_credit(0.5,\"Not in order\")\n )\n\nincluded:\nmap(\n let(\n num_student,len(filter(x=y,y,interpreted_answer)),\n num_expected,len(filter(x=y,y,expected_numbers)),\n switch(\n num_student=num_expected,\n true,\n num_studentThe separate items in the student's answer

", "definition": "let(b,filter(x<>\"\",x,split(studentAnswer,settings[\"separator\"])),\n if(isSet,list(set(b)),b)\n)"}, {"name": "expected_numbers", "description": "", "definition": "let(l,settings[\"correctAnswer\"] as \"list\",\n if(isSet,list(set(l)),l)\n)"}, {"name": "valid_numbers", "description": "

Is every number in the student's list valid?

", "definition": "if(all(map(not isnan(x),x,interpreted_answer)),\n true,\n let(index,filter(isnan(interpreted_answer[x]),x,0..len(interpreted_answer)-1)[0], wrong, bits[index],\n warn(wrong+\" is not a valid number\");\n fail(wrong+\" is not a valid number.\")\n )\n )"}, {"name": "is_sorted", "description": "

Are the student's answers in ascending order?

", "definition": "assert(sort(interpreted_answer)=interpreted_answer,\n multiply_credit(0.5,\"Not in order\")\n )"}, {"name": "included", "description": "

Is each number in the expected answer present in the student's list the correct number of times?

", "definition": "map(\n let(\n num_student,len(filter(x=y,y,interpreted_answer)),\n num_expected,len(filter(x=y,y,expected_numbers)),\n switch(\n num_student=num_expected,\n true,\n num_studentHas every number been included the right number of times?

", "definition": "all(included)"}, {"name": "no_extras", "description": "

True if the student's list doesn't contain any numbers that aren't in the expected answer.

", "definition": "if(all(map(x in expected_numbers, x, interpreted_answer)),\n true\n ,\n incorrect(\"Your answer contains \"+extra_numbers[0]+\" but should not.\");\n false\n )"}, {"name": "interpreted_answer", "description": "A value representing the student's answer to this part.", "definition": "if(lower(studentAnswer) in [\"empty\",\"\u2205\"],[],\n map(\n if(settings[\"allowFractions\"],parsenumber_or_fraction(x,notationStyles), parsenumber(x,notationStyles))\n ,x\n ,bits\n )\n)"}, {"name": "mark", "description": "This is the main marking note. It should award credit and provide feedback based on the student's answer.", "definition": "if(studentanswer=\"\",fail(\"You have not entered an answer\"),false);\napply(valid_numbers);\napply(included);\napply(no_extras);\ncorrectif(all_included and no_extras)"}, {"name": "notationStyles", "description": "", "definition": "[\"en\"]"}, {"name": "isSet", "description": "

Should the answer be considered as a set, so the number of times an element occurs doesn't matter?

", "definition": "settings[\"isSet\"]"}, {"name": "extra_numbers", "description": "

Numbers included in the student's answer that are not in the expected list.

", "definition": "filter(not (x in expected_numbers),x,interpreted_answer)"}], "settings": [{"name": "correctAnswer", "label": "Correct answer", "help_url": "", "hint": "The list of numbers that the student should enter. The order does not matter.", "input_type": "code", "default_value": "", "evaluate": true}, {"name": "allowFractions", "label": "Allow the student to enter fractions?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "correctAnswerFractions", "label": "Display the correct answers as fractions?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": false}, {"name": "isSet", "label": "Is the answer a set?", "help_url": "", "hint": "If ticked, the number of times an element occurs doesn't matter, only whether it's included at all.", "input_type": "checkbox", "default_value": false}, {"name": "show_input_hint", "label": "Show the input hint?", "help_url": "", "hint": "", "input_type": "checkbox", "default_value": true}, {"name": "separator", "label": "Separator", "help_url": "", "hint": "The substring that should separate items in the student's list", "input_type": "string", "default_value": ",", "subvars": false}], "public_availability": "always", "published": true, "extensions": []}], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"name": "Invertibility via eigenvalues", "tags": ["eigenvalue", "explore mode", "invertibility", "linear algebra"], "metadata": {"description": "

Example of an explore mode question. Student is given a 2x2 matrix with eigenvalues and eigenvectors, and is asked to decide if the matrix is invertible. If yes, second and third parts are offered where the student should give the eigenvalues and eigenvectors of the inverse matrix.

\n

Assessed: remembering link between 0 eigenvalue and invertibility. Remembering link between eigenvalues and eigenvectors of matrix and its inverse.

\n

Randomisation: a random true/false for invertibility is created, and the eigenvalues a and b are randomised (condition: two different evalues, and a=0 iff invertibility is false), and a random invertible 2x2 matrix with determinant 1 or -1 is created (via random elementary row operations) to change base from diag(a,b) to the matrix for the question. Determinant 1 or -1 ensures that we keep integer entries.

\n

The implementation uses linear algebra functions such as \"find reduced echelon form\" or \"find kernel of a reduced echelon form\", from the extension \"linalg2\".

", "licence": "Creative Commons Attribution 4.0 International"}, "statement": "

The matrix \\(\\var[fractionNumbers]{matrixA}\\) has eigenvalues \\(\\var[fractionNumbers]{a}\\) with eigenvector \\(\\var[fractionNumbers]{v1}\\) and \\(\\var[fractionNumbers]{b}\\) with eigenvector \\(\\var[fractionNumbers]{v2}\\).

\n

Determine whether the matrix is invertible. (You should use your knowledge of eigenvalues for this.) If the matrix is invertible, give the eigenvalues and eigenvectors of its inverse.

", "advice": "

A matrix is invertible if and only if it does not have \\(0\\) as an eigenvalue.  So as the eigenvalues are \\(\\var[fractionNumbers]{a}\\) and \\(\\var[fractionNumbers]{b}\\), we see that \\(A\\) is not invertible.

\n

When it is invertible, the eigenvalues of the inverse are the reciprocals: \\(\\var[fractionNumbers]{1/a}\\) and \\(\\var[fractionNumbers]{1/b}\\), with the same eigenvectors as \\(A\\) had, i.e. \\(\\var[fractionNumbers]{v1}\\) for \\(\\var[fractionNumbers]{1/a}\\) and \\(\\var[fractionNumbers]{v2}\\) for \\(\\var[fractionNumbers]{1/b}\\).

", "rulesets": {}, "extensions": ["linalg2", "linear-algebra"], "builtin_constants": {"e": true, "pi,\u03c0": true, "i": true}, "constants": [], "variables": {"matrixA": {"name": "matrixA", "group": "Ungrouped variables", "definition": "Pinverse*matrix([a,0],[0,b])*P", "description": "", "templateType": "anything", "can_override": false}, "a": {"name": "a", "group": "Ungrouped variables", "definition": "if(invertible,random(-5..5 #0.5 except 0 ),0)", "description": "", "templateType": "anything", "can_override": false}, "b": {"name": "b", "group": "Ungrouped variables", "definition": "random(-5..5 #0.5 except 0 )", "description": "", "templateType": "anything", "can_override": false}, "v1": {"name": "v1", "group": "Ungrouped variables", "definition": "transpose(matrix(le_kernel(RREFa)))", "description": "", "templateType": "anything", "can_override": false}, "v2": {"name": "v2", "group": "Ungrouped variables", "definition": "transpose(matrix(le_kernel(RREFb)))", "description": "", "templateType": "anything", "can_override": false}, "RREFa": {"name": "RREFa", "group": "Ungrouped variables", "definition": "matrix(le_red_echelon(matrixA-a*id(n)))", "description": "", "templateType": "anything", "can_override": false}, "RREFb": {"name": "RREFb", "group": "Ungrouped variables", "definition": "matrix(le_red_echelon(matrixA-b*id(n)))", "description": "", "templateType": "anything", "can_override": false}, "n": {"name": "n", "group": "Ungrouped variables", "definition": "2", "description": "", "templateType": "anything", "can_override": false}, "P": {"name": "P", "group": "Ungrouped variables", "definition": "matrix(le_row_shuffle(id(2),2,5))", "description": "", "templateType": "anything", "can_override": false}, "detP": {"name": "detP", "group": "Ungrouped variables", "definition": "det(P)", "description": "", "templateType": "anything", "can_override": false}, "Pinverse": {"name": "Pinverse", "group": "Ungrouped variables", "definition": "1/detP*matrix([P[1][1],-P[0][1]],[-P[1][0],P[0][0]])", "description": "", "templateType": "anything", "can_override": false}, "testinverse": {"name": "testinverse", "group": "Ungrouped variables", "definition": "P*Pinverse", "description": "", "templateType": "anything", "can_override": false}, "invertible": {"name": "invertible", "group": "Ungrouped variables", "definition": "random(true,false)", "description": "", "templateType": "anything", "can_override": false}, "Ainverse": {"name": "Ainverse", "group": "Ungrouped variables", "definition": "if(invertible,\n1/det(matrixA)*matrix([matrixA[1][1],-matrixA[0][1]],[-matrixA[1][0],matrixA[0][0]]),\n id(2))", "description": "", "templateType": "anything", "can_override": false}}, "variablesTest": {"condition": "(detP=1 or detP=-1) and a<>b", "maxRuns": "1000"}, "ungrouped_variables": ["matrixA", "a", "b", "v1", "v2", "RREFa", "RREFb", "n", "P", "detP", "Pinverse", "testinverse", "invertible", "Ainverse"], "variable_groups": [], "functions": {}, "preamble": {"js": "", "css": ""}, "parts": [{"type": "gapfill", "useCustomName": true, "customName": "Determine invertibility", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [{"label": "Eigenvalues of inverse", "rawLabel": "", "otherPart": 1, "variableReplacements": [], "availabilityCondition": "invertible and credit=1", "penalty": "", "penaltyAmount": 0, "lockAfterLeaving": false}], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Is \\(A\\) invertible?

\n

[[0]]

", "gaps": [{"type": "1_n_2", "useCustomName": false, "customName": "", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "minMarks": 0, "maxMarks": 0, "shuffleChoices": false, "displayType": "radiogroup", "displayColumns": 0, "showCellAnswerState": true, "choices": ["\\(A\\) is invertible.", "\\(A\\) is not invertible."], "matrix": ["if(invertible,1,0)", "if(invertible,0,1)"], "distractors": ["", ""]}], "sortAnswers": false}, {"type": "gapfill", "useCustomName": true, "customName": "Eigenvalues of inverse", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [{"label": "evectors of inverse", "rawLabel": "", "otherPart": 2, "variableReplacements": [], "availabilityCondition": "answered", "penalty": "", "penaltyAmount": 0, "lockAfterLeaving": false}], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

The eigenvalues of \\(A^{-1}\\) are (in any order): [[0]]

", "gaps": [{"type": "list-of-numbers", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "included:\nmap(\n let(\n num_student,len(filter(x=y,y,interpreted_answer)),\n num_expected,len(filter(x=y,y,expected_numbers)),\n switch(\n num_student=num_expected,\n true,\n num_student0,[1/a, 1/b],[])", "allowFractions": true, "correctAnswerFractions": true, "isSet": true, "show_input_hint": true}}], "sortAnswers": false}, {"type": "gapfill", "useCustomName": true, "customName": "evectors of inverse", "marks": 0, "scripts": {}, "customMarkingAlgorithm": "student_eval:\n interpreted_answers[0]\n\nstudent_evectors:\n interpreted_answers[1]\n\ncheck_matrix:\n Ainverse-student_eval*id(n)\n\ngeometric_mult:\n numrows(check_matrix)-rank(check_matrix)\n\nare_evectors:\n if(numrows(student_evectors)=numcolumns(Ainverse),\n check_matrix*student_evectors=le_zero_matrix(numrows(Ainverse),numcolumns(student_evectors)),\n false)\n\ncorrect_dim:\n rank(student_evectors)=geometric_mult\n\nlinear_indep:\n numcolumns(student_evectors)=rank(student_evectors)\n\nfurther_feedback:\n assert(numrows(student_evectors)=numcolumns(Ainverse),feedback(\"You dont' have the right number of rows.\");end());\n assert(are_evectors,feedback(\"Your entries are not all eigenvectors for your chosen eigenvalue.\"));\n assert(numcolumns(student_evectors)=geometric_mult,feedback(\"You don't have the right number of eigenvectors.\"));\n assert(numcolumns(student_evectors)=rank(student_evectors),feedback(\"The vectors you entered are not linearly independent.\"))\n\n\nmark:\n assert(all_valid or not settings[\"sortAnswers\"], fail(translate(\"question.can not submit\")));\n apply(answers);\n correctif(correct_dim and are_evectors and linear_indep);\n apply(further_feedback)", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": true, "showFeedbackIcon": true, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [{"label": "Other eigenvectors for inverse", "rawLabel": "Other eigenvectors for inverse", "otherPart": 2, "variableReplacements": [], "availabilityCondition": "", "penalty": "", "penaltyAmount": 0, "lockAfterLeaving": false}], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "prompt": "

Now choose one of the eigenvalues of \\(A^{-1}\\): [[0]]

\n

and enter the corresponding eigenvector(s). Note: you should use theory for this rather than working them out by hand.

\n

Enter a basis for the relevant eigenspace of \\(A\\), i.e. a linearly independent set of eigenvectors for your chosen eigenvalue, as the columns of a matrix. E.g. if there is only one eigenvector, select \"1 column\" and enter the vector. If there are two, select \"2 columns\" and enter the first vector in the first column and the second vector in the second column, etc. This way you can determine how many eigenvectors there are.

\n

[[1]]

", "gaps": [{"type": "numberentry", "useCustomName": false, "customName": "", "marks": "0", "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": false, "showFeedbackIcon": false, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "minValue": "a", "maxValue": "a", "correctAnswerFraction": false, "allowFractions": true, "mustBeReduced": false, "mustBeReducedPC": "0", "showFractionHint": true, "notationStyles": ["plain", "en", "si-en"], "correctAnswerStyle": "plain"}, {"type": "matrix", "useCustomName": false, "customName": "", "marks": 1, "scripts": {}, "customMarkingAlgorithm": "", "extendBaseMarkingAlgorithm": true, "unitTests": [], "showCorrectAnswer": false, "showFeedbackIcon": false, "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "nextParts": [], "suggestGoingBack": false, "adaptiveMarkingPenalty": 0, "exploreObjective": null, "correctAnswer": "v1", "correctAnswerFractions": false, "numRows": 1, "numColumns": 1, "allowResize": true, "tolerance": 0, "markPerCell": false, "allowFractions": true, "minColumns": 1, "maxColumns": 0, "minRows": 1, "maxRows": 0}], "sortAnswers": false}], "partsMode": "explore", "maxMarks": 0, "objectives": [], "penalties": [], "objectiveVisibility": "always", "penaltyVisibility": "always", "type": "question", "contributors": [{"name": "Julia Goedecke", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/5121/"}]}]}], "contributors": [{"name": "Julia Goedecke", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/5121/"}]}