// Numbas version: exam_results_page_options {"name": "Signed Curvature Graphs", "extensions": ["jsxgraph"], "custom_part_types": [], "resources": [["question-resources/CurvatureGraphNUMBAS.jpeg", "/srv/numbas/media/question-resources/CurvatureGraphNUMBAS.jpeg"], ["question-resources/CurvatureGraphNUMBAS_yZK8hzZ.jpeg", "/srv/numbas/media/question-resources/CurvatureGraphNUMBAS_yZK8hzZ.jpeg"]], "navigation": {"allowregen": true, "showfrontpage": false, "preventleave": false, "typeendtoleave": false}, "question_groups": [{"pickingStrategy": "all-ordered", "questions": [{"tags": [], "variable_groups": [{"name": "Constants", "variables": ["quadratic", "cubic", "quotient", "cos", "sin", "exp"]}, {"name": "Function Dictionary", "variables": ["quadstr", "cubstr", "quostr", "cosstr", "sinstr", "expstr"]}], "metadata": {"description": "

Warning: may take up to 60 seconds to load question!

\n

Students are given six graphs, corresponding to curves $\\gamma(t)$. They must match each with its signed curvature function, $\\kappa(t)$.

\n

The graphs are generated by calculating $\\theta(t)=\\int \\kappa(t) \\mathrm{d}t$ (by hand: these are given to the question as functions of a variable '#', in string form), and solving $x^{\\prime}=\\cos(\\theta(t)-\\theta(0))$ and $y^{\\prime}(t)=\\sin(\\theta(t)-\\theta(0))$ numerically (using the RKF method) with a JavaScript extension.

", "licence": "Creative Commons Attribution-NonCommercial-NoDerivs 4.0 International"}, "statement": "

The Fundamental Theorem of Planar Curves states that every curve in $\\mathbb{R}^{2}$ with non-zero curvature is completely determined by its signed curvature, $\\kappa(t)$, and some initial condition for a point on the curve.

\n

Below are six curves $\\gamma(t)$, all of which satisfy $\\gamma(0)=(0,0)$ and $\\gamma^{\\prime}(0)=(0,1)$. The corresponding signed curvatures are as follows:

\n

A: $\\simplify{1/{quadratic[0]}*(t+{quadratic[1]})(t+{quadratic[2]})}$

\n

B: $\\simplify{{sin[0]}*t*sin({sin[1]}*t)}$

\n

C: $\\simplify{exp({exp}*t)}$

\n

D: $\\simplify{1/{cubic[0]}*(t+{cubic[1]})(t+{cubic[2]})(t+{cubic[3]})}$

\n

E: $\\simplify{({quotient[0]}*t)/({quotient[1]}+{quotient[2]}*t^2)}$

\n

F: $\\simplify{{cos[0]}*t*cos({cos[1]}*t)}$

\n

", "parts": [{"variableReplacementStrategy": "originalfirst", "minAnswers": "3", "displayType": "checkbox", "warningType": "none", "scripts": {}, "showFeedbackIcon": true, "maxAnswers": "3", "shuffleChoices": false, "showCellAnswerState": true, "matrix": "markingmatrix1", "answers": ["{graph({collected[0][0]})}", "{graph({collected[1][0]})}", "{graph({collected[2][0]})}"], "showCorrectAnswer": true, "customMarkingAlgorithm": "", "unitTests": [], "maxMarks": "3", "variableReplacements": [], "layout": {"type": "all", "expression": ""}, "type": "m_n_x", "marks": 0, "choices": ["A", "B", "C", "D", "E", "F"], "shuffleAnswers": true, "extendBaseMarkingAlgorithm": true, "minMarks": 0}, {"variableReplacementStrategy": "originalfirst", "minAnswers": "3", "displayType": "checkbox", "warningType": "none", "scripts": {}, "showFeedbackIcon": true, "maxAnswers": "3", "shuffleChoices": false, "showCellAnswerState": true, "matrix": "markingmatrix2", "answers": ["{graph({collected[3][0]})}", "{graph({collected[4][0]})}", "{graph({collected[5][0]})}"], "showCorrectAnswer": true, "customMarkingAlgorithm": "", "unitTests": [], "maxMarks": "3", "variableReplacements": [], "layout": {"type": "all", "expression": ""}, "type": "m_n_x", "marks": 0, "choices": ["A", "B", "C", "D", "E", "F"], "shuffleAnswers": true, "extendBaseMarkingAlgorithm": true, "minMarks": 0}], "variables": {"exp": {"group": "Constants", "definition": "random(-3..3 except 0)", "description": "

Generates the list of constants {a} for a function e^(at).

", "templateType": "anything", "name": "exp"}, "markingmatrix1": {"group": "Ungrouped variables", "definition": "matrix(map(map(collected[n][1][m],n,0..2),m,0..5))", "description": "

The first three elements of the marking matrix.

