// Numbas version: finer_feedback_settings {"name": "Oracle function root estimation", "extensions": ["geogebra"], "custom_part_types": [], "resources": [], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"functions": {}, "ungrouped_variables": [], "name": "Oracle function root estimation", "tags": [], "question_groups": [{"pickingStrategy": "all-ordered", "name": "", "questions": [], "pickQuestions": 0}], "type": "question", "advice": "

Interval bisection means, simply, taking an interval and cutting it in half.

\n

Let us define $I_0 = (\\var{intervalBisected[0]},\\var{intervalBisected[2]})$.

\n

In this instance, the idea is that we generate two subintervals of our initial interval, $I_0$, and by the intermediate value theorem, we can guarantee that one of them will contain our root. Here are the first steps.

\n

Firstly, we check the values of the function at the endpoints of $I_0$: $f(\\var{intervalBisected[0]}) = \\var{functionValues[0]}$ and $f(\\var{intervalBisected[2]}) = \\var{functionValues[2]}$. Hence, by the intermediate value theorem, there is at least one $c \\in I_0$ such that $f(c) = 0$.

\n

Now, we cut the interval $I_0$ in half, producing the subintervals $(\\var{intervalBisected[0]},\\var{intervalBisected[1]})$ and $(\\var{intervalBisected[1]},\\var{intervalBisected[2]})$. Now, $f(\\var{intervalBisected[1]}) = \\var{functionValues[1]}$, and so we choose the subinterval where the sign of $f$ differs at the endpoints, which is to say, we take $I_1 = (\\var{intervalChoice[0]},\\var{intervalChoice[1]})$. By the intermediate value theorem, we guarantee that there is a $c \\in I_1$ such that $f(c) = 0$.

\n

We repeat this procedure on our new, smaller interval, $I_1$, choosing a smaller interval still, until eventually we have an interval so small that we can guarantee the answer to two decimal places, which is $c = \\var{dpformat(roots[pos],2)}$.

", "rulesets": {}, "parts": [{"prompt": "

I will also tell you that there is a root in the open interval $(\\var{intervalBisected[0]},\\var{intervalBisected[2]})$. Using interval bisection and the intermediate value theorem, identify the location of this root to two decimal places.

\n

The root is located at $x=\\;$[[0]]

", "variableReplacements": [], "variableReplacementStrategy": "originalfirst", "gaps": [{"precisionType": "dp", "precisionMessage": "You have not given your answer to the correct precision.", "allowFractions": false, "variableReplacements": [], "precision": "2", "maxValue": "roots[pos]", "minValue": "roots[pos]", "variableReplacementStrategy": "originalfirst", "strictPrecision": true, "correctAnswerFraction": false, "showCorrectAnswer": true, "precisionPartialCredit": 0, "scripts": {}, "marks": 1, "showPrecisionHint": true, "type": "numberentry"}], "showCorrectAnswer": true, "scripts": {}, "marks": 0, "type": "gapfill"}], "extensions": ["geogebra"], "statement": "

I am thinking of a function, but I will not tell you what it is! However:

\n
    \n
  1. I will tell you that it is continuous everywhere.
  2. \n
  3. I will tell you the value of the function anywhere you ask, to three decimal places. You can use the box below to inquire of me. (You may need to wait a little for it to load.)
  4. \n
\n

{geogebra_applet('ufgKrAzb',defs)}

