{"id":2437,"date":"2017-04-24T12:00:14","date_gmt":"2017-04-24T17:00:14","guid":{"rendered":"https:\/\/blogs.mathworks.com\/cleve\/?p=2437"},"modified":"2017-04-22T15:55:32","modified_gmt":"2017-04-22T20:55:32","slug":"a-roman-numeral-object-with-arithmetic-matrices-and-a-clock","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/cleve\/2017\/04\/24\/a-roman-numeral-object-with-arithmetic-matrices-and-a-clock\/","title":{"rendered":"A Roman Numeral Object, with Arithmetic, Matrices and a Clock"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>A MATLAB object for arithmetic with Roman numerals provides an example of object oriented programming.  I had originally intended this as my April Fools post, but I got fascinated and decided to make it the subject of a legitimate article.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#04ddd9de-64a2-4b5f-97e6-c1d213d4a97a\">Background<\/a><\/li><li><a href=\"#63b33791-4d8f-4529-aeda-27830e02cbdb\">Roman Numerals<\/a><\/li><li><a href=\"#4020550b-e76e-4b73-ab1f-da8368f0c539\">Extending Roman Numerals<\/a><\/li><li><a href=\"#86bdefa5-58d8-41d8-b470-aa41df7031ac\">Evaluating Input Strings<\/a><\/li><li><a href=\"#8483c6d8-da1a-4de6-b233-3c14ec947b9a\">Roman Object<\/a><\/li><li><a href=\"#661ec456-63be-4d4e-8a51-91e46a5b6cb1\">Producing Character Output<\/a><\/li><li><a href=\"#d6694e9d-922c-44ce-b9cc-c12ba696aaba\">Producing Numeric Output<\/a><\/li><li><a href=\"#b6c97ae3-a42f-4be9-a097-e5b256d40e57\">Roman Methods<\/a><\/li><li><a href=\"#486c080a-bd5a-411d-8add-fc49523c95f7\">Roman Matrices<\/a><\/li><li><a href=\"#5b30dac0-f6b8-4b2d-9426-01d79f74ec44\">Roman Backslash<\/a><\/li><li><a href=\"#fb6222b1-fa44-4b69-a627-da4f0677130e\">Residual<\/a><\/li><li><a href=\"#5b0b22e7-908c-43ea-9531-6ae4c514e051\">Calculator<\/a><\/li><li><a href=\"#f781f368-6265-4142-b1a6-7e0664593466\">Roman Clock<\/a><\/li><\/ul><\/div><h4>Background<a name=\"04ddd9de-64a2-4b5f-97e6-c1d213d4a97a\"><\/a><\/h4><p>I've always been interested in Roman numerals.  In my former life as a professor, when I taught the beginning computer programming course, one of my projects involved Roman numerals.<\/p><p>Doing arithmetic with Roman numerals is tricky.  What is IV + VI ? Stop reading this blog for a moment and compute this sum.<\/p><p>Did you find that IV + VI = X ?  How did you do that?  You probably converted IV and VI to decimal, did the addition using decimal arithmetic, then converted the result back to Roman.  You computed 4 + 6 = 10.  That is also how my <tt>roman<\/tt> object works.  I have no idea how the Romans did it without decimal arithmetic to rely on.<\/p><h4>Roman Numerals<a name=\"63b33791-4d8f-4529-aeda-27830e02cbdb\"><\/a><\/h4><p>Recall that Roman numerals are formed from seven letters<\/p><pre>  I, V, X, L, C, D, and M.<\/pre><p>Their values, expressed in decimal, are<\/p><pre>  1, 5, 10, 50, 100, 500, and 1000.<\/pre><p>A Roman numeral is just a string of these letters, usually in decreasing order, like MMXVII.  The value of the string is the sum of the values of the individual letters, that is 1000+1000+10+5+1+1, which is this year, 2017.  But sometimes the letters are out of order. If one letter is followed by another with higher value, then the value of the first letter is subtracted, rather than added, to the sum. Two years from now will be MMXIX, which is 1000+1000+10-1+10 = 2019.<\/p><h4>Extending Roman Numerals<a name=\"4020550b-e76e-4b73-ab1f-da8368f0c539\"><\/a><\/h4><p>I decided to jazz things up a bit by extending roman numerals to negative and fractional values.  So I allow for a unary minus sign at the beginning of the string, and I allow lower case letters for fractions.  The value of a lower case letter is the value of the corresponding upper case letter divided by 1000.  Here are a few examples.<\/p><pre>  vi = 6\/1000<\/pre><pre>  -c = -100\/1000 = -0.1<\/pre><pre>  mmxvii = 2017\/1000 = 2.017<\/pre><p>These extentions introduce some aspects of floating point arithmetic to the system.  Upper case letters evaluate to integers, equally spaced with an increment of one.  Lower case letters evaluate to fractional values less than one (if you leave off 'm'), with an increment of 1\/1000.<\/p><h4>Evaluating Input Strings<a name=\"86bdefa5-58d8-41d8-b470-aa41df7031ac\"><\/a><\/h4><p>Here is a function that accepts any string, looks for the fourteen letters, and sums their positive or negative values.<\/p><pre class=\"codeinput\">    type <span class=\"string\">roman_eval_string<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction n = roman_eval_string(s)\r\n% Convert a string to the .n component of a Roman numeral.\r\n    D = 'IVXLCDM';\r\n    v = [1 5 10 50 100 500 1000];\r\n    D = [D lower(D)];\r\n    v = [v v\/1000];\r\n    n = 0;\r\n    t = 0;\r\n    for d = s\r\n        k = find(d == D);\r\n        if ~isempty(k)\r\n            u = v(k);\r\n            if t &lt; u\r\n                n = n - t;\r\n            else\r\n                n = n + t;\r\n            end\r\n            t = u;\r\n        end\r\n    end\r\n    n = n + t;\r\n    if ~isempty(s) &amp;&amp; s(1)=='-'\r\n        n = -n;\r\n    end\r\nend\r\n<\/pre><p>Fractional values were obtained by adding just these two lines on code.<\/p><pre>  D = [D lower(D)];\r\n  v = [v v\/1000];<\/pre><p>Negative values come from the sign test at the end of the function.<\/p><p>Let's try it.<\/p><pre class=\"codeinput\">    n = roman_eval_string(<span class=\"string\">'MMXIX'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">n =\r\n        2019\r\n<\/pre><p>This will evaluate any string.  No attempt is made to check for \"correct\" strings.<\/p><pre class=\"codeinput\">    n = roman_eval_string(<span class=\"string\">'DDDCDVIVIIIIIVIIIIC'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">n =\r\n        2019\r\n<\/pre><p>The subtraction rule is not always used.  Clocks with Roman numerals for the hours sometimes denote 4 o'clock by IIII and sometimes by IV. So representations are not unique and correctness is elusive.<\/p><pre class=\"codeinput\">    four = roman_eval_string(<span class=\"string\">'IIII'<\/span>)\r\n    four = roman_eval_string(<span class=\"string\">'IV'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">four =\r\n     4\r\nfour =\r\n     4\r\n<\/pre><h4>Roman Object<a name=\"8483c6d8-da1a-4de6-b233-3c14ec947b9a\"><\/a><\/h4><p>Objects were introduced with MATLAB 5 in 1996.  My first example of a MATLAB object was this <tt>roman<\/tt> object. I now have a directory <tt>@roman<\/tt> on my path.  It includes all of the functions that define <i>methods<\/i> for the <tt>roman<\/tt> object. First and foremost is the <i>constructor<\/i>.<\/p><pre class=\"codeinput\">    type <span class=\"string\">@roman\/roman<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction r = roman(a)\r\n%ROMAN Roman numeral class constructor.\r\n%   r = ROMAN(a) converts a number or a string to a Roman numeral.\r\n%\r\n% A roman object retains its double precision numeric value.\r\n% The string representation of classic Roman numerals use just upper case\r\n% letters.  Our \"floating point\" numerals use both upper and lower case.\r\n%\r\n%        I    1     i  1\/1000 = .001\r\n%        V    5     v  5\/1000 = .002\r\n%        X   10     x  10\/1000 = .01\r\n%        L   50     l  50\/1000 = .05\r\n%        C  100     c  100\/1000 = .1\r\n%        D  500     d  500\/1000 = .5\r\n%        M 1000     m  1000\/1000 = 1\r\n%\r\n% The value of a string is the sum of the values of its letters,\r\n% except a letter followed by one of higher value is subtracted.\r\n%\r\n% Values &gt;= decimal 4000 are represented by 'MMMM'.\r\n% Decimal 0 is represented by blanks.\r\n%\r\n% Blog: https:\/\/blogs.mathworks.com\/cleve\/2017\/04\/24.\r\n% See also: calculator.\r\n\r\n    if nargin == 0\r\n       r.n = [];\r\n       r = class(r,'roman');\r\n       return\r\n    elseif isa(a,'roman')\r\n       r = a;\r\n       return\r\n    elseif isa(a,'char')\r\n       a = roman_eval_string(a);\r\n    end\r\n    r.n = a;\r\n    r = class(r,'roman');\r\n\r\nend % roman\r\n<\/pre><p>If the input <tt>a<\/tt> is already a <tt>roman<\/tt> object, the constructor just returns it.  If <tt>a<\/tt> is a string, such as 'MMXIX', the constructor calls <tt>roman_eval_string<\/tt> to convert <tt>a<\/tt> to a number <tt>n<\/tt>.<\/p><p>Finally the constuctor creates a <tt>roman<\/tt> object <tt>r<\/tt> containing <tt>a<\/tt> in its only field, the numeric value <tt>r.n<\/tt>.  Consequently, we see that a <tt>roman<\/tt> object is just an ordinary double precision floating point number masquerading in this Homeric garb.<\/p><p>For example<\/p><pre class=\"codeinput\">    r = roman(2019)\r\n<\/pre><pre class=\"codeoutput\"> \r\nr = \r\n \r\n    'MMXIX'\r\n \r\n<\/pre><h4>Producing Character Output<a name=\"661ec456-63be-4d4e-8a51-91e46a5b6cb1\"><\/a><\/h4><p>Why did <tt>roman(2019)<\/tt> print <tt>MMXIX<\/tt> in that last example? That's because the object system calls upon <tt>@roman\/display<\/tt>, which in turn calls <tt>@roman\/char<\/tt>, to produce the output printed in the command window.  Here is the crucial function <tt>@roman\/char<\/tt> that converts the numerical field to its Roman representation.<\/p><pre class=\"codeinput\">    type <span class=\"string\">@roman\/char<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction sea = char(r)\r\n% char Generate Roman representation of Roman numeral.\r\n%   c = CHAR(r) converts an @roman number or matrix to a\r\n%   cell array of character strings.\r\n    rn = r.n;\r\n    [p,q] = size(rn);\r\n    sea = cell(p,q);\r\n    for k = 1:p\r\n        for j = 1:q \r\n            if isempty(rn(k,j))\r\n                c = '';           \r\n            elseif isinf(rn(k,j)) || rn(k,j) &gt;= 4000\r\n                c = 'MMMM';\r\n            else\r\n                % Integer part\r\n                n = fix(abs(rn(k,j)));\r\n                f = abs(rn(k,j)) - n;\r\n                c = roman_flint2rom(n);\r\n                % Fractional part, thousandths.\r\n                if f &gt; 0\r\n                   fc = roman_flint2rom(round(1000*f));\r\n                   c = [c lower(fc)];\r\n                end\r\n                % Adjust sign\r\n                if rn(k,j) &lt; 0\r\n                   c = ['-' c];\r\n                end\r\n            end\r\n            sea{k,j} = c;\r\n        end\r\n    end\r\nend % roman\/char\r\n<\/pre><p>The heavy lifting is done by this function which generates the character representation of an integer.<\/p><pre class=\"codeinput\">    type <span class=\"string\">roman_flint2rom<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction c = roman_flint2rom(x) \r\n    D = {'','I','II','III','IV','V','VI','VII','VIII','IX'\r\n         '','X','XX','XXX','XL','L','LX','LXX','LXXX','XC'\r\n         '','C','CC','CCC','CD','D','DC','DCC','DCCC','CM'\r\n         '','M','MM','MMM','  ',' ','  ','   ','    ','  '}; \r\n    n = max(fix(x),0);\r\n    i = 1;\r\n    c = '';\r\n    while n &gt; 0\r\n       c = [D{i,rem(n,10)+1} c];\r\n       n = fix(n\/10);\r\n       i = i + 1;\r\n    end\r\nend\r\n<\/pre><p>The functions <tt>roman_eval_string<\/tt> and <tt>roman_flint2rom<\/tt> are essentially inverses of each other.  One converts a string of letters to a number and the other converts a number to a string of letters.<\/p><p>Converting a string to a numeric value and then converting it back to a string enforces a canonical representation of the result. So a nonconventional Roman numeral gets rectified.<\/p><pre class=\"codeinput\">    r = roman(<span class=\"string\">'MMXVIIII'<\/span>)\r\n<\/pre><pre class=\"codeoutput\"> \r\nr = \r\n \r\n    'MMXIX'\r\n \r\n<\/pre><h4>Producing Numeric Output<a name=\"d6694e9d-922c-44ce-b9cc-c12ba696aaba\"><\/a><\/h4><p>The crucial intermediate quantity in the previous example was the numeric value 2019.  That can be uncovered with a one-liner.<\/p><pre class=\"codeinput\">    type <span class=\"string\">@roman\/double<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction n = double(r)\r\n%DOUBLE Convert Roman numeral to double.\r\n%   n = double(r) is the numeric value of a Roman numeral.\r\n\r\n    n = r.n;\r\n    \r\nend % roman\/double\r\n<\/pre><pre class=\"codeinput\">    year = double(r)\r\n<\/pre><pre class=\"codeoutput\">year =\r\n        2019\r\n<\/pre><h4>Roman Methods<a name=\"b6c97ae3-a42f-4be9-a097-e5b256d40e57\"><\/a><\/h4><p>Here are all the operations that I can currently do with the <tt>roman<\/tt> class.  I've overloaded just a handful to provide a proof of concept.<\/p><pre class=\"codeinput\">    methods(r)\r\n<\/pre><pre class=\"codeoutput\">\r\nMethods for class roman:\r\n\r\nchar      display   minus     mrdivide  plus      \r\ndisp      double    mldivide  mtimes    roman     \r\n\r\n<\/pre><p>Binary arithmetic operations on <tt>roman<\/tt> objects are easy. Make sure both operands are <tt>roman<\/tt> and then do the arithmetic on the numeric fields.<\/p><pre class=\"codeinput\">    type <span class=\"string\">@roman\/plus<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction r = plus(p,q)\r\n    p = roman(p);\r\n    q = roman(q);\r\n    r = roman(p.n + q.n);\r\nend % roman\/plus\r\n<\/pre><p>So this is why IV + VI = X is just 4 + 6 = 10 under the covers.<\/p><pre class=\"codeinput\">    r = roman(<span class=\"string\">'IV'<\/span>) + roman(<span class=\"string\">'VI'<\/span>)\r\n<\/pre><pre class=\"codeoutput\"> \r\nr = \r\n \r\n    'X'\r\n \r\n<\/pre><h4>Roman Matrices<a name=\"486c080a-bd5a-411d-8add-fc49523c95f7\"><\/a><\/h4><p>Did you notice that the output method <tt>char<\/tt> will handle matrices? Let's try one.  Magic squares have integer elements.  Here is the 4-by-4 from Durer's Melancholia II.<\/p><pre class=\"codeinput\">   M = roman(magic(4))\r\n<\/pre><pre class=\"codeoutput\"> \r\nM = \r\n \r\n    'XVI'    'II'     'III'    'XIII'\r\n    'V'      'XI'     'X'      'VIII'\r\n    'IX'     'VII'    'VI'     'XII' \r\n    'IV'     'XIV'    'XV'     'I'   \r\n \r\n<\/pre><p>Check that its row sums are all the same.<\/p><pre class=\"codeinput\">   e = roman(ones(4,1))\r\n   Me = M*e\r\n<\/pre><pre class=\"codeoutput\"> \r\ne = \r\n \r\n    'I'\r\n    'I'\r\n    'I'\r\n    'I'\r\n \r\n \r\nMe = \r\n \r\n    'XXXIV'\r\n    'XXXIV'\r\n    'XXXIV'\r\n    'XXXIV'\r\n \r\n<\/pre><h4>Roman Backslash<a name=\"5b30dac0-f6b8-4b2d-9426-01d79f74ec44\"><\/a><\/h4><p>I've overloaded <tt>mldivide<\/tt>, so I can solve linear systems and compute inverses. All the elements of the 4-by-4 inverse Hilbert matrix are integers, but some are larger than 4000, so I'll scale the matrix by a factor of 2.<\/p><pre class=\"codeinput\">   X = invhilb(4)\/2\r\n   A = roman(X)\r\n<\/pre><pre class=\"codeoutput\">X =\r\n           8         -60         120         -70\r\n         -60         600       -1350         840\r\n         120       -1350        3240       -2100\r\n         -70         840       -2100        1400\r\n \r\nA = \r\n \r\n    'VIII'    '-LX'       'CXX'        '-LXX'  \r\n    '-LX'     'DC'        '-MCCCL'     'DCCCXL'\r\n    'CXX'     '-MCCCL'    'MMMCCXL'    '-MMC'  \r\n    '-LXX'    'DCCCXL'    '-MMC'       'MCD'   \r\n \r\n<\/pre><p>Inverting and rescaling <tt>A<\/tt> should produce the Hilbert matrix itself, where all of the elements are familiar fractions. I'll need the identity matrix, suitably scaled.<\/p><pre class=\"codeinput\">   I = roman(eye(4))\/2\r\n<\/pre><pre class=\"codeoutput\"> \r\nI = \r\n \r\n    'd'    ''     ''     '' \r\n    ''     'd'    ''     '' \r\n    ''     ''     'd'    '' \r\n    ''     ''     ''     'd'\r\n \r\n<\/pre><p>Now I call employ backslash to compute the inverse.  Do you recognize the familiar fractions?<\/p><pre class=\"codeinput\">   H = A\\I\r\n<\/pre><pre class=\"codeoutput\"> \r\nH = \r\n \r\n    'm'            'd'            'cccxxxiii'    'ccl'   \r\n    'd'            'cccxxxiii'    'ccl'          'cc'    \r\n    'cccxxxiii'    'ccl'          'cc'           'clxvii'\r\n    'ccl'          'cc'           'clxvii'       'cxliii'\r\n \r\n<\/pre><p>Here is some homework: why is <tt>H(1,1)<\/tt> represented by <tt>'m'<\/tt>, when it should be <tt>'I'<\/tt>?<\/p><h4>Residual<a name=\"fb6222b1-fa44-4b69-a627-da4f0677130e\"><\/a><\/h4><p>Finally, check the residual.  It's all zero -- to the nearest thousandths.<\/p><pre class=\"codeinput\">   R = I - A*H\r\n<\/pre><pre class=\"codeoutput\"> \r\nR = \r\n \r\n    ''    ''     ''     '-'\r\n    ''    ''     ''     '' \r\n    ''    ''     ''     '' \r\n    ''    '-'    '-'    '' \r\n \r\n<\/pre><h4>Calculator<a name=\"5b0b22e7-908c-43ea-9531-6ae4c514e051\"><\/a><\/h4><p>Two gizmos that exhibit the <tt>roman<\/tt> object are included in <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/59085-cleve-laboratory\">Version 3.0 of Cleve's Laboratory<\/a>.  One is a calculator.<\/p><pre class=\"codeinput\">   calculator(2017)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/roman_blog_01.png\" alt=\"\"> <h4>Roman Clock<a name=\"f781f368-6265-4142-b1a6-7e0664593466\"><\/a><\/h4><p>The clock captures the date and time whenever I publish this blog.<\/p><pre class=\"codeinput\">   roman_clock_snapshot\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/roman_blog_02.png\" alt=\"\"> <p>OK, let's quit foolin' around and get back to serious business.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_e8271352388f47c4b4eae2c80f10f8f7() {\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='e8271352388f47c4b4eae2c80f10f8f7 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' e8271352388f47c4b4eae2c80f10f8f7';\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 2017 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_e8271352388f47c4b4eae2c80f10f8f7()\"><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; R2017a<br><\/p><\/div><!--\r\ne8271352388f47c4b4eae2c80f10f8f7 ##### SOURCE BEGIN #####\r\n%% A Roman Numeral Object, with Arithmetic, Matrices and a Clock\r\n% A MATLAB object for arithmetic with Roman numerals provides an\r\n% example of object oriented programming.  I had originally intended\r\n% this as my April Fools post, but I got fascinated and decided to make\r\n% it the subject of a legitimate article.\r\n\r\n%% Background\r\n% I've always been interested in Roman numerals.  In my former life\r\n% as a professor, when I taught the beginning computer programming\r\n% course, one of my projects involved Roman numerals.\r\n\r\n%%\r\n% Doing arithmetic with Roman numerals is tricky.  What is IV + VI ?\r\n% Stop reading this blog for a moment and compute this sum.\r\n\r\n%%\r\n% Did you find that IV + VI = X ?  How did you do that?  You probably\r\n% converted IV and VI to decimal, did the addition using decimal\r\n% arithmetic, then converted the result back to Roman.  You computed\r\n% 4 + 6 = 10.  That is also how my |roman| object works.  I have no\r\n% idea how the Romans did it without decimal arithmetic to rely on.\r\n\r\n%% Roman Numerals\r\n% Recall that Roman numerals are formed from seven letters\r\n%\r\n%    I, V, X, L, C, D, and M.\r\n%\r\n% Their values, expressed in decimal, are\r\n%\r\n%    1, 5, 10, 50, 100, 500, and 1000.\r\n\r\n%%\r\n% A Roman numeral is just a string of these letters, usually in\r\n% decreasing order, like MMXVII.  The value of the string is the sum\r\n% of the values of the individual letters, that is 1000+1000+10+5+1+1,\r\n% which is this year, 2017.  But sometimes the letters are out of order.\r\n% If one letter is followed by another with higher value, then the value\r\n% of the first letter is subtracted, rather than added, to the sum.\r\n% Two years from now will be MMXIX, which is 1000+1000+10-1+10 = 2019.\r\n\r\n%% Extending Roman Numerals\r\n% I decided to jazz things up a bit by extending roman numerals to\r\n% negative and fractional values.  So I allow for a unary minus sign\r\n% at the beginning of the string, and I allow lower case letters for\r\n% fractions.  The value of a lower case letter is the value of the\r\n% corresponding upper case letter divided by 1000.  Here are a few \r\n% examples.\r\n%\r\n%    vi = 6\/1000\r\n%\r\n%    -c = -100\/1000 = -0.1\r\n%\r\n%    mmxvii = 2017\/1000 = 2.017\r\n\r\n%%\r\n% These extentions introduce some aspects of floating point arithmetic\r\n% to the system.  Upper case letters evaluate to integers, equally spaced\r\n% with an increment of one.  Lower case letters evaluate to fractional\r\n% values less than one (if you leave off 'm'), with an increment of 1\/1000.\r\n\r\n%% Evaluating Input Strings\r\n% Here is a function that accepts any string, looks for the fourteen\r\n% letters, and sums their positive or negative values.\r\n\r\n    type roman_eval_string\r\n    \r\n%%\r\n% Fractional values were obtained by adding just these two lines on code.\r\n%\r\n%    D = [D lower(D)];\r\n%    v = [v v\/1000];\r\n%\r\n% Negative values come from the sign test at the end of the function.\r\n    \r\n%%\r\n% Let's try it.\r\n\r\n    n = roman_eval_string('MMXIX')\r\n    \r\n%%\r\n% This will evaluate any string.  No attempt is made to check for \r\n% \"correct\" strings.\r\n\r\n    n = roman_eval_string('DDDCDVIVIIIIIVIIIIC')\r\n   \r\n%%\r\n% The subtraction rule is not always used.  Clocks with Roman numerals\r\n% for the hours sometimes denote 4 o'clock by IIII and sometimes by IV.\r\n% So representations are not unique and correctness is elusive.\r\n\r\n    four = roman_eval_string('IIII')\r\n    four = roman_eval_string('IV')\r\n    \r\n\r\n%% Roman Object\r\n% Objects were introduced with MATLAB 5 in 1996.  My first example of\r\n% a MATLAB object was this |roman| object.  \r\n% I now have a directory |@roman| on my path.  It includes all\r\n% of the functions that define _methods_ for the |roman| object.\r\n% First and foremost is the _constructor_.\r\n\r\n    type @roman\/roman\r\n    \r\n%%\r\n% If the input |a| is already a |roman| object, the constructor just\r\n% returns it.  If |a| is a string, such as 'MMXIX', the constructor\r\n% calls |roman_eval_string| to convert |a| to a number |n|.\r\n\r\n%%\r\n% Finally the constuctor creates a |roman| object |r| containing |a| in\r\n% its only field, the numeric value |r.n|.  Consequently, we see that a \r\n% |roman| object is just an ordinary double precision floating point\r\n% number masquerading in this Homeric garb.\r\n    \r\n%%\r\n% For example\r\n\r\n    r = roman(2019)\r\n    \r\n%% Producing Character Output\r\n% Why did |roman(2019)| print |MMXIX| in that last example?\r\n% That's because the object system calls upon |@roman\/display|, which\r\n% in turn calls |@roman\/char|, to produce the output printed in the\r\n% command window.  Here is the crucial function |@roman\/char| that\r\n% converts the numerical field to its Roman representation.\r\n    \r\n    type @roman\/char\r\n    \r\n%%\r\n% The heavy lifting is done by this function which generates the\r\n% character representation of an integer.\r\n\r\n    type roman_flint2rom\r\n    \r\n%%\r\n% The functions |roman_eval_string| and |roman_flint2rom| are\r\n% essentially inverses of each other.  One converts a string of letters\r\n% to a number and the other converts a number to a string of letters.\r\n    \r\n%%\r\n% Converting a string to a numeric value and then converting it back\r\n% to a string enforces a canonical representation of the result.\r\n% So a nonconventional Roman numeral gets rectified.\r\n\r\n    r = roman('MMXVIIII')\r\n    \r\n%% Producing Numeric Output\r\n% The crucial intermediate quantity in the previous example was the\r\n% numeric value 2019.  That can be uncovered with a one-liner.\r\n\r\n    type @roman\/double\r\n    \r\n%%\r\n    year = double(r)\r\n\r\n%% Roman Methods\r\n% Here are all the operations that I can currently do with the |roman|\r\n% class.  I've overloaded just a handful to provide a proof of concept.\r\n\r\n    methods(r)\r\n    \r\n%%\r\n% Binary arithmetic operations on |roman| objects are easy.\r\n% Make sure both operands are |roman| and then do the arithmetic on\r\n% the numeric fields.\r\n\r\n    type @roman\/plus\r\n    \r\n%%\r\n% So this is why IV + VI = X is just 4 + 6 = 10 under the covers.\r\n\r\n    r = roman('IV') + roman('VI')\r\n   \r\n%% Roman Matrices\r\n% Did you notice that the output method |char| will handle matrices?\r\n% Let's try one.  Magic squares have integer elements.  Here is the\r\n% 4-by-4 from Durer's Melancholia II.\r\n\r\n   M = roman(magic(4))\r\n   \r\n%%\r\n% Check that its row sums are all the same.\r\n\r\n   e = roman(ones(4,1))\r\n   Me = M*e\r\n   \r\n%% Roman Backslash\r\n% I've overloaded |mldivide|, so I can solve linear systems and\r\n% compute inverses.\r\n% All the elements of the 4-by-4 inverse Hilbert matrix are integers,\r\n% but some are larger than 4000, so I'll scale the matrix by a factor of 2.\r\n\r\n   X = invhilb(4)\/2\r\n   A = roman(X)\r\n   \r\n%%\r\n% Inverting and rescaling |A| should produce the Hilbert matrix\r\n% itself, where all of the elements are familiar fractions.\r\n% I'll need the identity matrix, suitably scaled.\r\n\r\n   I = roman(eye(4))\/2\r\n \r\n%%\r\n% Now I call employ backslash to compute the inverse.  Do you recognize\r\n% the familiar fractions?\r\n   \r\n   H = A\\I\r\n   \r\n%%\r\n% Here is some homework: why is |H(1,1)| represented by |'m'|,\r\n% when it should be |'I'|?\r\n   \r\n%% Residual\r\n% Finally, check the residual.  It's all zero REPLACE_WITH_DASH_DASH to the nearest\r\n% thousandths.\r\n\r\n   R = I - A*H\r\n\r\n%% Calculator\r\n% Two gizmos that exhibit the |roman| object are included in \r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/59085-cleve-laboratory\r\n% Version 3.0 of Cleve's Laboratory>.  One is a calculator.\r\n\r\n   calculator(2017)\r\n   \r\n%% Roman Clock\r\n% The clock captures the date and time whenever I publish this blog.\r\n\r\n   roman_clock_snapshot\r\n   \r\n%%\r\n% OK, let's quit foolin' around and get back to serious business.\r\n\r\n##### SOURCE END ##### e8271352388f47c4b4eae2c80f10f8f7\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/roman_blog_01.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p>A MATLAB object for arithmetic with Roman numerals provides an example of object oriented programming.  I had originally intended this as my April Fools post, but I got fascinated and decided to make it the subject of a legitimate article.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/cleve\/2017\/04\/24\/a-roman-numeral-object-with-arithmetic-matrices-and-a-clock\/\">read more >><\/a><\/p>","protected":false},"author":78,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,4,6],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/2437"}],"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=2437"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/2437\/revisions"}],"predecessor-version":[{"id":2442,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/2437\/revisions\/2442"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media?parent=2437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/categories?post=2437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/tags?post=2437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}