", "templateType": "anything", "name": "markingmatrix1"}, "cubstr": {"group": "Function Dictionary", "definition": "\"(Math.pow(#,4)/4+\"+(cubic[1]+cubic[2]+cubic[3])+\"*Math.pow(#,3)/3+\"+(cubic[1]*cubic[2]+cubic[2]*cubic[3]+cubic[1]*cubic[3])+\"*#*#/2+\"+cubic[1]*cubic[2]*cubic[3]+\"*#)/\"+cubic[0]+\"\"", "description": "

The integrated cubic, as a string.

", "templateType": "anything", "name": "cubstr"}, "expstr": {"group": "Function Dictionary", "definition": "\"Math.exp(\"+exp+\"*#)\"", "description": "

The integrated exponential function, as a string.

", "templateType": "anything", "name": "expstr"}, "sin": {"group": "Constants", "definition": "[random(-3..3 except 0),random(-2..2 except 0)]", "description": "

Generates the list of constants {a,b} for a function atsin(bt).

", "templateType": "anything", "name": "sin"}, "markingmatrix2": {"group": "Ungrouped variables", "definition": "matrix(map(map(collected[n][1][m],n,3..5),m,0..5))", "description": "

The second three elements of the marking matrix.

", "templateType": "anything", "name": "markingmatrix2"}, "quadratic": {"group": "Constants", "definition": "[random(2..4),random(-3..3 except 0),random(-3..3 except 0)]", "description": "

Generates the list of constants {a,b,c} for a quadratic (t+b)(t+c)/a.

", "templateType": "anything", "name": "quadratic"}, "cubic": {"group": "Constants", "definition": "[random(2..4),random(-5..5 except 0),random(-4..4 except 0),random(-5..5 except 0)]", "description": "

Generates the list of constants {a,b,c,d} for a cubic function (t+b)(t+c)(t+d)/a.

", "templateType": "anything", "name": "cubic"}, "quotient": {"group": "Constants", "definition": "[random(-3..3 except 0),random(1..3),random(1..3)]", "description": "

Generates the list of constants {a,b,c} for a funtion at/(b+ct^2).

", "templateType": "anything", "name": "quotient"}, "quostr": {"group": "Function Dictionary", "definition": "\"Math.log(\"+quotient[1]+\"+\"+quotient[2]+\"*#*#)*\"+quotient[0]+\"/(2*\"+quotient[2]+\")\"", "description": "

The integrated quotient function, as a string.

", "templateType": "anything", "name": "quostr"}, "cosstr": {"group": "Function Dictionary", "definition": "cos[0]+\"*(Math.cos(\"+cos[1]+\"*#)/(\"+cos[1]*cos[1]+\")+#*Math.sin(\"+cos[1]+\"*#)/(\"+cos[1]+\"))\"", "description": "

The integrated cos function, as a string.

", "templateType": "anything", "name": "cosstr"}, "quadstr": {"group": "Function Dictionary", "definition": "\"(Math.pow(#,3)/3\"+\"+\"+(quadratic[1]+quadratic[2])+\"*#*#/2\"+\"+\"+(quadratic[1]*quadratic[2])+\"*#)/\"+quadratic[0]", "description": "

The integrated quadratic, as a string.

", "templateType": "anything", "name": "quadstr"}, "collected": {"group": "Ungrouped variables", "definition": "shuffle([[quadstr,[1,-1,-1,-1,-1,-1]],[sinstr,[-1,1,-1,-1,-1,-1]],[expstr,[-1,-1,1,-1,-1,-1]],[cubstr,[-1,-1,-1,1,-1,-1]],[quostr,[-1,-1,-1,-1,1,-1]],[cosstr,[-1,-1,-1,-1,-1,1]]])", "description": "

A paired list of the strings and the associated row of the marking matrix.

", "templateType": "anything", "name": "collected"}, "sinstr": {"group": "Function Dictionary", "definition": "sin[0]+\"*(Math.sin(\"+sin[1]+\"*#)/(\"+sin[1]*sin[1]+\")+#*Math.cos(\"+sin[1]+\"*#)/(\"+sin[1]+\"))\"", "description": "

The integrated sin function, as a string.

", "templateType": "anything", "name": "sinstr"}, "cos": {"group": "Constants", "definition": "[random(-3..3 except 0),random(-2..2 except 0)]", "description": "

Generates the list of constants {a,b} for a function atcos(bt).

