{"id":3116,"date":"2018-03-21T07:12:21","date_gmt":"2018-03-21T12:12:21","guid":{"rendered":"https:\/\/blogs.mathworks.com\/cleve\/?p=3116"},"modified":"2018-03-21T07:12:21","modified_gmt":"2018-03-21T12:12:21","slug":"matlab-history-modern-matlab-part-1","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/cleve\/2018\/03\/21\/matlab-history-modern-matlab-part-1\/","title":{"rendered":"MATLAB\u00ae  History, Modern MATLAB, part 1"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>The ACM Special Interest Group on Programming Languages, SIGPLAN, expects to hold the fourth in a series of conferences on the History of Programming Languages in 2020, see <a href=\"https:\/\/hopl4.sigplan.org\/\">HOPL-IV<\/a>.  The first drafts of papers are to be submitted by August, 2018.  That long lead time gives me the opportunity to write a detailed history of MATLAB. I plan to write the paper in sections, which I'll post in this blog as they are available.<\/p><p>This is the fifth such installment and the first of a multipart post about modern MATLAB.<\/p><p>Despite its name, MATLAB is not just a Matrix Laboratory any more. It has evolved over the last 35 years into a rich technical computing environment.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#63197696-0da3-4cd2-874f-d20c8dd3481b\">Graphics<\/a><\/li><li><a href=\"#f20fd08c-7189-4c33-bf1e-0908e3ca6d35\">Data types<\/a><\/li><li><a href=\"#33eb8aec-888c-4f8b-bf78-84e484f560ec\">Sparse matrices<\/a><\/li><li><a href=\"#67178a2e-3292-4d33-b06c-043b68ac4693\">Cell arrays<\/a><\/li><li><a href=\"#5e7ddd1a-56b1-4cb7-860c-10bb4dd0cf9e\">Text<\/a><\/li><li><a href=\"#bf21aa58-164f-405c-a71d-24dd5ffc6a99\">Strings<\/a><\/li><li><a href=\"#e2ed0109-91ef-4853-98ff-11a6269504f7\">Commands<\/a><\/li><li><a href=\"#dc1c02e4-6dad-4243-8589-8c9e053c0bb2\">Function handles<\/a><\/li><\/ul><\/div><h4>Graphics<a name=\"63197696-0da3-4cd2-874f-d20c8dd3481b\"><\/a><\/h4><p>PC-MATLAB had only about a dozen graphics commands, including <tt>plot<\/tt> for two-dimensional work and <tt>mesh<\/tt> for three dimensions. The results were rendered on low resolution displays with limited memory and few, if any, colors. But as the equipment evolved, so did MATLAB graphics capabilities.<\/p><p>In 1986 we released a version of MATLAB named PRO-MATLAB, for UNIX workstations including the Sun-3.  The displays and the window systems on these workstations supported more powerful graphics.<\/p><p>In 1992 we released MATLAB 4 for both PCs and workstations. This release included significant new graphics features, including color. I remember struggling with conversion of the RGB color represention that was the basis for our software to the CMYK representation that was expected by the printers of our paper documention. The problem is under specified.  We have three values, R, G and B. They are weighted average of four values, C, M, Y and K. What are those four values? I was immensely pleased when I saw the first successful page proofs for the color insert.<\/p><p>This is not the place to describe all the graphics features we have in MATLAB today.  Here's a sample, four different views of one of our venerable test surfaces.<\/p><pre class=\"codeinput\">   [x,y,z] = peaks;\r\n<\/pre><p>$$ z = 3(1-x) e^{-x^2-(y+1)^2}\r\n   -10(\\textstyle\\frac{x}{5}-x^3-y^5) e^{-x^2-y^2}\r\n   -\\textstyle\\frac{1}{3} e^{-(x+1)^2-y^2} $$<\/p><pre class=\"codeinput\"><span class=\"comment\">%  First, an unadorned surface plot.<\/span>\r\n\r\n   p1 = subplot(2,2,1);\r\n   surf(x,y,z)\r\n   axis <span class=\"string\">tight<\/span>\r\n\r\n<span class=\"comment\">% Next, a 3D bar chart, with some adjustment of the default annotation.<\/span>\r\n\r\n   p2 = subplot(2,2,2);\r\n   k = 1:4:49;\r\n   b = bar3(flipud(z(k,k)));\r\n   fixup(p2,b)\r\n\r\n<span class=\"comment\">% Then, a 2D plot of the columns of the array.<\/span>\r\n\r\n   p3 = subplot(2,2,3);\r\n   plot(z)\r\n\r\n<span class=\"comment\">% Finally, a filled contour plot with 20 levels and a modest color map.<\/span>\r\n\r\n   p4 = subplot(2,2,4);\r\n   contourf(z,20);\r\n   colormap(p4,pink)\r\n   axis <span class=\"string\">off<\/span>\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/modern1_blog_01.png\" alt=\"\"> <h4>Data types<a name=\"f20fd08c-7189-4c33-bf1e-0908e3ca6d35\"><\/a><\/h4><p>For many years MATLAB had only one numeric data type, IEEE standard 754 double precision floating point, stored in the 64-bit format.<\/p><pre class=\"codeinput\">   clear\r\n   format <span class=\"string\">long<\/span>\r\n   phi = (1 + sqrt(5))\/2\r\n<\/pre><pre class=\"codeoutput\">phi =\r\n   1.618033988749895\r\n<\/pre><p>Over several releases, we added support for single precision. Requiring only 32 bits of storage, single precision cuts memory requirements for large arrays in half. It may or may not be faster.<\/p><p>MATLAB does not have declarations, so single precision variables are obtained from double precision ones by an executable conversion function.<\/p><pre class=\"codeinput\">   p = single(phi)\r\n<\/pre><pre class=\"codeoutput\">p =\r\n  single\r\n   1.6180340\r\n<\/pre><p>In 2004 MATLAB 7 introduced three unsigned integer data types, <tt>uint32<\/tt>, <tt>uint16<\/tt> and <tt>uint8<\/tt>, three signed integer data types, <tt>int32<\/tt>, <tt>int16<\/tt>, and <tt>int8<\/tt>, and one logical data type, <tt>logical<\/tt>.<\/p><pre class=\"codeinput\">   q = uint16(1000*phi)\r\n   r = int8(-10*phi)\r\n   s = logical(phi)\r\n<\/pre><pre class=\"codeoutput\">q =\r\n  uint16\r\n   1618\r\nr =\r\n  int8\r\n   -16\r\ns =\r\n  logical\r\n   1\r\n<\/pre><p>Let's see how much storage is requied for these quantities<\/p><pre class=\"codeinput\">   whos\r\n<\/pre><pre class=\"codeoutput\">  Name      Size            Bytes  Class      Attributes\r\n\r\n  p         1x1                 4  single               \r\n  phi       1x1                 8  double               \r\n  q         1x1                 2  uint16               \r\n  r         1x1                 1  int8                 \r\n  s         1x1                 1  logical              \r\n\r\n<\/pre><h4>Sparse matrices<a name=\"33eb8aec-888c-4f8b-bf78-84e484f560ec\"><\/a><\/h4><p>In 1992 MATLAB 4 introduced sparse matrices.  Only the nonzero elements are stored, along with row indices and pointers to the starts of columns. The only change to the outward appearance of MATLAB is a pair of functions, <tt>sparse<\/tt> and <tt>full<\/tt>. Nearly all the operations apply equally to full or sparse matrices.  The sparse storage scheme represents a matrix in space proportional to the number of nonzero entries, and most of the operations compute sparse results in  time proportional to the number of arithmetic operations on nonzeros.<\/p><p>For example, consider the classic finite difference approximation to the Laplacian differential operator.  The function <tt>numgrid<\/tt> numbers the points in a  two-dimensional grid, in this case n-by-n points in the interior of a square.<\/p><pre class=\"codeinput\">   clear\r\n   n = 100;\r\n   S = numgrid(<span class=\"string\">'S'<\/span>,n+2);\r\n<\/pre><p>The function <tt>delsq<\/tt> creates the five-point discrete Laplacian, stored as a sparse N-by-N matrix, where N = n^2.  With five or fewer nonzeros per row, the total number of nonzeros is a little less than 5*N.<\/p><pre class=\"codeinput\">   A = delsq(S);\r\n   nz = nnz(A)\r\n<\/pre><pre class=\"codeoutput\">nz =\r\n       49600\r\n<\/pre><p>For the sake of comparison, let's create the full version of the matrix and check the amount of storage required. Storage required for <tt>A<\/tt> is proportional to N, while for <tt>F<\/tt> it is proportion to N^2.<\/p><pre class=\"codeinput\">   F = full(A);\r\n   whos\r\n<\/pre><pre class=\"codeoutput\">  Name          Size                   Bytes  Class     Attributes\r\n\r\n  A         10000x10000               873608  double    sparse    \r\n  F         10000x10000            800000000  double              \r\n  S           102x102                  83232  double              \r\n  n             1x1                        8  double              \r\n  nz            1x1                        8  double              \r\n\r\n<\/pre><p>Let's time the solution to a boundary value problem. For the sparse matrix the time is O(N^2).  For n = 100 it's instanteous.<\/p><pre class=\"codeinput\">   b = ones(n^2,1);\r\n   tic\r\n   u = A\\b;\r\n   toc\r\n<\/pre><pre class=\"codeoutput\">Elapsed time is 0.018341 seconds.\r\n<\/pre><p>The full matrix time is O(N^3).  It would require several seconds to compute the same solution.<\/p><pre>tic\r\nu = F\\b;\r\ntoc<\/pre><pre>Elapsed time is 7.810682 seconds.<\/pre><h4>Cell arrays<a name=\"67178a2e-3292-4d33-b06c-043b68ac4693\"><\/a><\/h4><p>Cell arrays were introduced with MATLAB 5 in 1996.  A cell array is an indexed, possibly inhomogeneous collection of MATLAB objects, including other cell arrays.  Cell arrays are created by curly braces, {}.<\/p><pre class=\"codeinput\">   c = {magic(3); uint8(1:10); <span class=\"string\">'hello world'<\/span>}\r\n<\/pre><pre class=\"codeoutput\">c =\r\n  3&times;1 cell array\r\n    {3&times;3  double  }\r\n    {1&times;10 uint8   }\r\n    {'hello world'}\r\n<\/pre><p>Cell arrays can be indexed by both curly braces and smooth parentheses.  With braces, c{k} is the contents of the k-th cell. With parentheses, c(k) is another cell array containing the specified cells.<\/p><pre class=\"codeinput\">   M = c{1}\r\n   c2 = c(1)\r\n<\/pre><pre class=\"codeoutput\">M =\r\n     8     1     6\r\n     3     5     7\r\n     4     9     2\r\nc2 =\r\n  1&times;1 cell array\r\n    {3&times;3 double}\r\n<\/pre><p>Think of a cell array as a collection of mailboxes. <tt>box(k)<\/tt> is the <tt>k<\/tt>-th mail box. <tt>box{k}<\/tt> is the mail in the <tt>k<\/tt>-th box.<\/p><h4>Text<a name=\"5e7ddd1a-56b1-4cb7-860c-10bb4dd0cf9e\"><\/a><\/h4><p>For many years, text was a second class citizen in MATLAB.<\/p><p>With concerns about cross platform portability, <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2018\/02\/05\/the-historic-matlab-users-guide\/\">Historic MATLAB<\/a> had its own internal character set.  Text delineated by single quotes was converted a character at a time into floating point numbers in the range 0:51.  Lower case was converted to upper. This process was reversed by the DISP function.<\/p><p>Here is some output from Historic MATLAB.<\/p><pre>&lt;&gt;\r\nH = 'hello world'<\/pre><pre>H     =\r\n   17    14    21    21    24    36    32    24    27    21    13<\/pre><pre>&lt;&gt;\r\ndisp(H)<\/pre><pre>HELLO WORLD<\/pre><p>MathWorks versions of MATLAB have relied on the ASCII character set, including upper and lower case.  Character vectors are still delineated by single quotes.<\/p><pre class=\"codeinput\">   h = <span class=\"string\">'hello world'<\/span>\r\n<\/pre><pre class=\"codeoutput\">h =\r\n    'hello world'\r\n<\/pre><pre class=\"codeinput\">   disp(h)\r\n<\/pre><pre class=\"codeoutput\">hello world\r\n<\/pre><pre class=\"codeinput\">   d = uint8(h)\r\n<\/pre><pre class=\"codeoutput\">d =\r\n  1&times;11 uint8 row vector\r\n   104   101   108   108   111    32   119   111   114   108   100\r\n<\/pre><p>Short character strings are often used as optional parameters to functions.<\/p><pre class=\"language-matlab\">[U,S,V] = svd(A,<span class=\"string\">'econ'<\/span>)  <span class=\"comment\">% Economy size, U is the same shape as A.<\/span>\r\n<\/pre><pre class=\"language-matlab\">plot(x,y,<span class=\"string\">'o-'<\/span>)   <span class=\"comment\">% Plot lines with circles at the data points.<\/span>\r\n<\/pre><p>Multiple lines of text, or many words in an array, must be padded with blanks so that the character array is rectangular. The <tt>char<\/tt> function provides this service.  For example, here is a 3-by-7 array.<\/p><pre class=\"codeinput\">   cast = char(<span class=\"string\">'Alice'<\/span>,<span class=\"string\">'Bob'<\/span>,<span class=\"string\">'Charlie'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">cast =\r\n  3&times;7 char array\r\n    'Alice  '\r\n    'Bob    '\r\n    'Charlie'\r\n<\/pre><p>Or, you could use a cell array.<\/p><pre class=\"codeinput\">   cast = {<span class=\"string\">'Alice'<\/span>, <span class=\"string\">'Bob'<\/span>, <span class=\"string\">'Charlie'<\/span>}'\r\n<\/pre><pre class=\"codeoutput\">cast =\r\n  3&times;1 cell array\r\n    {'Alice'  }\r\n    {'Bob'    }\r\n    {'Charlie'}\r\n<\/pre><h4>Strings<a name=\"bf21aa58-164f-405c-a71d-24dd5ffc6a99\"><\/a><\/h4><p>In 2016, we began the process of providing more comprehensive support for text by introducing the double quote character and the <tt>string<\/tt> data structure.<\/p><pre class=\"codeinput\">   cast = [<span class=\"string\">\"Alice\"<\/span>, <span class=\"string\">\"Bob\"<\/span>, <span class=\"string\">\"Charlie\"<\/span>]'\r\n<\/pre><pre class=\"codeoutput\">cast = \r\n  3&times;1 string array\r\n    \"Alice\"\r\n    \"Bob\"\r\n    \"Charlie\"\r\n<\/pre><p>There are some very convenient functions for the new string data type.<\/p><pre class=\"codeinput\">   proverb = <span class=\"string\">\"A rolling stone gathers momentum\"<\/span>\r\n   words = split(proverb)\r\n<\/pre><pre class=\"codeoutput\">proverb = \r\n    \"A rolling stone gathers momentum\"\r\nwords = \r\n  5&times;1 string array\r\n    \"A\"\r\n    \"rolling\"\r\n    \"stone\"\r\n    \"gathers\"\r\n    \"momentum\"\r\n<\/pre><p>Addition of strings is concatenation.<\/p><pre class=\"codeinput\">   merge = cast(1);\r\n   plus = <span class=\"string\">\" + \"<\/span>;\r\n   <span class=\"keyword\">for<\/span> k = 2:length(cast)\r\n       merge = merge + plus + cast(k);\r\n   <span class=\"keyword\">end<\/span>\r\n   merge\r\n<\/pre><pre class=\"codeoutput\">merge = \r\n    \"Alice + Bob + Charlie\"\r\n<\/pre><p>The <tt>regexp<\/tt> function provides the <i>regular expression<\/i> pattern matching seen in Unix and many other programming languages.<\/p><h4>Commands<a name=\"e2ed0109-91ef-4853-98ff-11a6269504f7\"><\/a><\/h4><p>The distinction between functions and commands was never clear in the early days of MATLAB.  This was eventually resolved by <i>the command\/function duality<\/i>:  A command statement of the form<\/p><pre class=\"language-matlab\">cmd <span class=\"string\">arg1<\/span> <span class=\"string\">arg2<\/span>\r\n<\/pre><p>is the same function statement with <tt>char<\/tt> arguments<\/p><pre class=\"language-matlab\">cmd(<span class=\"string\">'arg1,'<\/span>arg2')\r\n<\/pre><p>For example<\/p><pre class=\"language-matlab\">diary <span class=\"string\">notes.txt<\/span>\r\n<\/pre><p>is the same as<\/p><pre class=\"language-matlab\">f = <span class=\"string\">'notes.txt'<\/span>;\r\ndiary(f)\r\n<\/pre><h4>Function handles<a name=\"dc1c02e4-6dad-4243-8589-8c9e053c0bb2\"><\/a><\/h4><p>MATLAB has functions that take other functions as arguments. These are known as \"function functions\". For many years function arguments were specified by a string. For example, suppose we want to numerically solve the ordinary differential equation for the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Van_der_Pol_oscillator\">Van de Pol oscillator<\/a>.  Create a file <tt>vanderpol.m<\/tt> that evaluates the differential equation.<\/p><pre class=\"codeinput\">   type <span class=\"string\">vanderpol<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction dydt = vanderpol(t,y)\r\n    dydt = [y(2); 5*(1-y(1)^2)*y(2)-y(1)];\r\nend\r\n\r\n<\/pre><p>Then pass the function name as a string to the ODE solver <tt>ode45<\/tt>.<\/p><pre class=\"codeinput\">   tspan = [0 150];\r\n   y0 = [1 0]';\r\n   [t,y] = ode45(<span class=\"string\">'vanderpol'<\/span>,tspan,y0);\r\n<\/pre><p>It turns out that over half the time required by this computation is spent in repeatedly decoding the string argument.  To improve performance we introduced the <i>function handle<\/i>, which is the function name preceeded by the \"at sign\", <tt>@vanderpol<\/tt>.<\/p><p>The \"at sign\" is also used to create a function handle that defines an <i>anonymous function<\/i>, which is the MATLAB instantiation of Church's <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lambda_calculus\">lambda calculus<\/a>.<\/p><pre class=\"language-matlab\">@(x) sin(x).\/x\r\n<\/pre><p>Ironically anonymous functions are often assigned to variables, thereby negating the anonymity.<\/p><pre class=\"codeinput\">   sinc = @(x) sin(x).\/x;\r\n\r\n   vdp = @(t,y) [y(2); 5*(1-y(1)^2)*y(2)-y(1)];\r\n<\/pre><p>Let's compare the times required in our Van der pol integration with strings, function handles and anonymous functions.<\/p><pre class=\"codeinput\">   tic, [t,y] = ode45(<span class=\"string\">'vanderpol'<\/span>,tspan,y0); toc\r\n\r\n   tic, [t,y] = ode45(@vanderpol,tspan,y0); toc\r\n\r\n   tic, [t,y] = ode45(vdp,tspan,y0); toc\r\n<\/pre><pre class=\"codeoutput\">Elapsed time is 0.173259 seconds.\r\nElapsed time is 0.041710 seconds.\r\nElapsed time is 0.032854 seconds.\r\n<\/pre><p>We see that the times required for the later two are comparable, and are significantly faster than the first.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_1a2d0af489d644beb45a9545ea2ed073() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='1a2d0af489d644beb45a9545ea2ed073 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 1a2d0af489d644beb45a9545ea2ed073';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2018 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_1a2d0af489d644beb45a9545ea2ed073()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2018a<br><\/p><\/div><!--\r\n1a2d0af489d644beb45a9545ea2ed073 ##### SOURCE BEGIN #####\r\n%% MATLAB History, Modern MATLAB, part 1\r\n% The ACM Special Interest Group on Programming Languages, SIGPLAN,\r\n% expects to hold the fourth in a series of conferences on\r\n% the History of Programming Languages in 2020, see\r\n% <https:\/\/hopl4.sigplan.org\/ HOPL-IV>.  The first drafts of\r\n% papers are to be submitted by August, 2018.  That long lead time\r\n% gives me the opportunity to write a detailed history of MATLAB.\r\n% I plan to write the paper in sections, which I'll post in\r\n% this blog as they are available.\r\n%\r\n% This is the fifth such installment and the first of a multipart\r\n% post about modern MATLAB.\r\n%\r\n% Despite its name, MATLAB is not just a Matrix Laboratory any more.\r\n% It has evolved over the last 35 years into a rich technical \r\n% computing environment.\r\n\r\n%% Graphics\r\n% PC-MATLAB had only about a dozen graphics commands, including\r\n% |plot| for two-dimensional work and |mesh| for three dimensions.\r\n% The results were rendered on low resolution displays with limited\r\n% memory and few, if any, colors. But as the equipment evolved, so did\r\n% MATLAB graphics capabilities.\r\n\r\n%%\r\n% In 1986 we released a version of MATLAB named PRO-MATLAB, for UNIX\r\n% workstations including the Sun-3.  The displays and the window\r\n% systems on these workstations supported more powerful graphics.\r\n\r\n%%\r\n% In 1992 we released MATLAB 4 for both PCs and workstations.\r\n% This release included significant new graphics features, including\r\n% color.\r\n% I remember struggling with conversion of the RGB color represention\r\n% that was the basis for our software to the CMYK representation that\r\n% was expected by the printers of our paper documention.\r\n% The problem is under specified.  We have three values, R, G and B.\r\n% They are weighted average of four values, C, M, Y and K.\r\n% What are those four values?\r\n% I was immensely pleased when I saw the first successful page proofs\r\n% for the color insert.\r\n\r\n%%\r\n% This is not the place to describe all the graphics features we have in\r\n% MATLAB today.  Here's a sample, four different views of one of\r\n% our venerable test surfaces.\r\n\r\n   [x,y,z] = peaks;\r\n\r\n%%\r\n% $$ z = 3(1-x) e^{-x^2-(y+1)^2} \r\n%    -10(\\textstyle\\frac{x}{5}-x^3-y^5) e^{-x^2-y^2}\r\n%    -\\textstyle\\frac{1}{3} e^{-(x+1)^2-y^2} $$\r\n\r\n%  First, an unadorned surface plot.\r\n\r\n   p1 = subplot(2,2,1);\r\n   surf(x,y,z)\r\n   axis tight\r\n \r\n% Next, a 3D bar chart, with some adjustment of the default annotation.\r\n\r\n   p2 = subplot(2,2,2);\r\n   k = 1:4:49;\r\n   b = bar3(flipud(z(k,k)));\r\n   fixup(p2,b)\r\n\r\n% Then, a 2D plot of the columns of the array.\r\n\r\n   p3 = subplot(2,2,3);\r\n   plot(z)\r\n   \r\n% Finally, a filled contour plot with 20 levels and a modest color map.\r\n\r\n   p4 = subplot(2,2,4);\r\n   contourf(z,20);\r\n   colormap(p4,pink)\r\n   axis off\r\n\r\n%% Data types\r\n% For many years MATLAB had only one numeric data type,\r\n% IEEE standard 754 double precision floating point, stored in the\r\n% 64-bit format.\r\n\r\n   clear\r\n   format long\r\n   phi = (1 + sqrt(5))\/2\r\n   \r\n%% \r\n% Over several releases, we added support for single precision.\r\n% Requiring only 32 bits of storage, single precision cuts memory\r\n% requirements for large arrays in half.\r\n% It may or may not be faster.\r\n%\r\n% MATLAB does not have declarations, so single precision variables\r\n% are obtained from double precision ones by an executable conversion\r\n% function.\r\n\r\n   p = single(phi)\r\n \r\n%%\r\n% In 2004 MATLAB 7 introduced three unsigned integer data types,\r\n% |uint32|, |uint16| and |uint8|, \r\n% three signed integer data types, |int32|, |int16|, and |int8|,\r\n% and one logical data type, |logical|.\r\n\r\n   q = uint16(1000*phi)\r\n   r = int8(-10*phi)\r\n   s = logical(phi)\r\n   \r\n%%\r\n% Let's see how much storage is requied for these quantities\r\n\r\n   whos\r\n   \r\n%% Sparse matrices\r\n% In 1992 MATLAB 4 introduced sparse matrices.  Only the nonzero elements\r\n% are stored, along with row indices and pointers to the starts of columns.\r\n% The only change to the outward appearance of MATLAB is a \r\n% pair of functions, |sparse| and |full|. Nearly all the operations apply\r\n% equally to full or sparse matrices.  The sparse storage scheme represents\r\n% a matrix in space proportional to the number of nonzero entries, and most\r\n% of the operations compute sparse results in  time proportional to the\r\n% number of arithmetic operations on nonzeros.\r\n%\r\n% For example, consider the classic finite difference approximation to the\r\n% Laplacian differential operator.  The function |numgrid| numbers the\r\n% points in a  two-dimensional grid, in this case n-by-n points in the \r\n% interior of a square.\r\n\r\n   clear\r\n   n = 100;\r\n   S = numgrid('S',n+2);\r\n   \r\n%%\r\n% The function |delsq| creates the five-point discrete Laplacian, stored\r\n% as a sparse N-by-N matrix, where N = n^2.  With five or fewer nonzeros\r\n% per row, the total number of nonzeros is a little less than 5*N.\r\n\r\n   A = delsq(S);\r\n   nz = nnz(A)\r\n   \r\n%%\r\n% For the sake of comparison, let's create the full version of the\r\n% matrix and check the amount of storage required.\r\n% Storage required for |A| is proportional to N, while for |F| it is\r\n% proportion to N^2.\r\n\r\n   F = full(A);\r\n   whos\r\n\r\n%%\r\n% Let's time the solution to a boundary value problem.\r\n% For the sparse matrix the time is O(N^2).  For n = 100 it's instanteous.\r\n\r\n   b = ones(n^2,1);\r\n   tic\r\n   u = A\\b;\r\n   toc\r\n   \r\n%%\r\n% The full matrix time is O(N^3).  It would require several seconds\r\n% to compute the same solution.\r\n%\r\n%  tic\r\n%  u = F\\b;\r\n%  toc\r\n%\r\n%  Elapsed time is 7.810682 seconds.\r\n   \r\n%% Cell arrays\r\n% Cell arrays were introduced with MATLAB 5 in 1996.  A cell array is an\r\n% indexed, possibly inhomogeneous collection of MATLAB objects,\r\n% including other cell arrays.  Cell arrays are created by curly braces,\r\n% {}.\r\n\r\n   c = {magic(3); uint8(1:10); 'hello world'}\r\n   \r\n%%\r\n% Cell arrays can be indexed by both curly braces and smooth\r\n% parentheses.  With braces, c{k} is the contents of the k-th cell.\r\n% With parentheses, c(k) is another cell array containing the specified \r\n% cells.\r\n\r\n   M = c{1}\r\n   c2 = c(1)\r\n   \r\n%%\r\n% Think of a cell array as a collection of mailboxes.\r\n% |box(k)| is the |k|-th mail box.\r\n% |box{k}| is the mail in the |k|-th box.\r\n   \r\n%% Text\r\n% For many years, text was a second class citizen in MATLAB.\r\n%\r\n% With concerns about cross platform portability, \r\n% <https:\/\/blogs.mathworks.com\/cleve\/2018\/02\/05\/the-historic-matlab-users-guide\/\r\n% Historic MATLAB>\r\n% had its own internal character set.  Text delineated by single quotes\r\n% was converted a character at a time into floating point numbers in\r\n% the range 0:51.  Lower case was converted to upper.\r\n% This process was reversed by the DISP function.\r\n%\r\n% Here is some output from Historic MATLAB.\r\n%\r\n%  <>\r\n%  H = 'hello world'\r\n%\r\n%  H     =\r\n%     17    14    21    21    24    36    32    24    27    21    13\r\n%\r\n%  <>\r\n%  disp(H)\r\n%\r\n%  HELLO WORLD\r\n\r\n%%\r\n% MathWorks versions of MATLAB have relied on the ASCII character set,\r\n% including upper and lower case.  Character vectors are still delineated\r\n% by single quotes.\r\n\r\n   h = 'hello world'\r\n   \r\n%%\r\n\r\n   disp(h)\r\n   \r\n%%\r\n\r\n   d = uint8(h)\r\n   \r\n%%\r\n% Short character strings are often used as optional parameters to\r\n% functions.\r\n%\r\n%   [U,S,V] = svd(A,'econ')  % Economy size, U is the same shape as A.\r\n%\r\n%   plot(x,y,'o-')   % Plot lines with circles at the data points.\r\n\r\n%%\r\n% Multiple lines of text, or many words in an array, must be padded\r\n% with blanks so that the character array is rectangular.\r\n% The |char| function provides this service.  For example,\r\n% here is a 3-by-7 array.\r\n\r\n   cast = char('Alice','Bob','Charlie')\r\n   \r\n%%\r\n% Or, you could use a cell array.\r\n\r\n   cast = {'Alice', 'Bob', 'Charlie'}'\r\n   \r\n%% Strings\r\n% In 2016, we began the process of providing more comprehensive support \r\n% for text by introducing the double quote character and the\r\n% |string| data structure.\r\n\r\n   cast = [\"Alice\", \"Bob\", \"Charlie\"]'\r\n   \r\n%%\r\n% There are some very convenient functions for the new string data type.\r\n\r\n   proverb = \"A rolling stone gathers momentum\"\r\n   words = split(proverb)\r\n   \r\n%%\r\n% Addition of strings is concatenation.\r\n\r\n   merge = cast(1);\r\n   plus = \" + \";\r\n   for k = 2:length(cast)\r\n       merge = merge + plus + cast(k);\r\n   end\r\n   merge\r\n   \r\n%%\r\n% The |regexp| function provides the _regular expression_ pattern matching\r\n% seen in Unix and many other programming languages.\r\n   \r\n%% Commands\r\n% The distinction between functions and commands was never clear in the\r\n% early days of MATLAB.  This was eventually resolved by\r\n% _the command\/function duality_:  A command statement of the form\r\n%\r\n%   cmd arg1 arg2\r\n% \r\n% is the same function statement with |char| arguments\r\n%\r\n%   cmd('arg1,'arg2')\r\n\r\n%%\r\n% For example\r\n%\r\n%   diary notes.txt\r\n%   \r\n% is the same as\r\n%\r\n%   f = 'notes.txt';\r\n%   diary(f)\r\n\r\n%% Function handles\r\n% MATLAB has functions that take other functions as arguments.\r\n% These are known as \"function functions\".\r\n% For many years function arguments were specified by a string.\r\n% For example, suppose we want to numerically solve\r\n% the ordinary differential equation for the\r\n% <https:\/\/en.wikipedia.org\/wiki\/Van_der_Pol_oscillator\r\n% Van de Pol oscillator>.  Create a file |vanderpol.m| that\r\n% evaluates the differential equation.\r\n\r\n   type vanderpol\r\n   \r\n%%\r\n% Then pass the function name as a string to the ODE solver |ode45|.\r\n\r\n   tspan = [0 150];\r\n   y0 = [1 0]';\r\n   [t,y] = ode45('vanderpol',tspan,y0);\r\n   \r\n%%\r\n% It turns out that over half the time required by this computation\r\n% is spent in repeatedly decoding the string argument.  To improve\r\n% performance we introduced the _function handle_, which is\r\n% the function name preceeded by the \"at sign\", |@vanderpol|.\r\n\r\n%%\r\n% The \"at sign\" is also used to create a function handle\r\n% that defines an _anonymous function_,\r\n% which is the MATLAB instantiation of Church's\r\n% <https:\/\/en.wikipedia.org\/wiki\/Lambda_calculus lambda calculus>.\r\n%\r\n%   @(x) sin(x).\/x\r\n   \r\n%%\r\n% Ironically anonymous functions are often assigned to variables,\r\n% thereby negating the anonymity.\r\n\r\n   sinc = @(x) sin(x).\/x;\r\n   \r\n   vdp = @(t,y) [y(2); 5*(1-y(1)^2)*y(2)-y(1)];\r\n\r\n\r\n%%\r\n% Let's compare the times required in our Van der pol integration\r\n% with strings, function handles and anonymous functions.\r\n\r\n   tic, [t,y] = ode45('vanderpol',tspan,y0); toc\r\n   \r\n   tic, [t,y] = ode45(@vanderpol,tspan,y0); toc\r\n   \r\n   tic, [t,y] = ode45(vdp,tspan,y0); toc\r\n\r\n%%\r\n% We see that the times required for the later two are comparable,\r\n% and are significantly faster than the first.\r\n   \r\n##### SOURCE END ##### 1a2d0af489d644beb45a9545ea2ed073\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/modern1_blog_01.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p>The ACM Special Interest Group on Programming Languages, SIGPLAN, expects to hold the fourth in a series of conferences on the History of Programming Languages in 2020, see <a href=\"https:\/\/hopl4.sigplan.org\/\">HOPL-IV<\/a>.  The first drafts of papers are to be submitted by August, 2018.  That long lead time gives me the opportunity to write a detailed history of MATLAB. I plan to write the paper in sections, which I'll post in this blog as they are available.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/cleve\/2018\/03\/21\/matlab-history-modern-matlab-part-1\/\">read more >><\/a><\/p>","protected":false},"author":78,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[23,4,6],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/3116"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/users\/78"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/comments?post=3116"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/3116\/revisions"}],"predecessor-version":[{"id":3170,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/3116\/revisions\/3170"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media?parent=3116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/categories?post=3116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/tags?post=3116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}