{"id":5220,"date":"2013-11-26T10:43:34","date_gmt":"2013-11-26T09:43:34","guid":{"rendered":"http:\/\/www.walkingrandomly.com\/?p=5220"},"modified":"2013-11-26T10:43:34","modified_gmt":"2013-11-26T09:43:34","slug":"playing-with-mathematica-on-raspberry-pi","status":"publish","type":"post","link":"https:\/\/walkingrandomly.com\/?p=5220","title":{"rendered":"Playing with Mathematica on Raspberry Pi"},"content":{"rendered":"<p>As soon as I heard the news that <a href=\"http:\/\/www.raspberrypi.org\/archives\/5282\">Mathematica was being made available completely free on the Raspberry Pi<\/a>, I just had to get myself a Pi and have a play.\u00a0 So, I bought the <a href=\"http:\/\/www.maplin.co.uk\/raspberry-pi-pro-kit-783586\">Raspberry Pi Advanced Kit<\/a> from my local Maplin Electronics store, plugged it to the kitchen telly and booted it up.\u00a0 The exercise made me miss my father because the last time I plugged a computer into the kitchen telly was when I was 8 years old; it was Christmas morning and dad and I took our first steps into a new world with my <a href=\"http:\/\/en.wikipedia.org\/wiki\/ZX_Spectrum\">Sinclair Spectrum 48K<\/a>.<\/p>\n<p><strong>How to install Mathematica on the Raspberry Pi<\/strong><\/p>\n<p>Future raspberry pis wll have Mathematica installed by default but mine wasn&#8217;t new enough so I just typed the following at the command line<\/p>\n<pre>sudo apt-get update &amp;&amp; sudo apt-get install wolfram-engine<\/pre>\n<p>On my machine, I was told<\/p>\n<pre>The following extra packages will be installed:\r\n  oracle-java7-jdk\r\nThe following NEW packages will be installed:\r\n  oracle-java7-jdk wolfram-engine\r\n0 upgraded, 2 newly installed, 0 to remove and 1 not upgraded.\r\nNeed to get 278 MB of archives.\r\nAfter this operation, 588 MB of additional disk space will be used.<\/pre>\n<p>So, it seems that Mathematica needs Oracle&#8217;s Java and that&#8217;s being installed for me as well. The combination of the two is going to use up 588MB of disk space which makes me glad that I have an 8Gb SD card in my pi.<\/p>\n<p><strong>Mathematica version 10!<\/strong><\/p>\n<p>On starting Mathematica on the pi, my first big surprise was the version number.\u00a0 I am the administrator of an unlimited academic site license for Mathematica at The University of Manchester and the latest version we can get for our PCs at the time of writing is 9.0.1.\u00a0 My free pi version is at version 10!\u00a0 The first clue is the installation directory:<\/p>\n<pre>\/opt\/Wolfram\/WolframEngine\/10.0<\/pre>\n<p>and the next clue is given by evaluating $Version in Mathematica itself<\/p>\n<pre>In[2]:= $Version\r\n\r\nOut[2]= \"10.0 for Linux ARM (32-bit) (November 19, 2013)\"<\/pre>\n<p>To get an idea of what&#8217;s new in 10, I evaluated the following command on Mathematica on the Pi<\/p>\n<pre>Export[\"PiFuncs.dat\",Names[\"System`*\"]]<\/pre>\n<p>This creates a PiFuncs.dat file which tells me the list of functions in the System context on the version of Mathematica on the pi. Transfer this over to my Windows PC and import into Mathematica 9.0.1 with<\/p>\n<pre>pifuncs = Flatten[Import[\"PiFuncs.dat\"]];<\/pre>\n<p>Get the list of functions from version 9.0.1 on Windows:<\/p>\n<pre>winVer9funcs = Names[\"System`*\"];<\/pre>\n<p>Finally, find out what&#8217;s in pifuncs but not winVer9funcs<\/p>\n<pre>In[16]:= Complement[pifuncs, winVer9funcs]\r\n\r\nOut[16]= {\"Activate\", \"AffineStateSpaceModel\", \"AllowIncomplete\", \\\r\n\"AlternatingFactorial\", \"AntihermitianMatrixQ\", \\\r\n\"AntisymmetricMatrixQ\", \"APIFunction\", \"ArcCurvature\", \"ARCHProcess\", \\\r\n\"ArcLength\", \"Association\", \"AsymptoticOutputTracker\", \\\r\n\"AutocorrelationTest\", \"BarcodeImage\", \"BarcodeRecognize\", \\\r\n\"BoxObject\", \"CalendarConvert\", \"CanonicalName\", \"CantorStaircase\", \\\r\n\"ChromaticityPlot\", \"ClassifierFunction\", \"Classify\", \\\r\n\"ClipPlanesStyle\", \"CloudConnect\", \"CloudDeploy\", \"CloudDisconnect\", \\\r\n\"CloudEvaluate\", \"CloudFunction\", \"CloudGet\", \"CloudObject\", \\\r\n\"CloudPut\", \"CloudSave\", \"ColorCoverage\", \"ColorDistance\", \"Combine\", \\\r\n\"CommonName\", \"CompositeQ\", \"Computed\", \"ConformImages\", \"ConformsQ\", \\\r\n\"ConicHullRegion\", \"ConicHullRegion3DBox\", \"ConicHullRegionBox\", \\\r\n\"ConstantImage\", \"CountBy\", \"CountedBy\", \"CreateUUID\", \\\r\n\"CurrencyConvert\", \"DataAssembly\", \"DatedUnit\", \"DateFormat\", \\\r\n\"DateObject\", \"DateObjectQ\", \"DefaultParameterType\", \\\r\n\"DefaultReturnType\", \"DefaultView\", \"DeviceClose\", \"DeviceConfigure\", \\\r\n\"DeviceDriverRepository\", \"DeviceExecute\", \"DeviceInformation\", \\\r\n\"DeviceInputStream\", \"DeviceObject\", \"DeviceOpen\", \"DeviceOpenQ\", \\\r\n\"DeviceOutputStream\", \"DeviceRead\", \"DeviceReadAsynchronous\", \\\r\n\"DeviceReadBuffer\", \"DeviceReadBufferAsynchronous\", \\\r\n\"DeviceReadTimeSeries\", \"Devices\", \"DeviceWrite\", \\\r\n\"DeviceWriteAsynchronous\", \"DeviceWriteBuffer\", \\\r\n\"DeviceWriteBufferAsynchronous\", \"DiagonalizableMatrixQ\", \\\r\n\"DirichletBeta\", \"DirichletEta\", \"DirichletLambda\", \"DSolveValue\", \\\r\n\"Entity\", \"EntityProperties\", \"EntityProperty\", \"EntityValue\", \\\r\n\"Enum\", \"EvaluationBox\", \"EventSeries\", \"ExcludedPhysicalQuantities\", \\\r\n\"ExportForm\", \"FareySequence\", \"FeedbackLinearize\", \"Fibonorial\", \\\r\n\"FileTemplate\", \"FileTemplateApply\", \"FindAllPaths\", \"FindDevices\", \\\r\n\"FindEdgeIndependentPaths\", \"FindFundamentalCycles\", \\\r\n\"FindHiddenMarkovStates\", \"FindSpanningTree\", \\\r\n\"FindVertexIndependentPaths\", \"Flattened\", \"ForeignKey\", \\\r\n\"FormatName\", \"FormFunction\", \"FormulaData\", \"FormulaLookup\", \\\r\n\"FractionalGaussianNoiseProcess\", \"FrenetSerretSystem\", \"FresnelF\", \\\r\n\"FresnelG\", \"FullInformationOutputRegulator\", \"FunctionDomain\", \\\r\n\"FunctionRange\", \"GARCHProcess\", \"GeoArrow\", \"GeoBackground\", \\\r\n\"GeoBoundaryBox\", \"GeoCircle\", \"GeodesicArrow\", \"GeodesicLine\", \\\r\n\"GeoDisk\", \"GeoElevationData\", \"GeoGraphics\", \"GeoGridLines\", \\\r\n\"GeoGridLinesStyle\", \"GeoLine\", \"GeoMarker\", \"GeoPoint\", \\\r\n\"GeoPolygon\", \"GeoProjection\", \"GeoRange\", \"GeoRangePadding\", \\\r\n\"GeoRectangle\", \"GeoRhumbLine\", \"GeoStyle\", \"Graph3D\", \"GroupBy\", \\\r\n\"GroupedBy\", \"GrowCutBinarize\", \"HalfLine\", \"HalfPlane\", \\\r\n\"HiddenMarkovProcess\", \"\u00ef\u008e\u00af\", \"\u00ef\u00a0\u0080\", \"\u00ef\u00a0\u0081\", \"\u00ef\u00a0\u0082\", \"\u00ef\u00a0\u0083\", \"\u00ef\u00a0\u0084\", \\\r\n\"\u00ef\u00a0\u0085\", \"\u00ef\u00a0\u0086\", \"\u00ef\u00a0\u0087\", \"\u00ef\u00a0\u0088\", \"\u00ef\u00a0\u0089\", \"\u00ef\u00a0\u008a\", \"\u00ef\u00a0\u008b\", \"\u00ef\u00a0\u008c\", \"\u00ef\u00a0\u008d\", \"\u00ef\u00a0\u008e\", \\\r\n\"\u00ef\u00a0\u008f\", \"\u00ef\u00a0\u0090\", \"\u00ef\u00a0\u0091\", \"\u00ef\u00a0\u0092\", \"\u00ef\u00a0\u0093\", \"\u00ef\u00a0\u0094\", \"\u00ef\u00a0\u0095\", \"\u00ef\u00a0\u0096\", \"\u00ef\u00a0\u0097\", \"\u00ef\u00a0\u0098\", \\\r\n\"\u00ef\u00a0\u0099\", \"\u00ef\u00a0\u009a\", \"\u00ef\u00a0\u009b\", \"\u00ef\u00a0\u009c\", \"\u00ef\u00a0\u009d\", \"\u00ef\u00a0\u009e\", \"\u00ef\u00a0\u009f\", \"\u00ef\u00a0\u00a0\", \"\u00ef\u00a0\u00a6\", \"\u00ef\u00a0\u00aa\", \\\r\n\"\u00ef\u00a0\u00af\", \"\u00ef\u00a0\\.b2\", \"\u00ef\u00a0\\.b3\", \"IgnoringInactive\", \"ImageApplyIndexed\", \\\r\n\"ImageCollage\", \"ImageSaliencyFilter\", \"Inactivate\", \"Inactive\", \\\r\n\"IncludeAlphaChannel\", \"IncludeWindowTimes\", \"IndefiniteMatrixQ\", \\\r\n\"IndexedBy\", \"IndexType\", \"InduceType\", \"InferType\", \"InfiniteLine\", \\\r\n\"InfinitePlane\", \"InflationAdjust\", \"InflationMethod\", \\\r\n\"IntervalSlider\", \"\u00ef\u00a0\u00a8\", \"\u00ef\u00a0\u00a2\", \"\u00ef\u00a0\u00a9\", \"\u00ef\u00a0\u00a4\", \"\u00ef\u00a0\\[Degree]\", \"\u00ef\u00a0\u00ad\", \\\r\n\"\u00ef\u00a0\u00a1\", \"\u00ef\u00a0\u00ab\", \"\u00ef\u00a0\u00ae\", \"\u00ef\u00a0\u00a7\", \"\u00ef\u00a0\u00a3\", \"\u00ef\u00a0\u00a5\", \"\u00ef\u00a0\\[PlusMinus]\", \\\r\n\"\u00ef\u00a0\\[Not]\", \"JuliaSetIterationCount\", \"JuliaSetPlot\", \\\r\n\"JuliaSetPoints\", \"KEdgeConnectedGraphQ\", \"Key\", \"KeyDrop\", \\\r\n\"KeyExistsQ\", \"KeyIntersection\", \"Keys\", \"KeySelect\", \"KeySort\", \\\r\n\"KeySortBy\", \"KeyTake\", \"KeyUnion\", \"KillProcess\", \\\r\n\"KVertexConnectedGraphQ\", \"LABColor\", \"LinearGradientImage\", \\\r\n\"LinearizingTransformationData\", \"ListType\", \"LocalAdaptiveBinarize\", \\\r\n\"LocalizeDefinitions\", \"LogisticSigmoid\", \"Lookup\", \"LUVColor\", \\\r\n\"MandelbrotSetIterationCount\", \"MandelbrotSetMemberQ\", \\\r\n\"MandelbrotSetPlot\", \"MinColorDistance\", \"MinimumTimeIncrement\", \\\r\n\"MinIntervalSize\", \"MinkowskiQuestionMark\", \"MovingMap\", \\\r\n\"NegativeDefiniteMatrixQ\", \"NegativeSemidefiniteMatrixQ\", \\\r\n\"NonlinearStateSpaceModel\", \"Normalized\", \"NormalizeType\", \\\r\n\"NormalMatrixQ\", \"NotebookTemplate\", \"NumberLinePlot\", \"OperableQ\", \\\r\n\"OrthogonalMatrixQ\", \"OverwriteTarget\", \"PartSpecification\", \\\r\n\"PlotRangeClipPlanesStyle\", \"PositionIndex\", \\\r\n\"PositiveSemidefiniteMatrixQ\", \"Predict\", \"PredictorFunction\", \\\r\n\"PrimitiveRootList\", \"ProcessConnection\", \"ProcessInformation\", \\\r\n\"ProcessObject\", \"ProcessStatus\", \"Qualifiers\", \"QuantityVariable\", \\\r\n\"QuantityVariableCanonicalUnit\", \"QuantityVariableDimensions\", \\\r\n\"QuantityVariableIdentifier\", \"QuantityVariablePhysicalQuantity\", \\\r\n\"RadialGradientImage\", \"RandomColor\", \"RegularlySampledQ\", \\\r\n\"RemoveBackground\", \"RequiredPhysicalQuantities\", \"ResamplingMethod\", \\\r\n\"RiemannXi\", \"RSolveValue\", \"RunProcess\", \"SavitzkyGolayMatrix\", \\\r\n\"ScalarType\", \"ScorerGi\", \"ScorerGiPrime\", \"ScorerHi\", \\\r\n\"ScorerHiPrime\", \"ScriptForm\", \"Selected\", \"SendMessage\", \\\r\n\"ServiceConnect\", \"ServiceDisconnect\", \"ServiceExecute\", \\\r\n\"ServiceObject\", \"ShowWhitePoint\", \"SourceEntityType\", \\\r\n\"SquareMatrixQ\", \"Stacked\", \"StartDeviceHandler\", \"StartProcess\", \\\r\n\"StateTransformationLinearize\", \"StringTemplate\", \"StructType\", \\\r\n\"SystemGet\", \"SystemsModelMerge\", \"SystemsModelVectorRelativeOrder\", \\\r\n\"TemplateApply\", \"TemplateBlock\", \"TemplateExpression\", \"TemplateIf\", \\\r\n\"TemplateObject\", \"TemplateSequence\", \"TemplateSlot\", \"TemplateWith\", \\\r\n\"TemporalRegularity\", \"ThermodynamicData\", \"ThreadDepth\", \\\r\n\"TimeObject\", \"TimeSeries\", \"TimeSeriesAggregate\", \\\r\n\"TimeSeriesInsert\", \"TimeSeriesMap\", \"TimeSeriesMapThread\", \\\r\n\"TimeSeriesModel\", \"TimeSeriesModelFit\", \"TimeSeriesResample\", \\\r\n\"TimeSeriesRescale\", \"TimeSeriesShift\", \"TimeSeriesThread\", \\\r\n\"TimeSeriesWindow\", \"TimeZoneConvert\", \"TouchPosition\", \\\r\n\"TransformedProcess\", \"TrapSelection\", \"TupleType\", \"TypeChecksQ\", \\\r\n\"TypeName\", \"TypeQ\", \"UnitaryMatrixQ\", \"URLBuild\", \"URLDecode\", \\\r\n\"URLEncode\", \"URLExistsQ\", \"URLExpand\", \"URLParse\", \"URLQueryDecode\", \\\r\n\"URLQueryEncode\", \"URLShorten\", \"ValidTypeQ\", \"ValueDimensions\", \\\r\n\"Values\", \"WhiteNoiseProcess\", \"XMLTemplate\", \"XYZColor\", \\\r\n\"ZoomLevel\", \"$CloudBase\", \"$CloudConnected\", \"$CloudDirectory\", \\\r\n\"$CloudEvaluation\", \"$CloudRootDirectory\", \"$EvaluationEnvironment\", \\\r\n\"$GeoLocationCity\", \"$GeoLocationCountry\", \"$GeoLocationPrecision\", \\\r\n\"$GeoLocationSource\", \"$RegisteredDeviceClasses\", \\\r\n\"$RequesterAddress\", \"$RequesterWolframID\", \"$RequesterWolframUUID\", \\\r\n\"$UserAgentLanguages\", \"$UserAgentMachine\", \"$UserAgentName\", \\\r\n\"$UserAgentOperatingSystem\", \"$UserAgentString\", \"$UserAgentVersion\", \\\r\n\"$WolframID\", \"$WolframUUID\"}<\/pre>\n<p>There we have it, a preview of the list of functions that might be coming in desktop version 10 of Mathematica courtesy of the free Pi version.<\/p>\n<p><strong>No local documentation<\/strong><\/p>\n<p>On a desktop version of Mathematica, all of the Mathematica documentation is available on your local machine by clicking on <strong>Help<\/strong>-&gt;<strong>Documentation Center<\/strong> in the Mathematica notebook interface.<strong>\u00a0\u00a0<\/strong>On the pi version, it seems that there is no local documentation, presumably to keep the installation size down.\u00a0 You get to the documentation via the notebook interface by clicking on <strong>Help<\/strong>-&gt;<strong>OnlineDocumentation<\/strong> which takes you to <a href=\"http:\/\/reference.wolfram.com\/language\/?src=raspi\">http:\/\/reference.wolfram.com\/language\/?src=raspi<\/a><\/p>\n<p><strong>Speed vs my laptop<br \/>\n<\/strong><\/p>\n<p>I am used to running Mathematica on high specification machines and so naturally the pi version felt very sluggish&#8211;particularly when using the notebook interface.\u00a0 With that said, however,\u00a0 I found it very usable for general playing around.\u00a0 I was very curious, however, about the speed of the pi version compared to the version on my home laptop and so created a small benchmark notebook that did three things:<\/p>\n<ul>\n<li>Calculate pi to 1,000,000 decimal places.<\/li>\n<li>Multiply two 1000 x 1000 random matrices together<\/li>\n<li>Integrate sin(x)^2*tan(x) with respect to x<\/li>\n<\/ul>\n<p>The comparison is going to be against my Windows 7 laptop which has a quad-core Intel Core i7-2630QM. The procedure I followed was:<\/p>\n<ul>\n<li>Start a fresh version of the Mathematica notebook and open pi_bench.nb<\/li>\n<li>Click on Evaluation-&gt;Evaluate Notebook and record the times<\/li>\n<li>Click on Evaluation-&gt;Evaluate Notebook again and record the new times.<\/li>\n<\/ul>\n<p>Note that I use the AbsoluteTiming function instead of Timing (<a href=\"http:\/\/mathematica.stackexchange.com\/questions\/14152\/difference-between-absolutetiming-and-timing\">detailed reason given here<\/a>) and I clear the system cache (<a href=\"http:\/\/mathematica.stackexchange.com\/questions\/1115\/making-sure-that-timing-isnt-thrown-off-by-caching\">detailed resason given here<\/a>). \u00a0 You can download the <a href=\"https:\/\/www.walkingrandomly.com\/images\/mathematica9\/pi_bench.nb\">notebook I used here<\/a>.\u00a0 Alternatively, copy and paste the code below<\/p>\n<pre>(*Clear Cache*)\r\nClearSystemCache[]\r\n\r\n(*Calculate pi to 1 million decimal places and store the result*)\r\nAbsoluteTiming[pi = N[Pi, 1000000];]\r\n\r\n(*Multiply two random 1000x1000 matrices together and store the \\\r\nresult*)\r\na = RandomReal[1, {1000, 1000}];\r\nb = RandomReal[1, {1000, 1000}];\r\n\r\nAbsoluteTiming[prod = Dot[a, b];]\r\n\r\n(*calculate an integral and store the result*)\r\nAbsoluteTiming[res = Integrate[Sin[x]^2*Tan[x], x];]<\/pre>\n<p>Here are the results. All timings in seconds.<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<td>Test<\/td>\n<td>Laptop Run 1<\/td>\n<td>Laptop Run 2<\/td>\n<td>RaspPi Run 1<\/td>\n<td>RaspPi Run 2<\/td>\n<td>Best Pi\/Best Laptop<\/td>\n<\/tr>\n<tr>\n<td>Million digits of Pi<\/td>\n<td>0.994057<\/td>\n<td>1.007058<\/td>\n<td>14.101360<\/td>\n<td>13.860549<\/td>\n<td>13.9434<\/td>\n<\/tr>\n<tr>\n<td>Matrix product<\/td>\n<td>0.108006<\/td>\n<td>0.074004<\/td>\n<td>85.076986<\/td>\n<td>85.526180<\/td>\n<td>1149.63<\/td>\n<\/tr>\n<tr>\n<td>Symbolic integral<\/td>\n<td>0.035002<\/td>\n<td>0.008000<\/td>\n<td>0.980086<\/td>\n<td>0.448804<\/td>\n<td>56.1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>From these tests, we see that Mathematica on the pi is around 14 to 1149 times slower on the pi than my laptop. The huge difference between the pi and laptop for the matrix product stems from the fact that ,on the laptop, Mathematica is using <a href=\"http:\/\/software.intel.com\/en-us\/intel-mkl\">Intels Math Kernel Library<\/a> (MKL).\u00a0 The MKL is extremely well optimised for Intel processors and will be using all 4 of the laptop&#8217;s CPU cores along with extra tricks such as <a href=\"https:\/\/www.walkingrandomly.com\/?p=3378\">AVX operations<\/a> etc.\u00a0 I am not sure what is being used on the pi for this operation.<\/p>\n<p>I also ran the standard <strong>BenchMarkReport[]<\/strong> on the Raspberry Pi.\u00a0 The <a href=\"https:\/\/www.walkingrandomly.com\/images\/mathematica9\/PiMathematicaMark9Report.nb\">results are available here<\/a>.<\/p>\n<p><strong>Speed vs Python<\/strong><\/p>\n<p>Comparing Mathematica on the pi to Mathematica on my laptop might have been a fun exercise for me but it&#8217;s not really fair on the pi which wasn&#8217;t designed to perform against expensive laptops. So, let&#8217;s move on to a more meaningful speed comparison: Mathematica on pi versus Python on pi.<\/p>\n<p>When it comes to benchmarking on Python, I usually turn to the <a href=\"http:\/\/docs.python.org\/2\/library\/timeit.html\">timeit module<\/a>. \u00a0This time, however, I&#8217;m not going to use it and that&#8217;s because of something odd that&#8217;s happening with sympy and caching. \u00a0I&#8217;m using sympy to calculate pi to 1 million places and for the symbolic calculus. \u00a0Check out this ipython session on the pi<\/p>\n<pre>pi@raspberrypi ~ $ SYMPY_USE_CACHE=no\r\npi@raspberrypi ~ $ ipython\r\nPython 2.7.3 (default, Jan 13 2013, 11:20:46)\r\nType \"copyright\", \"credits\" or \"license\" for more information.\r\n\r\nIPython 0.13.1 -- An enhanced Interactive Python.\r\n?         -&gt; Introduction and overview of IPython's features.\r\n%quickref -&gt; Quick reference.\r\nhelp      -&gt; Python's own help system.\r\nobject?   -&gt; Details about 'object', use 'object??' for extra details.\r\n\r\nIn [1]: import sympy\r\nIn [2]: pi=sympy.pi.evalf(100000) #Takes a few seconds\r\nIn [3]: %timeit pi=sympy.pi.evalf(100000)\r\n100 loops, best of 3: 2.35 ms per loop<\/pre>\n<p>In short, I have asked sympy not to use caching (I think!) and yet it is caching the result. \u00a0I don&#8217;t want to time how quickly sympy can get a result from the cache so I can&#8217;t use timeit until I figure out what&#8217;s going on here. Since I wanted to publish this post sooner rather than later I just did this:<\/p>\n<pre>import sympy\r\nimport time\r\nimport numpy\r\n\r\nstart = time.time()\r\npi=sympy.pi.evalf(1000000)\r\nelapsed = (time.time() - start)\r\nprint('1 million pi digits: %f seconds' % elapsed)\r\n\r\na = numpy.random.uniform(0,1,(1000,1000))\r\nb = numpy.random.uniform(0,1,(1000,1000))\r\nstart = time.time()\r\nc=numpy.dot(a,b)\r\nelapsed = (time.time() - start)\r\nprint('Matrix Multiply: %f seconds' % elapsed)\r\n\r\nx=sympy.Symbol('x')\r\nstart = time.time()\r\nres=sympy.integrate(sympy.sin(x)**2*sympy.tan(x),x)\r\nelapsed = (time.time() - start)\r\nprint('Symbolic Integration: %f seconds' % elapsed)<\/pre>\n<p>Usually, I&#8217;d use time.clock() to measure things like this but something *very* strange is happening with time.clock() on my pi&#8211;something I&#8217;ll write up later. \u00a0In short, it didn&#8217;t work properly and so I had to resort to time.time().<\/p>\n<p>Here are the results:<\/p>\n<pre>1 million pi digits: 5535.621769 seconds\r\nMatrix Multiply: 77.938481 seconds\r\nSymbolic Integration: 1654.666123 seconds<\/pre>\n<p>The result that really surprised me here was the symbolic integration since the problem I posed didn&#8217;t look very difficult. <strong>Sympy on pi was thousands of times slower<\/strong> <strong>than Mathematica on pi<\/strong> for this calculation! \u00a0On my laptop, the calculation times between Mathematica and sympy were about the same for this operation.<\/p>\n<p>That Mathematica beats sympy for 1 million digits of pi doesn&#8217;t surprise me too much since I recall attending a seminar a few years ago where Wolfram Research described how they had optimized the living daylights out of that particular operation. Nice to see Python beating Mathematica by a little bit in the linear algebra though.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As soon as I heard the news that Mathematica was being made available completely free on the Raspberry Pi, I just had to get myself a Pi and have a play.\u00a0 So, I bought the Raspberry Pi Advanced Kit from my local Maplin Electronics store, plugged it to the kitchen telly and booted it up.\u00a0 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8,31,74],"tags":[],"class_list":["post-5220","post","type-post","status-publish","format-standard","hentry","category-math-software","category-mathematica","category-python","category-raspberry-pi"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3swhs-1mc","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/5220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5220"}],"version-history":[{"count":17,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/5220\/revisions"}],"predecessor-version":[{"id":5244,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/5220\/revisions\/5244"}],"wp:attachment":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}