\\n\"+\n",
- " \"
\\n\"+\n",
- " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
- " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
- " \"
\\n\"+\n",
- " \"
\\n\"+\n",
- " \"- re-rerun `output_notebook()` to attempt to load from CDN again, or
\\n\"+\n",
- " \"- use INLINE resources instead, as so:
\\n\"+\n",
- " \"
\\n\"+\n",
- " \"
\\n\"+\n",
- " \"from bokeh.resources import INLINE\\n\"+\n",
- " \"output_notebook(resources=INLINE)\\n\"+\n",
- " \"
\\n\"+\n",
- " \"
\"}};\n",
- "\n",
- " function display_loaded() {\n",
- " if (window.Bokeh !== undefined) {\n",
- " document.getElementById(\"27f5bd5d-be76-4417-8060-775df8356902\").textContent = \"BokehJS successfully loaded.\";\n",
- " } else if (Date.now() < window._bokeh_timeout) {\n",
- " setTimeout(display_loaded, 100)\n",
- " }\n",
- " }\n",
- "\n",
- " function run_callbacks() {\n",
- " window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
- " delete window._bokeh_onload_callbacks\n",
- " console.info(\"Bokeh: all callbacks have finished\");\n",
- " }\n",
- "\n",
- " function load_libs(js_urls, callback) {\n",
- " window._bokeh_onload_callbacks.push(callback);\n",
- " if (window._bokeh_is_loading > 0) {\n",
- " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
- " return null;\n",
- " }\n",
- " if (js_urls == null || js_urls.length === 0) {\n",
- " run_callbacks();\n",
- " return null;\n",
- " }\n",
- " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
- " window._bokeh_is_loading = js_urls.length;\n",
- " for (var i = 0; i < js_urls.length; i++) {\n",
- " var url = js_urls[i];\n",
- " var s = document.createElement('script');\n",
- " s.src = url;\n",
- " s.async = false;\n",
- " s.onreadystatechange = s.onload = function() {\n",
- " window._bokeh_is_loading--;\n",
- " if (window._bokeh_is_loading === 0) {\n",
- " console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
- " run_callbacks()\n",
- " }\n",
- " };\n",
- " s.onerror = function() {\n",
- " console.warn(\"failed to load library \" + url);\n",
- " };\n",
- " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
- " document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
- " }\n",
- " };var element = document.getElementById(\"27f5bd5d-be76-4417-8060-775df8356902\");\n",
- " if (element == null) {\n",
- " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '27f5bd5d-be76-4417-8060-775df8356902' but no matching script tag was found. \")\n",
- " return false;\n",
- " }\n",
- "\n",
- " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js\"];\n",
- "\n",
- " var inline_js = [\n",
- " function(Bokeh) {\n",
- " Bokeh.set_log_level(\"info\");\n",
- " },\n",
- " \n",
- " function(Bokeh) {\n",
- " \n",
- " document.getElementById(\"27f5bd5d-be76-4417-8060-775df8356902\").textContent = \"BokehJS is loading...\";\n",
- " },\n",
- " function(Bokeh) {\n",
- " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.css\");\n",
- " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.css\");\n",
- " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.css\");\n",
- " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.css\");\n",
- " }\n",
- " ];\n",
- "\n",
- " function run_inline_js() {\n",
- " \n",
- " if ((window.Bokeh !== undefined) || (force === true)) {\n",
- " for (var i = 0; i < inline_js.length; i++) {\n",
- " inline_js[i](window.Bokeh);\n",
- " }if (force === true) {\n",
- " display_loaded();\n",
- " }} else if (Date.now() < window._bokeh_timeout) {\n",
- " setTimeout(run_inline_js, 100);\n",
- " } else if (!window._bokeh_failed_load) {\n",
- " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
- " window._bokeh_failed_load = true;\n",
- " } else if (force !== true) {\n",
- " var cell = $(document.getElementById(\"27f5bd5d-be76-4417-8060-775df8356902\")).parents('.cell').data().cell;\n",
- " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
- " }\n",
- "\n",
- " }\n",
- "\n",
- " if (window._bokeh_is_loading === 0) {\n",
- " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
- " run_inline_js();\n",
- " } else {\n",
- " load_libs(js_urls, function() {\n",
- " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
- " run_inline_js();\n",
- " });\n",
- " }\n",
- "}(this));"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "import qexpy as q"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Next, we'll declare two measured values, x and y, with uncertainties, and print them out. We use the Measurement object from qexpy:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {
- "collapsed": false,
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "x = 10 +/- 1\n",
- "y = 5 +/- 3\n"
- ]
- }
- ],
- "source": [
- "#Our two measured values:\n",
- "x = q.Measurement(10,1)\n",
- "y = q.Measurement(5,3)\n",
- "\n",
- "#We can print them out:\n",
- "print(\"x =\",x)\n",
- "print(\"y =\",y)\n",
- "#x.set_correlation(y,0.3)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We can declare a third object, z, which depends on x and y. The uncertainty in x and y will be correctly propagated to z, so once we have defined z, we can simply print it out with the correct uncertainty:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "z = 15 +/- 3\n"
- ]
- }
- ],
- "source": [
- "#We define z\n",
- "z = x+y\n",
- "#z can now be printed out\n",
- "print(\"z =\",z)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Note how the uncertainties have been kept to 1 significant figure. In this case, the error in z was obtained by adding the errors in x and y in quadrature. We can change the number of significant figures to confirm that the errors were indeed added in quadrature. We can choose between setting the number of significant figures based on the uncertainty (more common) or based on the central value."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "z = 15.000 +/- 3.162\n"
- ]
- }
- ],
- "source": [
- "q.set_sigfigs_error(4) # set sigfigs based on the error\n",
- "print(\"z =\",z)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Let's compare the error in z to what the errors in x and y are when added manually in quadrature. We need to import the sqrt() function from the math package to apply mathematical functions to numbers:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "3.1622776601683795\n"
- ]
- }
- ],
- "source": [
- "import math as m\n",
- "quadrature = m.sqrt(x.std**2+y.std**2)\n",
- "print(quadrature)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Math functions\n",
- "We can propagate the uncertainties through any operator (+,-,\\*,/) automatically as we showed above. QExPy also knows how to propagate the uncertainty through common mathematical functions. To use mathematical functions on Measurement objects, we need to call the functions from the QExPy package (as opposed to the math package as we did above for 2 numbers)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "time = 1.277102 +/- 0.007982 seconds\n"
- ]
- }
- ],
- "source": [
- "#If an object fell a distance of 8.0 +/0.1 m, how long did it take to fall?\n",
- "y = q.Measurement(8,0.1)\n",
- "g = 9.81\n",
- "t = q.sqrt(2*y/g)\n",
- "print(\"time = \",t, \"seconds\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Error in correlated quantities\n",
- "If we have two measurements, x and y, that are correlated, then their correlation factor will impact the uncertainty on a quantity that depends on them:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "x and y uncorrelated: z= 15.000 +/- 3.162\n",
- "x and y positively correlated: z= 15.000 +/- 3.606\n",
- "x and y negatively correlated: z= 15.000 +/- 2.646\n"
- ]
- }
- ],
- "source": [
- "x = q.Measurement(10,1)\n",
- "y = q.Measurement(5,3)\n",
- "z = x+y\n",
- "print(\"x and y uncorrelated: z=\",z)\n",
- "\n",
- "#Now set a correlation factor between x and y:\n",
- "x.set_correlation(y,0.5)\n",
- "z = x+y\n",
- "print(\"x and y positively correlated: z=\",z)\n",
- "\n",
- "#We can also use the covariance factor instead of the correlation factor:\n",
- "x.set_covariance(y,-1.5)\n",
- "z = x+y\n",
- "print(\"x and y negatively correlated: z=\",z)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "If we don't specify any correlation factors, then all quantities are assumed to be independent. However, a quantity should not be independent from itself, so QExPy knows how to track the correlation in quantities that depend on common quantities. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0.000 +/- 0.000\n"
- ]
- }
- ],
- "source": [
- "x = q.Measurement(10,1)\n",
- "y = x*x\n",
- "z = x*x - y #this should be 0 +/- 0, since it's really x^2 - x^2 \n",
- "print(z)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "## Statistical measurements\n",
- "QExPy can also handle the case when you have repeated measurements of a single quantity and you want to average them together. Suppose that you have measured 5 values of some quantity T. QExPy will automatically assume that those values should be averaged together so that T is given by the mean of the measured values with an uncertainty given by the standard deviation of the values.\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "5.3000 +/- 0.5431\n"
- ]
- }
- ],
- "source": [
- "T=q.Measurement( [5.6, 4.8, 6.1, 4.9, 5.1 ] )\n",
- "print(T)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "T can be used just as any other measurement with uncertainties, and its error will be propagate correctly:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "1.1849 +/- 0.1214\n"
- ]
- }
- ],
- "source": [
- "omega = 2*3.14/T\n",
- "print(omega)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "If we have measured many values, it can sometimes be useful to visualize those measurements in a histogram. QExPy will automatically create a histogram of the values, showing lines corresponding to the mean and the range covered by one standard deviation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- "\n",
- "