\n", "variable_groups": [{"variables": ["a", "b", "c", "d"], "name": "Coefficients"}, {"variables": ["rootsInteger", "rootsDecimal", "roots"], "name": "Roots"}, {"variables": ["k", "testRoots", "testRootsExplicit", "testRootsInteger", "testRootsDecimal"], "name": "Testing"}, {"variables": ["pos", "extend", "minExtent"], "name": "Question definition"}, {"variables": ["defs"], "name": "Geogebra"}, {"variables": ["intervalBisected", "functionValues", "intervalChoice"], "name": "Worked solution"}], "variablesTest": {"maxRuns": "1", "condition": "roots[pos] < intervalBisected[2]"}, "preamble": {"css": "", "js": ""}, "variables": {"a": {"definition": "random(-3..3 except 0)", "templateType": "anything", "group": "Coefficients", "name": "a", "description": ""}, "defs": {"definition": "[\n ['a',a],\n ['b',b],\n ['c',c],\n ['d',d]\n]", "templateType": "anything", "group": "Geogebra", "name": "defs", "description": ""}, "c": {"definition": "-d*sum(map(1/x,x,roots))", "templateType": "anything", "group": "Coefficients", "name": "c", "description": ""}, "b": {"definition": "-a*sum(roots)", "templateType": "anything", "group": "Coefficients", "name": "b", "description": ""}, "functionValues": {"definition": "map(precround(a*x^3+b*x^2+c*x+d,3),x,intervalBisected)", "templateType": "anything", "group": "Worked solution", "name": "functionValues", "description": ""}, "d": {"definition": "-a*roots[0]*roots[1]*roots[2]", "templateType": "anything", "group": "Coefficients", "name": "d", "description": ""}, "extend": {"definition": "repeat(precround(random(50..99)*minExtent/100,2),2)", "templateType": "anything", "group": "Question definition", "name": "extend", "description": ""}, "testRootsInteger": {"definition": "rootsInteger[k]", "templateType": "anything", "group": "Testing", "name": "testRootsInteger", "description": ""}, "k": {"definition": "1", "templateType": "anything", "group": "Testing", "name": "k", "description": ""}, "pos": {"definition": "random(0..2)", "templateType": "anything", "group": "Question definition", "name": "pos", "description": ""}, "testRoots": {"definition": "roots[k]", "templateType": "anything", "group": "Testing", "name": "testRoots", "description": ""}, "intervalChoice": {"definition": "if(functionValues[0]*functionValues[1] < 0,intervalBisected[0..2],intervalBisected[1..3])", "templateType": "anything", "group": "Worked solution", "name": "intervalChoice", "description": ""}, "testRootsExplicit": {"definition": "rootsInteger[k]+rootsDecimal[k]", "templateType": "anything", "group": "Testing", "name": "testRootsExplicit", "description": ""}, "testRootsDecimal": {"definition": "rootsDecimal[k]", "templateType": "anything", "group": "Testing", "name": "testRootsDecimal", "description": ""}, "minExtent": {"definition": "precround(min([abs(roots[2]-roots[1]),abs(roots[2]-roots[0]),abs(roots[1]-roots[0])]),2)", "templateType": "anything", "group": "Question definition", "name": "minExtent", "description": ""}, "rootsInteger": {"definition": "sort(map(x-5,x,deal(10)[0..3]))", "templateType": "anything", "group": "Roots", "name": "rootsInteger", "description": ""}, "intervalBisected": {"definition": "[\n precround(roots[pos]-extend[0],2),\n precround((roots[pos]+extend[1]+roots[pos]-extend[0])/2,2),\n precround(roots[pos]+extend[1],2)\n]", "templateType": "anything", "group": "Worked solution", "name": "intervalBisected", "description": ""}, "rootsDecimal": {"definition": "repeat(random(1..9999)/10000,3)", "templateType": "anything", "group": "Roots", "name": "rootsDecimal", "description": ""}, "roots": {"definition": "map(sum(x),x,zip(rootsInteger,rootsDecimal))", "templateType": "anything", "group": "Roots", "name": "roots", "description": ""}}, "showQuestionGroupNames": false, "metadata": {"description": "

Given an oracle function that will output its value given an input, and an interval within which a root exists, find the root to a given precision.

\n

Makes use of a Geogebra applet.

", "licence": "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International"}, "contributors": [{"name": "Philip Walker", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/362/"}]}]}], "contributors": [{"name": "Philip Walker", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/362/"}]}