", "templateType": "anything", "name": "cos"}}, "functions": {"graph": {"type": "html", "definition": "/*\nJavaScript implementation of Runge-Kutta adapative 4th order ODE solving.\nThis uses the Fehlberg 4(5) coefficients to calculate 4th and 5th order steps,\nchanging step-size if the truncation error is too high.\nThis is designed to numerically solve to find a graph given its signed curvature\nfunction: given a curvature function k(t), we pass in the integral of k(t) as f(t,y),\nthen the ODEs to solve are x'(t)=cos(f(x,t)-f(0,0)) and y'(t)=sin(f(y,t)-f(0,0)).\n\nAlso included is JSXGraph implementation to plot the results as a parametric curve,\nvia some imaginative interleaving: up to a margin of error, we find x and y values\ncorresponding to the same t value and build a set of points, which JSXGraph plots\nas a curve.\n*/\nfunction funcval(t,y)\n{\n return eval(func.replace(/#/g,t).replace(/y/g,y));\n}\n\n /** The right-hand side of the x ODE.\n * @param {Float} t The value of time to evaluate at\n * @param {Float} x The y value corresponding to t.\n * @returns {Float} The function value.\n */\n function fx(t,x)\n {\n return Math.cos(funcval(t,x)-funcval(0,0));\n }\n /** The right-hand side of the y ODE.\n * @param {Float} t The value of time to evaluate at\n * @param {Float} y The y value corresponding to t.\n * @returns {Float} The function value.\n */\nfunction fy(t,y)\n{\n return Math.sin(funcval(t,y)-funcval(0,0));\n}\n\n/**\n * Performs adaptive Runge-Kutta solving. The weights and nodes are in line with\n * Fehlberg's 4(5) method.\n *\n * @param {Function} f The function to be evaluated.\n * @param {Float} t0 Starting time\n * @param {Float} tf Final time\n * @param {Float} y0 The value of y(t) at t=0\n * @param {Float} h0 Initial step size\n * @param {Float} e Allowed error\n * @param {Array} outarr The target destination for the data. This must be globally instantiated!\n *\n *\n */\nfunction RungeKutta(f,t0,tf,y0,h0,e,outarr)\n{\n var t=t0, h=h0, y=y0;\n while (Math.abs(t)e)\n {\n h = h/2;\n if (Math.abs(h)max)\n max = Math.abs(arr[i]);\n }\n return max;\n}\n/**\n* Plotting function for JSXGraph.\n*\n* @param {Array[Array[Float]]} data A collection of points to be plotted\n*\n*\n*/\nfunction jsxPlot(data)\n{\n var arrx = [], arry = [];\n for (i=0; iIn principle, given a signed curvature function $\\kappa(t)$ and an intitial condition $\\gamma(0)$, $\\gamma^{\\prime}(0)$, we can find the equation $\\gamma:\\,\\mathbb{R}\\to\\mathbb{R}^{2}$ of the curve using

\n

$\\theta(t)=\\int\\kappa(t)\\mathrm{d}t$

\n

$\\gamma=(\\int \\cos(\\theta(t)-\\theta_{0})\\mathrm{d}t,\\,\\int \\sin(\\theta(t)-\\theta_{0})\\mathrm{d}t),$

\n

where $\\theta_{0}$ is determined by the initial conditions. However, this is often not feasible to work out explicitly: for example, if $\\kappa(t)=t$ and $\\gamma(0)=(0,0)$ and $\\gamma^{\\prime}(0)=(0,1)$, then we must find

\n

$\\int \\cos(\\frac{t^{2}}{2})\\mathrm{d}t,$

\n

which has no nice form.

\n

Instead, we can relate properties of the signed curvature to properties of the curve:

\n
    \n
  • Symmetry: if $\\kappa(t)$ is an even function, then $\\gamma$ has reflection symmetry; if $\\kappa(t)$ is odd, $\\gamma$ has rotational symmetry.
  • \n
  • Turning points: if $\\kappa(t)$ changes sign at a point, then the curve $\\gamma$ will change from anticlockwise to clockwise rotation (and vice versa). Note that $\\kappa(t)$ must change sign: it is not enough for $\\kappa(t)$ to equal $0$ at some point.
  • \n
  • Asymptotics: As $t\\to\\pm\\infty$, we can determine the behaviour of $\\kappa(t)$: if it tends to $0$ as $t\\to\\infty$, then $\\gamma$ curves less as we travel rightwards along it; if $\\kappa(t)\\to\\infty$ as $t\\to\\infty$ then $\\gamma$ curves more and more sharply; if $\\kappa(t)$ has no limit as $t\\to\\infty$ then we expect oscillations.
  • \n
\n

Consider, as an example,

\n

$\\kappa(t)=\\sin\\left(\\frac{t^{2}}{2}\\right).$

\n

This is an even function, as the argument is $t^{2}$ so $\\kappa(-t)=\\kappa(t)$; hence $\\gamma$ has reflection symmetry. $\\sin(x)$ changes sign an infinite number of times, so we expect infinitely many changes from clockwise to anticlockwise. Finally, $\\sin(x)$ has no limit as we take $x\\to\\infty$, corresponding to $t\\to\\pm\\infty$, so we would expect the curve to oscillate. Then we can see that this $\\kappa(t)$ corresponds to the following graph:

\n

", "preamble": {"js": "", "css": ""}, "variablesTest": {"maxRuns": 100, "condition": "not (quadratic[1]=quadratic[2] or quadratic[1]=-quadratic[2])"}, "name": "Signed Curvature Graphs", "ungrouped_variables": ["collected", "markingmatrix1", "markingmatrix2"], "type": "question", "contributors": [{"name": "Andrew Iskauskas", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/724/"}, {"name": "Sam Fearn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/2426/"}]}]}], "contributors": [{"name": "Andrew Iskauskas", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/724/"}, {"name": "Sam Fearn", "profile_url": "https://numbas.mathcentre.ac.uk/accounts/profile/2426/"}]}