index.html 190 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929
  1. <!DOCTYPE html>
  2. <html>
  3. <!-- Created by GNU Texinfo 7.0.1, https://www.gnu.org/software/texinfo/ -->
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6. <!-- ra:: (version 21, updated 2023 July 8)
  7. (c) Daniel Llorens 2005-2023
  8. Permission is granted to copy, distribute and/or modify this document
  9. under the terms of the GNU Free Documentation License, Version 1.3 or
  10. any later version published by the Free Software Foundation; with no
  11. Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. -->
  12. <title>ra:: — An array library for C++20</title>
  13. <meta name="description" content="ra:: — An array library for C++20">
  14. <meta name="keywords" content="ra:: — An array library for C++20">
  15. <meta name="resource-type" content="document">
  16. <meta name="distribution" content="global">
  17. <meta name="Generator" content="makeinfo">
  18. <meta name="viewport" content="width=device-width,initial-scale=1">
  19. <link href="#Top" rel="start" title="Top">
  20. <link href="#Indices" rel="index" title="Indices">
  21. <link href="#Overview" rel="next" title="Overview">
  22. <style type="text/css">
  23. <!--
  24. a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
  25. a.summary-letter-printindex {text-decoration: none}
  26. div.display {margin-left: 3.2em}
  27. div.example {margin-left: 3.2em}
  28. pre.display-preformatted {font-family: inherit}
  29. span:hover a.copiable-link {visibility: visible}
  30. strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
  31. td.printindex-index-entry {vertical-align: top}
  32. td.printindex-index-section {vertical-align: top}
  33. th.entries-header-printindex {text-align:left}
  34. th.sections-header-printindex {text-align:left}
  35. ul.mark-bullet {list-style-type: disc}
  36. -->
  37. </style>
  38. <script type='text/javascript'>
  39. MathJax = {
  40. options: {
  41. skipHtmlTags: {'[-]': ['pre']},
  42. ignoreHtmlClass: 'tex2jax_ignore',
  43. processHtmlClass: 'tex2jax_process'
  44. },
  45. };
  46. </script><script type="text/javascript" id="MathJax-script" async
  47. src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
  48. </script>
  49. </head>
  50. <body lang="en" class="tex2jax_ignore">
  51. <div class="top-level-extent" id="Top">
  52. <div class="nav-panel">
  53. <p>
  54. Next: <a href="#Overview" accesskey="n" rel="next">Overview</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  55. </div>
  56. <h1 class="top" id="ra_003a_003a"><code class="code">ra::</code></h1>
  57. <p><code class="code">ra::</code> (version 21, updated 2023 July 8)
  58. </p>
  59. <p>(c) Daniel Llorens 2005&ndash;2023
  60. </p>
  61. <div class="display smalldisplay">
  62. <pre class="display-preformatted">Permission is granted to copy, distribute and/or modify this document
  63. under the terms of the GNU Free Documentation License, Version 1.3 or
  64. any later version published by the Free Software Foundation; with no
  65. Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
  66. </pre></div>
  67. <p><code class="code">ra::</code><a class="footnote" id="DOCF1" href="#FOOT1"><sup>1</sup></a> is a general purpose multidimensional array and expression template library for C++20. Please keep in mind that this manual is a work in progress. There are many errors and whole sections unwritten.
  68. </p>
  69. <ul class="mini-toc">
  70. <li><a href="#Overview" accesskey="1">Overview</a></li>
  71. <li><a href="#Usage" accesskey="2">Usage</a></li>
  72. <li><a href="#Extras" accesskey="3">Extras</a></li>
  73. <li><a href="#Hazards" accesskey="4">Hazards</a></li>
  74. <li><a href="#Internals" accesskey="5">Internals</a></li>
  75. <li><a href="#The-future" accesskey="6">The future</a></li>
  76. <li><a href="#Reference" accesskey="7">Reference</a></li>
  77. <li><a href="#Sources" accesskey="8">Sources</a></li>
  78. <li><a href="#Indices" accesskey="9">Indices</a></li>
  79. <li><a href="#Notes">Notes</a></li>
  80. </ul>
  81. <hr>
  82. <div class="chapter-level-extent" id="Overview">
  83. <div class="nav-panel">
  84. <p>
  85. Next: <a href="#Usage" accesskey="n" rel="next">Usage</a>, Previous: <a href="#Top" accesskey="p" rel="prev"><code class="code">ra::</code></a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  86. </div>
  87. <h2 class="chapter" id="Overview-1">1 Overview</h2>
  88. <a class="index-entry-id" id="index-length"></a>
  89. <a class="index-entry-id" id="index-rank"></a>
  90. <a class="index-entry-id" id="index-shape"></a>
  91. <p>A multidimensional array is a container whose elements can be looked up using a multi-index (i₀, i₁, ...). Each of the indices i₀, i₁, ... has a constant range [0, n₀), [0, n₁), ... independent of the values of the other indices, so the array is ‘rectangular’. The number of indices in the multi-index is the <em class="dfn">rank</em> of the array, and the list of all the <em class="dfn">lengths</em> (n₀, n₁, ... nᵣ₋₁) is the <em class="dfn">shape</em> of the array. We speak of a rank-<em class="math tex2jax_process">\(r\)</em> array or of an <em class="math tex2jax_process">\(r\)</em>-array.
  92. </p>
  93. <p>Often we deal with multidimensional <em class="emph">expressions</em> where the elements aren&rsquo;t stored anywhere, but are computed on demand when the expression is looked up. In this general sense, an ‘array’ is just a function of integers with a rectangular domain.
  94. </p>
  95. <p>Arrays (as a representation of <em class="dfn">matrices</em>, <em class="dfn">vectors</em>, or <em class="dfn">tensors</em>) are common objects in math and programming, and it is very useful to be able to manipulate arrays as individual entities rather than as aggregates. Not only is
  96. </p>
  97. <pre class="verbatim">A = B+C;
  98. </pre>
  99. <p>much more compact and easier to read than
  100. </p>
  101. <pre class="verbatim">for (int i=0; i!=m; ++i)
  102. for (int j=0; j!=n; ++j)
  103. for (int k=0; k!=p; ++k)
  104. A(i, j, k) = B(i, j, k)+C(i, j, k);
  105. </pre>
  106. <p>but it&rsquo;s also safer and less redundant. For example, the order of the loops may be something you don&rsquo;t really care about.
  107. </p>
  108. <p>However, if array operations are implemented naively, a piece of code such as <code class="code">A=B+C</code> may result in the creation of a temporary to hold <code class="code">B+C</code> which is then assigned to <code class="code">A</code>. This is wasteful if the arrays involved are large.
  109. </p>
  110. <a class="index-entry-id" id="index-Blitz_002b_002b"></a>
  111. <p>Fortunately the problem is almost as old as aggregate data types, and other programming languages have addressed it with optimizations such as <a class="url" href="https://en.wikipedia.org/wiki/Loop_fission_and_fusion">‘loop fusion’</a>, ‘drag along’ [<a class="ref" href="#Sources">Abr70</a>]
  112. , or ‘deforestation’ [<a class="ref" href="#Sources">Wad90</a>]
  113. . In the C++ context the technique of ‘expression templates’ was pioneered in the late 90s by libraries such as Blitz++ [<a class="ref" href="#Sources">bli17</a>]
  114. . It works by making <code class="code">B+C</code> into an ‘expression object’ which holds references to its arguments and performs the sum only when its elements are looked up. The compiler removes the temporary expression objects during optimization, so that <code class="code">A=B+C</code> results (in principle) in the same generated code as the complicated loop nest above.
  115. </p>
  116. <ul class="mini-toc">
  117. <li><a href="#Rank-polymorphism" accesskey="1">Rank polymorphism</a></li>
  118. <li><a href="#Drag-along-and-beating" accesskey="2">Drag along and beating</a></li>
  119. <li><a href="#Why-C_002b_002b" accesskey="3">Why C++</a></li>
  120. <li><a href="#Guidelines" accesskey="4">Guidelines</a></li>
  121. <li><a href="#Other-libraries" accesskey="5">Other array libraries</a></li>
  122. </ul>
  123. <hr>
  124. <div class="section-level-extent" id="Rank-polymorphism">
  125. <div class="nav-panel">
  126. <p>
  127. Next: <a href="#Drag-along-and-beating" accesskey="n" rel="next">Drag along and beating</a>, Up: <a href="#Overview" accesskey="u" rel="up">Overview</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  128. </div>
  129. <h3 class="section" id="Rank-polymorphism-1">1.1 Rank polymorphism</h3>
  130. <p><em class="dfn">Rank polymorphism</em> is the ability to treat an array of rank <em class="math tex2jax_process">\(r\)</em> as an array of lower rank where the elements are themselves arrays.
  131. </p>
  132. <a class="index-entry-id" id="index-cell"></a>
  133. <a class="index-entry-id" id="index-frame"></a>
  134. <p>For example, think of a matrix A, a 2-array with shape (n₀, n₁) where the elements A(i₀, i₁) are numbers. If we consider the subarrays A(0, ...), A(1, ...), ..., A(n₀-1, ...) as individual elements, then we have a new view of A as a 1-array of length n₀ with those rows as elements. We say that the rows A(i₀)≡A(i₀, ...) are the 1-<em class="dfn">cells</em> of A, and the numbers A(i₀, i₁) are 0-cells of A. For an array of arbitrary rank <em class="math tex2jax_process">\(r\)</em> the (<em class="math tex2jax_process">\(r\)</em>-1)-cells of A are called its <em class="dfn">items</em>. The prefix of the shape (n₀, n₁, ... nₙ₋₁₋ₖ) that is not taken up by the k-cell is called the k-<em class="dfn">frame</em>.
  135. </p>
  136. <p>An obvious way to store an array in linearly addressed memory is to place its items one after another. So we would store a 3-array as
  137. </p>
  138. <blockquote class="quotation">
  139. <p>A: [A(0), A(1), ...]
  140. </p></blockquote>
  141. <p>and the items of A(i₀), etc. are in turn stored in the same way, so
  142. </p>
  143. <blockquote class="quotation">
  144. <p>A: [A(0): [A(0, 0), A(0, 1) ...], ...]
  145. </p></blockquote>
  146. <p>and the same for the items of A(i₀, i₁), etc.
  147. </p>
  148. <blockquote class="quotation">
  149. <p>A: [[A(0, 0): [A(0, 0, 0), A(0, 0, 1) ...], A(0, 1): [A(0, 1, 0), A(0, 1, 1) ...]], ...]
  150. </p></blockquote>
  151. <a class="index-entry-id" id="index-order_002c-row_002dmajor"></a>
  152. <p>This way to lay out an array in memory is called <em class="dfn">row-major order</em> or <em class="dfn">C-order</em>, since it&rsquo;s the default order for built-in arrays in C (see <a class="pxref" href="#Other-libraries">Other array libraries</a>). A row-major array A with shape (n₀, n₁, ... nᵣ₋₁) can be looked up like this:
  153. </p>
  154. <a class="anchor" id="x_002dsteps"></a><blockquote class="quotation">
  155. <p>A(i₀, i₁, ...) = (storage-of-A) [(((i₀n₁ + i₁)n₂ + i₂)n₃ + ...)+iᵣ₋₁] = (storage-of-A) [o + s₀i₀ + s₁i₁ + ...]
  156. </p></blockquote>
  157. <a class="index-entry-id" id="index-step"></a>
  158. <a class="index-entry-id" id="index-stride"></a>
  159. <p>where the numbers (s₀, s₁, ...) are called the <em class="dfn">steps</em><a class="footnote" id="DOCF2" href="#FOOT2"><sup>2</sup></a>. Note that the ‘linear’ or ‘raveled’ address [o + s₀i₀ + s₁i₁ + ...] is an affine function of (i₀, i₁, ...). If we represent an array as a tuple
  160. </p>
  161. <blockquote class="quotation">
  162. <p>A ≡ ((storage-of-A), o, (s₀, s₁, ...))
  163. </p></blockquote>
  164. <p>then any affine transformation of the indices can be achieved simply by modifying the numbers (o, (s₀, s₁, ...)), with no need to touch the storage. This includes common operations such as: <a class="ref" href="#x_002dtranspose">transposing</a> axes, <a class="ref" href="#x_002dreverse">reversing</a> the order along an axis, most cases of <a class="ref" href="#Slicing">slicing</a>, and sometimes even reshaping or tiling the array.
  165. </p>
  166. <p>A basic example is obtaining the i₀-th item of A:
  167. </p>
  168. <blockquote class="quotation">
  169. <p>A(i₀) ≡ ((storage-of-A), o+s₀i₀, (s₁, ...))
  170. </p></blockquote>
  171. <p>Note that we can iterate over these items by simply bumping the pointer o+s₀i₀. This means that iterating over (k&gt;0)-cells doesn&rsquo;t cost any more than iterating over 0-cells (see <a class="pxref" href="#Cell-iteration">Cell iteration</a>).
  172. </p>
  173. <hr>
  174. </div>
  175. <div class="section-level-extent" id="Drag-along-and-beating">
  176. <div class="nav-panel">
  177. <p>
  178. Next: <a href="#Why-C_002b_002b" accesskey="n" rel="next">Why C++</a>, Previous: <a href="#Rank-polymorphism" accesskey="p" rel="prev">Rank polymorphism</a>, Up: <a href="#Overview" accesskey="u" rel="up">Overview</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  179. </div>
  180. <h3 class="section" id="Drag-along-and-beating-1">1.2 Drag along and beating</h3>
  181. <p>These two fundamental array optimizations are described in [<a class="ref" href="#Sources">Abr70</a>]
  182. .
  183. </p>
  184. <p><em class="dfn">Drag-along</em> is the process that delays evaluation of array operations. Expression templates can be seen as an implementation of drag-along. Drag-along isn&rsquo;t an optimization in and of itself; it simply preserves the necessary information up to the point where the expression can be executed efficiently.
  185. </p>
  186. <p><em class="dfn">Beating</em> is the implementation of certain array operations on the array <a class="ref" href="#Containers-and-views">view</a> descriptor instead of on the array contents. For example, if <code class="code">A</code> is a 1-array, one can implement <a class="ref" href="#x_002dreverse"><code class="code">reverse(A, 0)</code></a> by negating the <a class="ref" href="#x_002dsteps">step</a> and moving the offset to the other end of the array, without having to move any elements. More generally, beating applies to any function-of-indices (generator) that can take the place of an array in an array expression. For instance, an expression such as <a class="ref" href="#x_002diota"><code class="code">1+iota(3, 0)</code></a> can be beaten into <code class="code">iota(3, 1)</code>, and this can enable further optimizations.
  187. </p>
  188. <hr>
  189. </div>
  190. <div class="section-level-extent" id="Why-C_002b_002b">
  191. <div class="nav-panel">
  192. <p>
  193. Next: <a href="#Guidelines" accesskey="n" rel="next">Guidelines</a>, Previous: <a href="#Drag-along-and-beating" accesskey="p" rel="prev">Drag along and beating</a>, Up: <a href="#Overview" accesskey="u" rel="up">Overview</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  194. </div>
  195. <h3 class="section" id="Why-C_002b_002b-1">1.3 Why C++</h3>
  196. <p>Of course the main reason is that (this being a personal project) I&rsquo;m more familiar with C++ than with other languages to which the following might apply.
  197. </p>
  198. <p>C++ supports the low level control that is necessary for interoperation with external libraries and languages, but still has the abstraction power to create the features we want even though the language has no native support for most of them.
  199. </p>
  200. <a class="index-entry-id" id="index-APL"></a>
  201. <a class="index-entry-id" id="index-J"></a>
  202. <p>The classic array languages, APL [<a class="ref" href="#Sources">FI73</a>]
  203. and J [<a class="ref" href="#Sources">Ric08</a>]
  204. , have array support baked in. The same is true for other languages with array facilities such as Fortran or Octave/Matlab. Array libraries for general purpose languages usually depend heavily on C extensions. In Numpy&rsquo;s case [<a class="ref" href="#Sources">num17</a>]
  205. this is both for reasons of flexibility (e.g. to obtain predictable memory layout and machine types) and of performance.
  206. </p>
  207. <p>On the other extreme, an array library for C would be hampered by the limited means of abstraction in the language (no polymorphism, no metaprogramming, etc.) so the natural choice of C programmers is to resort to code generators, which eventually turn into new languages.
  208. </p>
  209. <p>In C++, a library is enough.
  210. </p>
  211. <hr>
  212. </div>
  213. <div class="section-level-extent" id="Guidelines">
  214. <div class="nav-panel">
  215. <p>
  216. Next: <a href="#Other-libraries" accesskey="n" rel="next">Other array libraries</a>, Previous: <a href="#Why-C_002b_002b" accesskey="p" rel="prev">Why C++</a>, Up: <a href="#Overview" accesskey="u" rel="up">Overview</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  217. </div>
  218. <h3 class="section" id="Guidelines-1">1.4 Guidelines</h3>
  219. <p><code class="code">ra::</code> attempts to be general, consistent, and transparent.
  220. </p>
  221. <p>Generality is achieved by removing arbitrary restrictions and by adopting the rank extension mechanism of J. <code class="code">ra::</code> supports array operations with an arbitrary number of arguments. Any of the arguments in an array expression can be read from or written to. Arrays or array expressions can be of any rank. Slicing operations work for subscripts of any rank, as in APL. You can use your own types as array elements.
  222. </p>
  223. <p>Consistency is achieved by having a clear set of concepts and having the realizations of those concepts adhere to the concept as closely as possible. <code class="code">ra::</code> offers a few different types of views and containers, but it should be possible to use them interchangeably whenever the properties that justify their existence are not involved. When this isn&rsquo;t possible, it&rsquo;s a bug. For example, it used to be the case that you couldn&rsquo;t create a higher rank iterator on a <code class="code">SmallView</code>, even though you could do it on a <code class="code">View</code>; this was a bug.
  224. </p>
  225. <p>Sometimes consistency requires a choice. For example, given array views A and B, <code class="code">A=B</code> copies the contents of view B into view A. To change view A instead (to treat A as a pointer) would be the default meaning of A=B for C++ types, and result in better consistency with the rest of the language, but I have decided that having consistency between views and containers (which ‘are’ their contents in a sense that views aren&rsquo;t) is more important.<a class="footnote" id="DOCF3" href="#FOOT3"><sup>3</sup></a>
  226. </p>
  227. <p>Transparency is achieved by avoiding unnecessary abstraction. An array view consists of a pointer and a list of steps and I see no point in hiding that. Manipulating the steps directly is often useful. A container consists of storage and a view and that isn&rsquo;t hidden either. Some of the types have an obscure implementation but I consider that a defect. Ideally you should be able to rewrite expressions on the fly, or plug in your own traversal methods or storage handling.
  228. </p>
  229. <p>That isn&rsquo;t to mean that you need to be in command of a lot of internal detail to be able to use the library. I hope to have provided a high level interface to most operations and a reasonably usable syntax. However, transparency is critical to achieve interoperation with external libraries and languages. When you need to, you&rsquo;ll be able to guarantee that an array is stored in compact columns, or that the real parts are interleaved with the imaginary parts.
  230. </p>
  231. <hr>
  232. </div>
  233. <div class="section-level-extent" id="Other-libraries">
  234. <div class="nav-panel">
  235. <p>
  236. Previous: <a href="#Guidelines" accesskey="p" rel="prev">Guidelines</a>, Up: <a href="#Overview" accesskey="u" rel="up">Overview</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  237. </div>
  238. <h3 class="section" id="Other-array-libraries">1.5 Other array libraries</h3>
  239. <p>Here I try to list the C++ array libraries that I know of, or libraries that I think deserve a mention for the way they deal with arrays. It is not an extensive review, since I have only used a few of these libraries myself. Please follow the links if you want to be properly informed.
  240. </p>
  241. <p>Since the C++ standard library doesn&rsquo;t offer a standard multidimensional array type, some libraries for specific tasks (linear algebra operations, finite elements, optimization) offer an accessory array library, which may be more or less general. Other libraries have generic array interfaces without needing to provide an array type. FFTW is a good example, maybe because it isn&rsquo;t C++!
  242. </p>
  243. <ul class="mini-toc">
  244. <li><a href="#Standard-C_002b_002b" accesskey="1">Standard C++</a></li>
  245. <li><a href="#Blitz_002b_002b" accesskey="2">Blitz++</a></li>
  246. <li><a href="#Other-C_002b_002b-libraries" accesskey="3">Other C++ libraries</a></li>
  247. <li><a href="#Other-languages" accesskey="4">Other languages</a></li>
  248. </ul>
  249. <div class="subsection-level-extent" id="Standard-C_002b_002b">
  250. <h4 class="subsection">1.5.1 Standard C++</h4>
  251. <p>The C++ language offers multidimensional arrays as a legacy feature from C, e.g. <code class="code">int a[3][4]</code>. These decay to pointers when you do nearly anything with them, don&rsquo;t know their own shape or rank at runtime, and are generally too limited.
  252. </p>
  253. <p>The C++ standard library also offers a number of contiguous storage containers that can be used as 1-arrays: <code class="code">&lt;array&gt;</code>, <code class="code">&lt;vector&gt;</code> and <code class="code">&lt;valarray&gt;</code>. Neither supports higher ranks out of the box, but <code class="code">&lt;valarray&gt;</code> offers array operations for 1-arrays. <code class="code">ra::</code> makes use of <code class="code">&lt;array&gt;</code> and <code class="code">&lt;vector&gt;</code> for storage and bootstrapping.
  254. </p>
  255. <p><code class="code">ra::</code> accepts built-in arrays and standard library types as array objects (see <a class="pxref" href="#Compatibility">Compatibility</a>).
  256. </p>
  257. </div>
  258. <div class="subsection-level-extent" id="Blitz_002b_002b">
  259. <h4 class="subsection">1.5.2 Blitz++</h4>
  260. <a class="index-entry-id" id="index-Blitz_002b_002b-1"></a>
  261. <p>Blitz++ [<a class="ref" href="#Sources">bli17</a>]
  262. pioneered the use of expression templates in C++. It supported higher rank arrays, as high as it was practical in C++98, but not runtime rank. It also supported small arrays with compile time shape (<code class="code">Tiny</code>), and convenience features such as Fortran-order constructors and arbitrary lower bounds for the array indices (both of which <code class="code">ra::</code> chooses not to support). It placed a strong emphasis on performance, with array traversal methods such as blocking, space filling curves, etc.
  263. </p>
  264. <p>However, the implementation had to fight the limitations of C++98, and it offered no general rank extension mechanism.
  265. </p>
  266. <p>One important difference between Blitz++ and <code class="code">ra::</code> is that Blitz++&rsquo;s arrays were reference counted. <code class="code">ra::</code> doesn&rsquo;t do any memory management on its own: the default container (data-owning) types are values, and views are distinct types. You can select your own storage for the data-owning objects, including reference-counted storage (<code class="code">ra::</code> declares a type using <code class="code">std::shared_ptr</code>), but this is not the default.
  267. </p>
  268. </div>
  269. <div class="subsection-level-extent" id="Other-C_002b_002b-libraries">
  270. <h4 class="subsection">1.5.3 Other C++ libraries</h4>
  271. <p>TODO
  272. </p>
  273. </div>
  274. <div class="subsection-level-extent" id="Other-languages">
  275. <h4 class="subsection">1.5.4 Other languages</h4>
  276. <p>TODO Maybe review other languages, at least the big ones (Fortran / APL / J / Matlab / Python-Numpy).
  277. </p>
  278. <hr>
  279. </div>
  280. </div>
  281. </div>
  282. <div class="chapter-level-extent" id="Usage">
  283. <div class="nav-panel">
  284. <p>
  285. Next: <a href="#Extras" accesskey="n" rel="next">Extras</a>, Previous: <a href="#Overview" accesskey="p" rel="prev">Overview</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  286. </div>
  287. <h2 class="chapter" id="Usage-1">2 Usage</h2>
  288. <p>This is an extended exposition of the features of <code class="code">ra::</code> and is probably best read in order. For details on specific functions or types, please see <a class="pxref" href="#Reference">Reference</a>.
  289. </p>
  290. <ul class="mini-toc">
  291. <li><a href="#Using-the-library" accesskey="1">Using <code class="code">ra::</code></a></li>
  292. <li><a href="#Containers-and-views" accesskey="2">Containers and views</a></li>
  293. <li><a href="#Array-operations" accesskey="3">Array operations</a></li>
  294. <li><a href="#Rank-extension" accesskey="4">Rank extension</a></li>
  295. <li><a href="#Cell-iteration" accesskey="5">Cell iteration</a></li>
  296. <li><a href="#Slicing" accesskey="6">Slicing</a></li>
  297. <li><a href="#Special-objects" accesskey="7">Special objects</a></li>
  298. <li><a href="#The-rank-conjunction" accesskey="8">The rank conjunction</a></li>
  299. <li><a href="#Compatibility" accesskey="9">Compatibility</a></li>
  300. <li><a href="#Extension">Extension</a></li>
  301. <li><a href="#Functions">Functions</a></li>
  302. <li><a href="#Error-handling">Error handling</a></li>
  303. </ul>
  304. <hr>
  305. <div class="section-level-extent" id="Using-the-library">
  306. <div class="nav-panel">
  307. <p>
  308. Next: <a href="#Containers-and-views" accesskey="n" rel="next">Containers and views</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  309. </div>
  310. <h3 class="section" id="Using-ra_003a_003a">2.1 Using <code class="code">ra::</code></h3>
  311. <p><code class="code">ra::</code> is a header only library with no dependencies other than the standard library, so you just need to place the &lsquo;<samp class="samp">ra/</samp>&rsquo; folder somewhere in your include path and add <code class="code">#include &quot;ra/ra.hh&quot;</code> at the top of your sources.
  312. </p>
  313. <p>A compiler with C++20 support is required. At the time of writing this means <b class="b">gcc 11</b> or with <samp class="option">-std=c++20</samp>. Some C++23 features are available with <samp class="option">-std=c++2b</samp>. Check the top README.md for more up-to-date information.
  314. </p>
  315. <p>Here is a minimal program<a class="footnote" id="DOCF4" href="#FOOT4"><sup>4</sup></a>:
  316. </p>
  317. <div class="example">
  318. <pre class="verbatim">#include &quot;ra/ra.hh&quot;
  319. #include &lt;iostream&gt;
  320. int main()
  321. {
  322. ra::Big&lt;char, 2&gt; A({2, 5}, &quot;helloworld&quot;);
  323. std::cout &lt;&lt; ra::noshape &lt;&lt; format_array(transpose&lt;1, 0&gt;(A), &quot;|&quot;) &lt;&lt; std::endl;
  324. }
  325. </pre><pre class="example-preformatted">-| h|w
  326. e|o
  327. l|r
  328. l|l
  329. d|d
  330. </pre></div>
  331. <p>The following headers are <em class="emph">not</em> included by default:
  332. </p><ul class="itemize mark-bullet">
  333. <li><code class="code">&quot;ra/dual.hh&quot;</code>: A dual number type for simple uses of automatic differentiation.
  334. </li><li><code class="code">&quot;ra/mpdebug.hh&quot;</code>: Functions to help in debugging template tangles.
  335. </li><li><code class="code">&quot;ra/test.hh&quot;</code>, <code class="code">&quot;ra/bench.hh&quot;</code>: Used by the test and benchmark suites.
  336. </li></ul>
  337. <p>The header <code class="code">&quot;ra/bootstrap.hh&quot;</code> can be used to configure <a class="ref" href="#Error-handling">Error handling</a>. You don&rsquo;t need to modify the header, but the configuration depends on including <code class="code">&quot;ra/bootstrap.hh&quot;</code> before the rest of <code class="code">ra::</code>.
  338. </p>
  339. <p>All other headers are for internal use by <code class="code">ra::</code><a class="footnote" id="DOCF5" href="#FOOT5"><sup>5</sup></a>
  340. </p>
  341. <img class="image" src="headers.png" alt="headers">
  342. <a class="index-entry-id" id="index-container"></a>
  343. <hr>
  344. </div>
  345. <div class="section-level-extent" id="Containers-and-views">
  346. <div class="nav-panel">
  347. <p>
  348. Next: <a href="#Array-operations" accesskey="n" rel="next">Array operations</a>, Previous: <a href="#Using-the-library" accesskey="p" rel="prev">Using <code class="code">ra::</code></a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  349. </div>
  350. <h3 class="section" id="Containers-and-views-1">2.2 Containers and views</h3>
  351. <p><code class="code">ra::</code> offers two kinds of data objects. The first kind, the <em class="dfn">container</em>, owns its data. Creating a container uses up memory and destroying it causes that memory to be freed.
  352. </p>
  353. <a class="index-entry-id" id="index-compile_002dtime"></a>
  354. <a class="index-entry-id" id="index-ct"></a>
  355. <a class="index-entry-id" id="index-runtime"></a>
  356. <a class="index-entry-id" id="index-rt"></a>
  357. <p>There are three kinds of containers (ct: compile-time, rt: runtime): 1) ct size, 2) ct rank/rt shape, and 3) rt rank; rt rank implies rt shape. Some rt size arrays can be resized but rt rank arrays cannot normally have their rank changed. Instead, you create a new container or view with the rank you want.
  358. </p>
  359. <p>For example:
  360. </p>
  361. <div class="example">
  362. <pre class="verbatim">{
  363. ra::Small&lt;double, 2, 3&gt; a(0.); // a ct size 2x3 array
  364. ra::Big&lt;double, 2&gt; b({2, 3}, 0.); // a rt size 2x3 array
  365. ra::Big&lt;double&gt; c({2, 3}, 0.); // a rt rank 2x3 array
  366. // a, b, c destroyed at end of scope
  367. }
  368. </pre></div>
  369. <p>Using the right kind of container can result in better performance. Ct shapes do not need to be stored in memory, which matters when you have many small arrays. Ct shape or ct rank arrays are also safer to use; sometimes <code class="code">ra::</code> will be able to detect errors in the shapes or ranks of array operands at compile time, if the appropriate types are used.
  370. </p>
  371. <p>Container constructors come in two forms. The first form takes a single argument which is copied into the new container. This argument provides shape information if the container type requires it.<a class="footnote" id="DOCF6" href="#FOOT6"><sup>6</sup></a>
  372. </p>
  373. <div class="example">
  374. <pre class="verbatim">using ra::Small, ra::Big;
  375. Small&lt;int, 2, 2&gt; a = {{1, 2}, {3, 4}}; // explicit contents
  376. Big&lt;int, 2&gt; a1 = {{1, 2}, {3, 4}}; // explicit contents
  377. Small&lt;int, 2, 2&gt; a2 = {{1, 2}}; // error: bad shape
  378. Small&lt;int, 2, 2&gt; b = 7; // 7 is copied into b
  379. Small&lt;int, 2, 2&gt; c = a; // the contents of a are copied into c
  380. Big&lt;int&gt; d = a; // d takes the shape of a and a is copied into d
  381. Big&lt;int&gt; e = 0; // e is a 0-array with one element f()==0.
  382. </pre></div>
  383. <p>The second form takes two arguments, one giving the shape, the second the contents.
  384. </p>
  385. <a class="index-entry-id" id="index-none"></a>
  386. <a class="index-entry-id" id="index-uninitialized-container"></a>
  387. <div class="example">
  388. <pre class="verbatim">ra::Big&lt;double, 2&gt; a({2, 3}, 1.); // a has shape [2 3], filled with 1.
  389. ra::Big&lt;double&gt; b({2, 3}, ra::none); // b has shape [2 3], default initialized
  390. ra::Big&lt;double&gt; c({2, 3}, a); // c has shape [2 3], a is copied into c
  391. </pre></div>
  392. <p>The last example may result in an error if the shape of <code class="code">a</code> and (2,&nbsp;<!-- /@w -->3) don&rsquo;t match. Here the shape of <code class="code">1.</code> [which is ()] matches (2,&nbsp;<!-- /@w -->3) by a mechanism of rank extension (see <a class="pxref" href="#Rank-extension">Rank extension</a>). The special value <code class="code">ra::none</code> can be used to request <a class="url" href="https://en.cppreference.com/w/cpp/language/default_initialization">default initialization</a> of the container&rsquo;s elements.
  393. </p>
  394. <p>The shape argument can have rank 0 only for rank 1 arrays.
  395. </p>
  396. <a class="index-entry-id" id="index-none-1"></a>
  397. <a class="index-entry-id" id="index-uninitialized-container-1"></a>
  398. <div class="example">
  399. <pre class="verbatim">ra::Big&lt;int&gt; c(3, 0); // ok {0, 0, 0}, same as ra::Big&lt;int&gt; c({3}, 0)
  400. ra::Big&lt;int, 1&gt; c(3, 0); // ok {0, 0, 0}, same as ra::Big&lt;int, 1&gt; c({3}, 0)
  401. ra::Big&lt;int, 2&gt; c({3}, 0); // error: bad length for shape
  402. ra::Big&lt;int, 2&gt; c(3, 0); // error: bad length for shape
  403. </pre></div>
  404. <p>When the content argument is a pointer or a 1D brace list, it&rsquo;s handled especially, not for shape<a class="footnote" id="DOCF7" href="#FOOT7"><sup>7</sup></a>, but only as the (row-major) ravel of the content. The pointer constructor is unsafe —use at your own risk!<a class="footnote" id="DOCF8" href="#FOOT8"><sup>8</sup></a>
  405. </p>
  406. <a class="index-entry-id" id="index-order_002c-column_002dmajor"></a>
  407. <div class="example">
  408. <pre class="verbatim">Small&lt;int, 2, 2&gt; aa = {1, 2, 3, 4}; // ravel of the content
  409. ra::Big&lt;double, 2&gt; a({2, 3}, {1, 2, 3, 4, 5, 6}); // same as a = {{1, 2, 3}, {4, 5, 6}}
  410. </pre></div>
  411. <div class="example">
  412. <pre class="verbatim">double bx[6] = {1, 2, 3, 4, 5, 6}
  413. ra::Big&lt;double, 2&gt; b({3, 2}, bx); // {{1, 2}, {3, 4}, {5, 6}}
  414. double cx[4] = {1, 2, 3, 4}
  415. ra::Big&lt;double, 2&gt; c({3, 2}, cx); // *** WHO NOSE ***
  416. </pre></div>
  417. <div class="example">
  418. <pre class="verbatim">using lens = mp::int_list&lt;2, 3&gt;;
  419. using steps = mp::int_list&lt;1, 2&gt;;
  420. ra::SmallArray&lt;double, lens, steps&gt; a {{1, 2, 3}, {4, 5, 6}}; // stored column-major: 1 4 2 5 3 6
  421. </pre></div>
  422. <p>These produce compile time errors:
  423. </p>
  424. <div class="example">
  425. <pre class="verbatim">Big&lt;int, 2&gt; b = {1, 2, 3, 4}; // error: shape cannot be deduced from ravel
  426. Small&lt;int, 2, 2&gt; b = {1, 2, 3, 4 5}; // error: bad size
  427. Small&lt;int, 2, 2&gt; b = {1, 2, 3}; // error: bad size
  428. </pre></div>
  429. <a class="anchor" id="x_002dscalar_002dchar_002dstar"></a><p>Sometimes the pointer constructor gets in the way (see <a class="ref" href="#x_002dscalar"><code class="code">scalar</code></a>): </p>
  430. <div class="example">
  431. <pre class="verbatim">ra::Big&lt;char const *, 1&gt; A({3}, &quot;hello&quot;); // error: try to convert char to char const *
  432. ra::Big&lt;char const *, 1&gt; A({3}, ra::scalar(&quot;hello&quot;)); // ok, &quot;hello&quot; is a single item
  433. cout &lt;&lt; ra::noshape &lt;&lt; format_array(A, &quot;|&quot;) &lt;&lt; endl;
  434. </pre><pre class="example-preformatted">-| hello|hello|hello
  435. </pre></div>
  436. <a class="index-entry-id" id="index-view"></a>
  437. <p>A <em class="dfn">view</em> is similar to a container in that it points to actual data in memory. However, the view doesn&rsquo;t own that data and destroying the view won&rsquo;t affect it. For example:
  438. </p>
  439. <div class="example">
  440. <pre class="verbatim">ra::Big&lt;double&gt; c({2, 3}, 0.); // a rt rank 2x3 array
  441. {
  442. auto c1 = c(1); // the second row of array c
  443. // c1 is destroyed here
  444. }
  445. cout &lt;&lt; c(1, 1) &lt;&lt; endl; // ok
  446. </pre></div>
  447. <p>The data accessed through a view is the data of the ‘root’ container, so modifying the former will be reflected in the latter.
  448. </p>
  449. <div class="example">
  450. <pre class="verbatim">ra::Big&lt;double&gt; c({2, 3}, 0.);
  451. auto c1 = c(1);
  452. c1(2) = 9.; // c(1, 2) = 9.
  453. </pre></div>
  454. <p>Just as for containers, there are separate types of views depending on whether the shape is known at compile time, the rank is known at compile time but the shape is not, or neither the shape nor the rank are known at compile time. <code class="code">ra::</code> has functions to create the most common kinds of views:
  455. </p>
  456. <div class="example">
  457. <pre class="verbatim">ra::Big&lt;double&gt; c {{1, 2, 3}, {4, 5, 6}};
  458. auto ct = transpose&lt;1, 0&gt;(c); // {{1, 4}, {2, 5}, {3, 6}}
  459. auto cr = reverse(c, 0); // {{4, 5, 6}, {1, 2, 3}}
  460. </pre></div>
  461. <p>However, views can point to anywhere in memory and that memory doesn&rsquo;t have to belong to an <code class="code">ra::</code> container. For example:
  462. </p>
  463. <div class="example">
  464. <pre class="verbatim">int raw[6] = {1, 2, 3, 4, 5, 6};
  465. ra::View&lt;int&gt; v1({{2, 3}, {3, 1}}, raw); // view with shape [2, 3] steps [3, 1]
  466. ra::View&lt;int&gt; v2({2, 3}, raw); // same, default C (row-major) steps
  467. </pre></div>
  468. <p>Containers can be treated as views of the same kind (rt or ct) . If you declare a function
  469. </p>
  470. <div class="example">
  471. <pre class="verbatim">void f(ra::View&lt;int, 3&gt; &amp; v);
  472. </pre></div>
  473. <p>you may pass it an object of type <code class="code">ra::Big&lt;int, 3&gt;</code>.
  474. </p>
  475. <hr>
  476. </div>
  477. <div class="section-level-extent" id="Array-operations">
  478. <div class="nav-panel">
  479. <p>
  480. Next: <a href="#Rank-extension" accesskey="n" rel="next">Rank extension</a>, Previous: <a href="#Containers-and-views" accesskey="p" rel="prev">Containers and views</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  481. </div>
  482. <h3 class="section" id="Array-operations-1">2.3 Array operations</h3>
  483. <p>To apply an operation to each element of an array, use the function <code class="code">for_each</code>. The array is traversed in an order that is decided by the library.
  484. </p>
  485. <div class="example">
  486. <pre class="verbatim">ra::Small&lt;double, 2, 3&gt; a = {{1, 2, 3}, {4, 5, 6}};
  487. double s = 0.;
  488. for_each([&amp;s](auto &amp;&amp; a) { s+=a; }, a);
  489. </pre><pre class="example-preformatted">&rArr; s = 21.
  490. </pre></div>
  491. <p>To construct an array expression but stop short of traversing it, use the function <code class="code">map</code>. The expression will be traversed when it is assigned to a view, printed out, etc.
  492. </p>
  493. <div class="example">
  494. <pre class="verbatim">using T = ra::Small&lt;double, 2, 2&gt;;
  495. T a = {{1, 2}, {3, 4}};
  496. T b = {{10, 20}, {30, 40}};
  497. T c = map([](auto &amp;&amp; a, auto &amp;&amp; b) { return a+b; }, a, b); // (1)
  498. </pre><pre class="example-preformatted">&rArr; c = {{11, 22}, {33, 44}}
  499. </pre></div>
  500. <p>Expressions may take any number of arguments and be nested arbitrarily.
  501. </p>
  502. <div class="example">
  503. <pre class="verbatim">T d = 0;
  504. for_each([](auto &amp;&amp; a, auto &amp;&amp; b, auto &amp;&amp; d) { d = a+b; },
  505. a, b, d); // same as (1)
  506. for_each([](auto &amp;&amp; ab, auto &amp;&amp; d) { d = ab; },
  507. map([](auto &amp;&amp; a, auto &amp;&amp; b) { return a+b; },
  508. a, b),
  509. d); // same as (1)
  510. </pre></div>
  511. <p>The operator of an expression may return a reference and you may assign to an expression in that case. <code class="code">ra::</code> will complain if the expression is somehow not assignable.
  512. </p>
  513. <div class="example">
  514. <pre class="verbatim">T d = 0;
  515. map([](auto &amp; d) -&gt; decltype(auto) { return d; }, d) // just pass d along
  516. = map([](auto &amp;&amp; a, auto &amp;&amp; b) { return a+b; }, a, b); // same as (1)
  517. </pre></div>
  518. <p><code class="code">ra::</code> defines many shortcuts for common array operations. You can of course just do:
  519. </p>
  520. <div class="example">
  521. <pre class="verbatim">T c = a+b; // same as (1)
  522. </pre></div>
  523. <hr>
  524. </div>
  525. <div class="section-level-extent" id="Rank-extension">
  526. <div class="nav-panel">
  527. <p>
  528. Next: <a href="#Cell-iteration" accesskey="n" rel="next">Cell iteration</a>, Previous: <a href="#Array-operations" accesskey="p" rel="prev">Array operations</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  529. </div>
  530. <h3 class="section" id="Rank-extension-1">2.4 Rank extension</h3>
  531. <p>Rank extension is the mechanism that allows <code class="code">R+S</code> to be defined even when <code class="code">R</code>, <code class="code">S</code> may have different ranks. The idea is an interpolation of the following basic cases.
  532. </p>
  533. <p>Suppose first that <code class="code">R</code> and <code class="code">S</code> have the same rank. We require that the shapes be the same. Then the shape of <code class="code">R+S</code> will be the same as the shape of either <code class="code">R</code> or <code class="code">S</code> and the elements of <code class="code">R+S</code> will be
  534. </p>
  535. <blockquote class="quotation">
  536. <p><code class="code">(R+S)(i₀ i₁ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ᵣ₋₁₎) + S(i₀ i₁ ... i₍ᵣ₋₁₎)</code>
  537. </p></blockquote>
  538. <p>where <code class="code">r</code> is the rank of <code class="code">R</code>.
  539. </p>
  540. <p>Now suppose that <code class="code">S</code> has rank 0. The shape of <code class="code">R+S</code> is the same as the shape of <code class="code">R</code> and the elements of <code class="code">R+S</code> will be
  541. </p>
  542. <blockquote class="quotation">
  543. <p><code class="code">(R+S)(i₀ i₁ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ᵣ₋₁₎) + S()</code>.
  544. </p></blockquote>
  545. <p>The two rules above are supported by all primitive array languages, e.g. Matlab [<a class="ref" href="#Sources">Mat</a>]
  546. . But suppose that <code class="code">S</code> has rank <code class="code">s</code>, where <code class="code">0&lt;s&lt;r</code>. Looking at the expressions above, it seems natural to define <code class="code">R+S</code> by
  547. </p>
  548. <blockquote class="quotation">
  549. <p><code class="code">(R+S)(i₀ i₁ ... i₍ₛ₋₁₎ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ₛ₋₁₎ ... i₍ᵣ₋₁₎) + S(i₀ i₁ ... i₍ₛ₋₁₎)</code>.
  550. </p></blockquote>
  551. <p>That is, after we run out of indices in <code class="code">S</code>, we simply repeat the elements. We have aligned the shapes so:
  552. </p>
  553. <blockquote class="quotation">
  554. <pre class="verbatim">[n₀ n₁ ... n₍ₛ₋₁₎ ... n₍ᵣ₋₁₎]
  555. [n₀ n₁ ... n₍ₛ₋₁₎]
  556. </pre></blockquote>
  557. <a class="index-entry-id" id="index-shape-agreement_002c-prefix"></a>
  558. <a class="index-entry-id" id="index-shape-agreement_002c-suffix"></a>
  559. <a class="index-entry-id" id="index-Numpy"></a>
  560. <p>This rank extension rule is used by the J language [<a class="ref" href="#Sources">J S</a>]
  561. and is known as <em class="dfn">prefix agreement</em>. The opposite rule of <em class="dfn">suffix agreement</em> is used, for example, in Numpy [<a class="ref" href="#Sources">num17</a>]
  562. <a class="footnote" id="DOCF9" href="#FOOT9"><sup>9</sup></a>.
  563. </p>
  564. <p>As you can verify, the prefix agreement rule is distributive. Therefore it can be applied to nested expressions or to expressions with any number of arguments. It is applied systematically throughout <code class="code">ra::</code>, even in assignments. For example,
  565. </p>
  566. <div class="example">
  567. <pre class="verbatim">ra::Small&lt;int, 3&gt; x {3, 5, 9};
  568. ra::Small&lt;int, 3, 2&gt; a = x; // assign x(i) to each a(i, j)
  569. </pre><pre class="example-preformatted">&rArr; a = {{3, 3}, {5, 5}, {9, 9}}
  570. </pre></div>
  571. <div class="example">
  572. <pre class="verbatim">ra::Small&lt;int, 3&gt; x(0.);
  573. ra::Small&lt;int, 3, 2&gt; a = {{1, 2}, {3, 4}, {5, 6}};
  574. x += a; // sum the rows of a
  575. </pre><pre class="example-preformatted">&rArr; x = {3, 7, 11}
  576. </pre></div>
  577. <div class="example">
  578. <pre class="verbatim">ra::Big&lt;double, 3&gt; a({5, 3, 3}, ra::_0);
  579. ra::Big&lt;double, 1&gt; b({5}, 0.);
  580. b += transpose&lt;0, 1, 1&gt;(a); // b(i) = ∑ⱼ a(i, j, j)
  581. </pre><pre class="example-preformatted">&rArr; b = {0, 3, 6, 9, 12}
  582. </pre></div>
  583. <a class="index-entry-id" id="index-Numpy-1"></a>
  584. <a class="index-entry-id" id="index-broadcasting_002c-singleton_002c-newaxis"></a>
  585. <p>An weakness of prefix agreement is that the axes you want to match aren&rsquo;t always the prefix axes. Other array systems offer a feature similar to rank extension called ‘broadcasting’ that is a bit more flexible. For example, in the way it&rsquo;s implemented in Numpy [<a class="ref" href="#Sources">num17</a>]
  586. , an array of shape [A B 1 D] will match an array of shape [A B C D]. The process of broadcasting consists in inserting so-called ‘singleton dimensions’ (axes with length one) to align the axes that one wishes to match. You can think of prefix agreement as a particular case of broadcasting where the singleton dimensions are added to the end of the shorter shapes automatically.
  587. </p>
  588. <p>A drawback of singleton broadcasting is that it muddles the distinction between a scalar and a vector of length 1. Sometimes, an axis of length 1 is no more than that, and if 2≠3 is a size mismatch, it isn&rsquo;t obvious why 1≠2 shouldn&rsquo;t be. To avoid this problem, <code class="code">ra::</code> supports broadcasting with undefined length axes (see <a class="ref" href="#x_002dinsert"><code class="code">insert</code></a>).
  589. </p>
  590. <div class="example">
  591. <pre class="verbatim">ra::Big&lt;double, 3&gt; a({5, 3}, ra::_0);
  592. ra::Big&lt;double, 1&gt; b({3}, 0.);
  593. ra::Big&lt;double, 3&gt; c({1, 3}, ra::_0);
  594. // b(?, i) += a(j, i) → b(i) = ∑ⱼ a(j, i) (sum columns)
  595. b(ra::insert&lt;1&gt;) += a;
  596. c = a; // 1 ≠ 5, still an agreement error
  597. </pre></div>
  598. <p>Still another way to align array axes is provided by the <a class="ref" href="#The-rank-conjunction">rank conjunction</a>.
  599. </p>
  600. <p>Even with axis insertion, it is still necessary that the axes one wishes to match are in the same order in all the arguments.
  601. <a class="ref" href="#x_002dtranspose">Transposing</a> the axes before extension is a possible workaround.
  602. </p>
  603. <hr>
  604. </div>
  605. <div class="section-level-extent" id="Cell-iteration">
  606. <div class="nav-panel">
  607. <p>
  608. Next: <a href="#Slicing" accesskey="n" rel="next">Slicing</a>, Previous: <a href="#Rank-extension" accesskey="p" rel="prev">Rank extension</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  609. </div>
  610. <h3 class="section" id="Cell-iteration-1">2.5 Cell iteration</h3>
  611. <p><code class="code">map</code> and <code class="code">for_each</code> apply their operators to each element of their arguments; in other words, to the 0-cells of the arguments. But it is possible to specify directly the rank of the cells that one iterates over:
  612. </p>
  613. <div class="example">
  614. <pre class="verbatim">ra::Big&lt;double, 3&gt; a({5, 4, 3}, ra::_0);
  615. for_each([](auto &amp;&amp; b) { /* b has shape (5 4 3) */ }, iter&lt;3&gt;(a));
  616. for_each([](auto &amp;&amp; b) { /* b has shape (4 3) */ }, iter&lt;2&gt;(a));
  617. for_each([](auto &amp;&amp; b) { /* b has shape (3) */ }, iter&lt;1&gt;(a));
  618. for_each([](auto &amp;&amp; b) { /* b has shape () */ }, iter&lt;0&gt;(a)); // elements
  619. for_each([](auto &amp;&amp; b) { /* b has shape () */ }, a); // same as iter&lt;0&gt;(a); default
  620. </pre></div>
  621. <p>One may specify the <em class="emph">frame</em> rank instead:
  622. </p>
  623. <div class="example">
  624. <pre class="verbatim">for_each([](auto &amp;&amp; b) { /* b has shape () */ }, iter&lt;-3&gt;(a)); // same as iter&lt;0&gt;(a)
  625. for_each([](auto &amp;&amp; b) { /* b has shape (3) */ }, iter&lt;-2&gt;(a)); // same as iter&lt;1&gt;(a)
  626. for_each([](auto &amp;&amp; b) { /* b has shape (4 3) */ }, iter&lt;-1&gt;(a)); // same as iter&lt;2&gt;(a)
  627. </pre></div>
  628. <p>In this way it is possible to match shapes in various ways. Compare
  629. </p>
  630. <div class="example">
  631. <pre class="verbatim">ra::Big&lt;double, 2&gt; a = {{1, 2, 3}, {4, 5, 6}};
  632. ra::Big&lt;double, 1&gt; b = {10, 20};
  633. ra::Big&lt;double, 2&gt; c = a * b; // multiply (each item of a) by (each item of b)
  634. </pre><pre class="example-preformatted">&rArr; a = {{10, 20, 30}, {80, 100, 120}}
  635. </pre></div>
  636. <p>with
  637. </p>
  638. <div class="example">
  639. <pre class="verbatim">ra::Big&lt;double, 2&gt; a = {{1, 2, 3}, {4, 5, 6}};
  640. ra::Big&lt;double, 1&gt; b = {10, 20, 30};
  641. ra::Big&lt;double, 2&gt; c({2, 3}, 0.);
  642. iter&lt;1&gt;(c) = iter&lt;1&gt;(a) * iter&lt;1&gt;(b); // multiply (each item of a) by (b)
  643. </pre><pre class="example-preformatted">&rArr; a = {{10, 40, 90}, {40, 100, 180}}
  644. </pre></div>
  645. <p>Note that in this case we cannot construct <code class="code">c</code> directly from <code class="code">iter&lt;1&gt;(a) * iter&lt;1&gt;(b)</code>, since the constructor for <code class="code">ra::Big</code> matches its argument using (the equivalent of) <code class="code">iter&lt;0&gt;(*this)</code>. See <a class="ref" href="#x_002diter"><code class="code">iter</code></a> for more examples.
  646. </p>
  647. <p>Cell iteration is appropriate when the operations take naturally operands of rank &gt; 0; for instance, the operation ‘determinant of a matrix’ is naturally of rank 2. When the operation is of rank 0, such as <code class="code">*</code> above, there may be faster ways to rearrange shapes for matching (see <a class="pxref" href="#The-rank-conjunction">The rank conjunction</a>).
  648. </p>
  649. <p>FIXME More examples.
  650. </p>
  651. <hr>
  652. </div>
  653. <div class="section-level-extent" id="Slicing">
  654. <div class="nav-panel">
  655. <p>
  656. Next: <a href="#Special-objects" accesskey="n" rel="next">Special objects</a>, Previous: <a href="#Cell-iteration" accesskey="p" rel="prev">Cell iteration</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  657. </div>
  658. <h3 class="section" id="Slicing-1">2.6 Slicing</h3>
  659. <p>Slicing is an array extension of the subscripting operation. However, tradition and convenience have given it a special status in most array languages, together with some peculiar semantics that <code class="code">ra::</code> supports.
  660. </p>
  661. <p>The form of the scripting operator <code class="code">A(i₀, i₁, ...)</code> makes it plain that <code class="code">A</code> is a function of <code class="code">rank(A)</code> integer arguments<a class="footnote" id="DOCF10" href="#FOOT10"><sup>10</sup></a>. An array extension is immediately available through <code class="code">map</code>. For example:
  662. </p>
  663. <div class="example">
  664. <pre class="verbatim">ra::Big&lt;double, 1&gt; a = {1., 2., 3., 4.};
  665. ra::Big&lt;int, 1&gt; i = {1, 3};
  666. map(a, i) = 77.;
  667. </pre><pre class="example-preformatted">&rArr; a = {1., 77., 3, 77.}
  668. </pre></div>
  669. <p>Just as with any use of <code class="code">map</code>, array arguments are subject to the prefix agreement rule.
  670. </p>
  671. <div class="example">
  672. <pre class="verbatim">ra::Big&lt;double, 2&gt; a({2, 2}, {1., 2., 3., 4.});
  673. ra::Big&lt;int, 1&gt; i = {1, 0};
  674. ra::Big&lt;double, 1&gt; b = map(a, i, 0);
  675. </pre><pre class="example-preformatted">&rArr; b = {3., 1.} // {a(1, 0), a(0, 0)}
  676. </pre></div>
  677. <div class="example">
  678. <pre class="verbatim">ra::Big&lt;int, 1&gt; j = {0, 1};
  679. b = map(a, i, j);
  680. </pre><pre class="example-preformatted">&rArr; b = {3., 2.} // {a(1, 0), a(0, 1)}
  681. </pre></div>
  682. <p>The latter is a form of sparse subscripting.
  683. </p>
  684. <p>Most array operations (e.g. <code class="code">+</code>) are defined through <code class="code">map</code> in this way. For example, <code class="code">A+B+C</code> is defined as <code class="code">map(+, A, B, C)</code> (or the equivalent <code class="code">map(+, map(+, A, B), C)</code>). Not so for the subscripting operation:
  685. </p>
  686. <div class="example">
  687. <pre class="verbatim">ra::Big&lt;double, 2&gt; A {{1., 2.}, {3., 4.}};
  688. ra::Big&lt;int, 1&gt; i = {1, 0};
  689. ra::Big&lt;int, 1&gt; j = {0, 1};
  690. // {{A(i₀, j₀), A(i₀, j₁)}, {A(i₁, j₀), A(i₁, j₁)}}
  691. ra::Big&lt;double, 2&gt; b = A(i, j);
  692. </pre><pre class="example-preformatted">&rArr; b = {{3., 4.}, {1., 2.}}
  693. </pre></div>
  694. <a class="anchor" id="x_002dsubscript_002douter_002dproduct"></a><p><code class="code">A(i, j, ...)</code> is defined as the <em class="emph">outer product</em> of the indices <code class="code">(i, j, ...)</code> with operator <code class="code">A</code>, because this operation sees much more use in practice than <code class="code">map(A, i, j ...)</code>.
  695. </p>
  696. <a class="index-entry-id" id="index-elision_002c-index"></a>
  697. <p>You may give fewer subscripts than the rank of the array. The full extent is assumed for the missing subscripts (cf <a class="ref" href="#x_002dall"><code class="code">all</code></a> below):
  698. </p>
  699. <div class="example">
  700. <pre class="verbatim">ra::Big&lt;int, 3&gt; a({2, 2, 2}, {1, 2, 3, 4, 5, 6, 7, 8});
  701. auto a0 = a(0); // same as a(0, ra::all, ra::all)
  702. auto a10 = a(1, 0); // same as a(1, 0, ra::all)
  703. </pre><pre class="example-preformatted">&rArr; a0 = {{1, 2}, {3, 4}}
  704. &rArr; a10 = {5, 6}
  705. </pre></div>
  706. <p>This supports the notion (see <a class="pxref" href="#Rank-polymorphism">Rank polymorphism</a>) that a 3-array is also an 2-array where the elements are 1-arrays themselves, or a 1-array where the elements are 2-arrays. This important property is directly related to the mechanism of rank extension (see <a class="pxref" href="#Rank-extension">Rank extension</a>).
  707. </p>
  708. <p>Besides, when the subscripts <code class="code">i, j, ...</code> are scalars or integer sequences of the form <code class="code">(o, o+s, ..., o+s*(n-1))</code> (<em class="dfn">linear ranges</em>), the subscripting can be performed inmediately at constant cost, and without needing to construct an expression object. This optimization is called <a class="ref" href="#Drag-along-and-beating"><em class="dfn">beating</em></a>.
  709. </p>
  710. <p><code class="code">ra::</code> isn&rsquo;t smart enough to know when an arbitrary expression might be a linear range, so the following special objects are provided:
  711. </p>
  712. <a class="anchor" id="x_002diota"></a><dl class="first-deffn">
  713. <dt class="deffn" id="index-iota"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">iota</strong> <var class="def-var-arguments">count [start:0 [step:1]]</var><a class="copiable-link" href='#index-iota'> &para;</a></span></dt>
  714. <dd><p>Create a linear range <code class="code">start, start+step, ... start+step*(count-1)</code>.
  715. </p>
  716. <p>This can used anywhere an array expression is expected.
  717. </p>
  718. <div class="example">
  719. <pre class="verbatim">ra::Big&lt;int, 1&gt; a = ra::iota(4, 3 -2);
  720. </pre><pre class="example-preformatted">&rArr; a = {3, 1, -1, -3}
  721. </pre></div>
  722. <p>Here, <code class="code">b</code> and <code class="code">c</code> are <code class="code">View</code>s (see <a class="pxref" href="#Containers-and-views">Containers and views</a>).
  723. </p><div class="example">
  724. <pre class="verbatim">ra::Big&lt;int, 1&gt; a = {1, 2, 3, 4, 5, 6};
  725. auto b = a(iota(3));
  726. auto c = a(iota(3, 3));
  727. </pre><pre class="example-preformatted">&rArr; a = {1, 2, 3}
  728. &rArr; a = {4, 5, 6}
  729. </pre></div>
  730. </dd></dl>
  731. <a class="anchor" id="x_002dall"></a><dl class="first-deffn">
  732. <dt class="deffn" id="index-all"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">all</strong><a class="copiable-link" href='#index-all'> &para;</a></span></dt>
  733. <dd><p>Create a linear range <code class="code">0, 1, ... (nᵢ-1)</code> when used as a subscript at the <var class="var">i</var>-th place of a subscripting expression. This might not be the <var class="var">i</var>-th argument; see <a class="ref" href="#x_002dinsert"><code class="code">insert</code></a>, <a class="ref" href="#x_002ddots"><code class="code">dots</code></a>.
  734. </p>
  735. <p>This object cannot stand alone as an array expression. All the examples below result in <code class="code">View</code> objects:
  736. </p>
  737. <div class="example">
  738. <pre class="verbatim">ra::Big&lt;int, 2&gt; a({3, 2}, {1, 2, 3, 4, 5, 6});
  739. auto b = a(ra::all, ra::all); // (1) a view of the whole of a
  740. auto c = a(iota(3), iota(2)); // same as (1)
  741. auto d = a(iota(3), ra::all); // same as (1)
  742. auto e = a(ra:all, iota(2)); // same as (1)
  743. auto f = a(0, ra::all); // first row of a
  744. auto g = a(ra::all, 1); // second column of a
  745. auto g = a(ra::all, ra::dots&lt;0&gt;, 1); // same
  746. </pre></div>
  747. <p><code class="code">all</code> is a special case (<code class="code">dots&lt;1&gt;</code>) of the more general object <code class="code">dots</code>.
  748. </p>
  749. </dd></dl>
  750. <a class="anchor" id="x_002ddots"></a><dl class="first-deffn">
  751. <dt class="deffn" id="index-dots_003cn_003e"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">dots&lt;n&gt;</strong><a class="copiable-link" href='#index-dots_003cn_003e'> &para;</a></span></dt>
  752. <dd><p>Equivalent to as many instances of <code class="code">ra::all</code> as indicated by <code class="code">n</code>, which must not be negative. Each instance takes the place of one argument to the subscripting operation.
  753. </p>
  754. <p>If <var class="var">n</var> is defaulted (<code class="code">dots&lt;&gt;</code>), all available places will be used; this can only be done once in a given subscript list.
  755. </p>
  756. <p>This object cannot stand alone as an array expression. All the examples below result in <code class="code">View</code> objects:
  757. </p>
  758. <div class="example">
  759. <pre class="verbatim">ra::Big&lt;int, 3&gt; a({3, 2, 4}, ...);
  760. auto h = a(); // all of a
  761. auto b = a(ra::all, ra::all, ra::all); // (1) all of a
  762. auto c = a(ra::dots&lt;3&gt;); // same as (1)
  763. auto d = a(ra::all, ra::dots&lt;2&gt;); // same as (1)
  764. auto e = a(ra::dots&lt;2&gt;, ra::all); // same as (1)
  765. auto f = a(ra::dots&lt;&gt;); // same as (1)
  766. auto j0 = a(0, ra::dots&lt;2&gt;); // first page of a
  767. auto j1 = a(0); // same
  768. auto j2 = a(0, ra::dots&lt;&gt;); // same
  769. auto k0 = a(ra::all, 0); // first row of a
  770. auto k1 = a(ra::all, 0, ra::all); // same
  771. auto k2 = a(ra::all, 0, ra::dots&lt;&gt;); // same
  772. auto k3 = a(ra::dots&lt;&gt;, 0, ra::all); // same
  773. // auto k = a(ra::dots&lt;&gt;, 0, ra::dots&lt;&gt;); // error
  774. auto l0 = a(ra::all, ra::all, 0); // first column of a
  775. auto l1 = a(ra::dots&lt;2&gt;, 0); // same
  776. auto l2 = a(ra::dots&lt;&gt;, 0); // same
  777. </pre></div>
  778. <p>This is useful when writing rank-generic code, see <code class="code">examples/maxwell.cc</code> in the distribution for an example.
  779. </p>
  780. </dd></dl>
  781. <p>The following special objects aren&rsquo;t related to linear ranges, but they are meant to be used in a subscript context.
  782. </p>
  783. <a class="index-entry-id" id="index-insert"></a>
  784. <a class="anchor" id="x_002dinsert"></a><dl class="first-deffn">
  785. <dt class="deffn" id="index-insert_003cn_003e"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">insert&lt;n&gt;</strong><a class="copiable-link" href='#index-insert_003cn_003e'> &para;</a></span></dt>
  786. <dd><p>Inserts <code class="code">n</code> new axes at the subscript position. <code class="code">n</code> must not be negative.
  787. </p>
  788. <p>The new axes have step 0 and undefined length, so they will match any length on those axes by repeating items. <code class="code">insert</code> objects cannot stand alone as an array expression. The examples below result in <code class="code">View</code> objects:
  789. </p>
  790. <div class="example">
  791. <pre class="verbatim">auto h = a(insert&lt;0&gt;); // same as (1)
  792. auto k = a(insert&lt;1&gt;); // shape [undefined, 3, 2]
  793. </pre></div>
  794. <a class="index-entry-id" id="index-broadcasting_002c-singleton_002c-Numpy"></a>
  795. <p><code class="code">insert&lt;n&gt;</code> main use is to prepare arguments for broadcasting. In other array systems (e.g. Numpy) broadcasting is done with singleton dimensions, that is, dimensions of length one match dimensions of any length. In <code class="code">ra::</code> singleton dimensions aren&rsquo;t special, so broadcasting requires the use of <code class="code">insert</code>. For example: </p>
  796. <div class="example">
  797. <pre class="verbatim">ra::Big&lt;int, 1&gt; x = {1, 10};
  798. // match shapes [2, U, U] with [U, 3, 2] to produce [2, 3, 2]
  799. cout &lt;&lt; x(ra::all, ra::insert&lt;2&gt;) * a(insert&lt;1&gt;) &lt;&lt; endl;
  800. </pre><pre class="example-preformatted">-| 2 3 2
  801. 1 2
  802. 3 4
  803. 5 6
  804. 10 20
  805. 30 40
  806. 50 60
  807. </pre></div>
  808. </dd></dl>
  809. <a class="index-entry-id" id="index-len"></a>
  810. <a class="index-entry-id" id="index-end_002c-Octave_002fMatlab"></a>
  811. <a class="anchor" id="x_002dlen"></a><dl class="first-deffn">
  812. <dt class="deffn" id="index-len-1"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">len</strong><a class="copiable-link" href='#index-len-1'> &para;</a></span></dt>
  813. <dd><p>Represents the length of the <var class="var">i</var>-th axis of a subscripted expression, when used at the <var class="var">i</var>-th place of a subscripting expression.
  814. </p>
  815. <p>This works like <code class="code">end</code> in Octave/Matlab, but note that the last element of a vector <code class="code">a</code> is <code class="code">a(ra::len-1)</code>.
  816. </p>
  817. <div class="example">
  818. <pre class="verbatim">ra::Big&lt;int, 2&gt; a({10, 10}, 100 + ra::_0 - ra::_1);
  819. auto a0 = a(ra::len-1); // last row of a; ra::len is a.len(0)
  820. auto a1 = a(ra::all, ra::len-1); // last column a; ra::len is a.len(1)
  821. auto a2 = a(ra::len-1, ra::len-1); // last element of last row; the first ra::len is a.len(0) and the second one is a.len(1)
  822. auto a3 = a(ra::all, ra::iota(2, ra::len-2)); // last two columns of a
  823. auto a4 = a(ra::iota(ra::len/2, 1, 2)); // odd rows of a
  824. a(ra::len - std::array {1, 3, 4}) = 0; // set to 0 the 1st, 3rd and 4th rows of a, counting from the end
  825. </pre></div>
  826. <div class="example">
  827. <pre class="verbatim">ra::Big&lt;int, 3&gt; b({2, 3, 4}, ...);
  828. auto b0 = b(ra::dots&lt;2&gt;, ra::len-1); // ra::len is a.len(2)
  829. auto b1 = b(ra::insert&lt;1&gt;, ra::len-1); // ra::len is a.len(0)
  830. </pre></div>
  831. <p>Using <code class="code">ra::len</code> outside of a subscript context will result in a compile time error.<a class="footnote" id="DOCF11" href="#FOOT11"><sup>11</sup></a>
  832. </p>
  833. </dd></dl>
  834. <p>We were speaking earlier of the outer product of the subscripts with operator <code class="code">A</code>. Here&rsquo;s a way to perform the actual outer product (with operator <code class="code">*</code>) of two <code class="code">Views</code>, through broadcasting. All three lines are equivalent. See <a class="ref" href="#x_002dfrom"><code class="code">from</code></a> for a more general way to compute outer products.
  835. </p><div class="example">
  836. <pre class="verbatim">cout &lt;&lt; (A(ra::dots&lt;A.rank()&gt;, ra::insert&lt;B.rank()&gt;) * B(ra::insert&lt;A.rank()&gt;, ra::dots&lt;B.rank()&gt;)) &lt;&lt; endl;
  837. cout &lt;&lt; (A(ra::dots&lt;&gt;, ra::insert&lt;B.rank()&gt;) * B(ra::insert&lt;A.rank()&gt;, ra::dots&lt;&gt;)) &lt;&lt; endl; // default dots&lt;&gt;
  838. cout &lt;&lt; (A * B(ra::insert&lt;A.rank()&gt;)) &lt;&lt; endl; // index elision + prefix matching
  839. </pre></div>
  840. <ul class="mini-toc">
  841. <li><a href="#Subscripting-and-rank_002d0-views" accesskey="1">Subscripting and rank-0 views</a></li>
  842. </ul>
  843. <div class="subsection-level-extent" id="Subscripting-and-rank_002d0-views">
  844. <h4 class="subsection">2.6.1 Subscripting and rank-0 views</h4>
  845. <a class="index-entry-id" id="index-view_002c-rank-0"></a>
  846. <a class="index-entry-id" id="index-rank_002c-runtime"></a>
  847. <a class="index-entry-id" id="index-rank_002c-compile_002dtime"></a>
  848. <p>When the result of the subscripting operation would have rank 0, the type returned is the type of the view <em class="emph">element</em> and not a rank-0 view as long as the rank of the result can be determined at compile time. When that&rsquo;s not possible (for instance, the subscripted view has rt rank) then a rank-0 view is returned instead. An automatic conversion is defined for rank-0 views, but manual conversion may be needed in some contexts.
  849. </p>
  850. <div class="example">
  851. <pre class="verbatim">using T = std::complex&lt;double&gt;;
  852. int f(T &amp;);
  853. Big&lt;T, 2&gt; a({2, 3}, 0); // ct rank
  854. Big&lt;T&gt; b({2, 3}, 0); // rt rank
  855. cout &lt;&lt; a(0, 0).real_part() &lt;&lt; endl; // ok, a(0, 0) returns complex &amp;
  856. // cout &lt;&lt; b(0, 0).real_part() &lt;&lt; endl; // error, View&lt;T&gt; has no member real_part
  857. cout &lt;&lt; ((T &amp;)(b(0, 0))).real_part() &lt;&lt; endl; // ok, manual conversion to T &amp;
  858. cout &lt;&lt; f(b(0, 0)) &lt;&lt; endl; // ok, automatic conversion from View&lt;T&gt; to T &amp;
  859. // cout &lt;&lt; f(a(0)) &lt;&lt; endl; // compile time error, conversion failed since ct rank of a(0) is not 0
  860. // cout &lt;&lt; f(b(0)) &lt;&lt; endl; // runtime error, conversion failed since rt rank of b(0) is not 0
  861. </pre></div>
  862. <hr>
  863. </div>
  864. </div>
  865. <div class="section-level-extent" id="Special-objects">
  866. <div class="nav-panel">
  867. <p>
  868. Next: <a href="#The-rank-conjunction" accesskey="n" rel="next">The rank conjunction</a>, Previous: <a href="#Slicing" accesskey="p" rel="prev">Slicing</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  869. </div>
  870. <h3 class="section" id="Special-objects-1">2.7 Special objects</h3>
  871. <dl class="first-deffn">
  872. <dt class="deffn" id="index-TensorIndex_003cn_002c"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">TensorIndex&lt;n,</strong> <var class="def-var-arguments">integer_type=ra::dim_t&gt;</var><a class="copiable-link" href='#index-TensorIndex_003cn_002c'> &para;</a></span></dt>
  873. <dd><p><code class="code">TensorIndex&lt;n&gt;</code> represents the <code class="code">n</code>-th index of an array expression. <code class="code">TensorIndex&lt;n&gt;</code> is itself an array expression of rank <code class="code">n</code>-1 and length undefined. It must be used with other terms whose dimensions are defined, so that the overall shape of the array expression can be determined.
  874. </p>
  875. <p><code class="code">ra::</code> offers the shortcut <code class="code">ra::_0</code> for <code class="code">ra::TensorIndex&lt;0&gt;{}</code>, etc.
  876. </p></dd></dl>
  877. <div class="example">
  878. <pre class="verbatim">ra::Big&lt;int, 1&gt; v = {1, 2, 3};
  879. cout &lt;&lt; (v - ra::_0) &lt;&lt; endl; // { 1-0, 2-1, 3-2 }
  880. // cout &lt;&lt; (ra::_0) &lt;&lt; endl; // error: TensorIndex cannot drive array expression
  881. // cout &lt;&lt; (v - ra::_1) &lt;&lt; endl; // error: TensorIndex cannot drive array expression
  882. ra::Big&lt;int, 2&gt; a({3, 2}, 0);
  883. cout &lt;&lt; (a + ra::_0 - ra::_1) &lt;&lt; endl; // {{0, -1, -2}, {1, 0, -1}, {2, 1, 0}}
  884. </pre></div>
  885. <hr>
  886. </div>
  887. <div class="section-level-extent" id="The-rank-conjunction">
  888. <div class="nav-panel">
  889. <p>
  890. Next: <a href="#Compatibility" accesskey="n" rel="next">Compatibility</a>, Previous: <a href="#Special-objects" accesskey="p" rel="prev">Special objects</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  891. </div>
  892. <h3 class="section" id="The-rank-conjunction-1">2.8 The rank conjunction</h3>
  893. <p>We have seen in <a class="ref" href="#Cell-iteration">Cell iteration</a> that it is possible to treat an r-array as an array of lower rank with subarrays as its elements. With the <a class="ref" href="#x_002diter"><code class="code">iter&lt;cell rank&gt;</code></a> construction, this ‘exploding’ is performed (notionally) on the argument; the operation of the array expression is applied blindly to these cells, whatever they turn out to be.
  894. </p>
  895. <div class="example">
  896. <pre class="verbatim">for_each(my_sort, iter&lt;1&gt;(A)); // (in ra::) my_sort is a regular function, cell rank must be given
  897. for_each(my_sort, iter&lt;0&gt;(A)); // (in ra::) error, bad cell rank
  898. </pre></div>
  899. <p>The array language J has instead the concept of <em class="dfn">verb rank</em>. Every function (or <em class="dfn">verb</em>) has an associated cell rank for each of its arguments. Therefore <code class="code">iter&lt;cell rank&gt;</code> is not needed.
  900. </p>
  901. <div class="example">
  902. <pre class="verbatim">for_each(sort_rows, A); // (not in ra::) will iterate over 1-cells of A, sort_rows knows
  903. </pre></div>
  904. <p><code class="code">ra::</code> doesn&rsquo;t have ‘verb ranks’ yet. In practice one can think of <code class="code">ra::</code>&rsquo;s operations as having a verb rank of 0. However, <code class="code">ra::</code> supports a limited form of J&rsquo;s <em class="dfn">rank conjunction</em> with the function <a class="ref" href="#x_002dwrank"><code class="code">wrank</code></a>.
  905. </p>
  906. <p>This is an operator that takes one verb (such operators are known as <em class="dfn">adverbs</em> in J) and produces another verb with different ranks. These ranks are used for rank extension through prefix agreement, but then the original verb is used on the cells that result. The rank conjunction can be nested, and this allows repeated rank extension before the innermost operation is applied.
  907. </p>
  908. <p>A standard example is ‘outer product’.
  909. </p>
  910. <div class="example">
  911. <pre class="verbatim">ra::Big&lt;int, 1&gt; a = {1, 2, 3};
  912. ra::Big&lt;int, 1&gt; b = {40, 50};
  913. ra::Big&lt;int, 2&gt; axb = map(ra::wrank&lt;0, 1&gt;([](auto &amp;&amp; a, auto &amp;&amp; b) { return a*b; }),
  914. a, b)
  915. </pre><pre class="example-preformatted">&rArr; axb = {{40, 80, 120}, {50, 100, 150}}
  916. </pre></div>
  917. <p>It works like this. The verb <code class="code">ra::wrank&lt;0, 1&gt;([](auto &amp;&amp; a, auto &amp;&amp; b) { return a*b; })</code> has verb ranks (0, 1), so the 0-cells of <code class="code">a</code> are paired with the 1-cells of <code class="code">b</code>. In this case <code class="code">b</code> has a single 1-cell. The frames and the cell shapes of each operand are:
  918. </p>
  919. <div class="example">
  920. <pre class="verbatim">a: 3 |
  921. b: | 2
  922. </pre></div>
  923. <p>Now the frames are rank-extended through prefix agreement.
  924. </p>
  925. <div class="example">
  926. <pre class="verbatim">a: 3 |
  927. b: 3 | 2
  928. </pre></div>
  929. <p>Now we need to perform the operation on each cell. The verb <code class="code">[](auto &amp;&amp; a, auto &amp;&amp; b) { return a*b; }</code> has verb ranks (0, 0). This results in the 0-cells of <code class="code">a</code> (which have shape ()) being rank-extended to the shape of the 1-cells of <code class="code">b</code> (which is (2)).
  930. </p>
  931. <div class="example">
  932. <pre class="verbatim">a: 3 | 2
  933. b: 3 | 2
  934. </pre></div>
  935. <p>This use of the rank conjunction is packaged in <code class="code">ra::</code> as the <a class="ref" href="#x_002dfrom"><code class="code">from</code></a> operator. It supports any number of arguments, not only two.
  936. </p>
  937. <div class="example">
  938. <pre class="verbatim">ra::Big&lt;int, 1&gt; a = {1, 2, 3};
  939. ra::Big&lt;int, 1&gt; b = {40, 50};
  940. ra::Big&lt;int, 2&gt; axb = from([](auto &amp;&amp; a, auto &amp;&amp; b) { return a*b; }), a, b)
  941. </pre><pre class="example-preformatted">&rArr; axb = {{40, 80, 120}, {50, 100, 150}}
  942. </pre></div>
  943. <p>Another example is matrix multiplication. For 2-array arguments C, A and B with shapes C: (m, n) A: (m, p) and B: (p, n), we want to perform the operation C(i, j) += A(i, k)*B(k, j). The axis alignment gives us the ranks we need to use.
  944. </p>
  945. <div class="example">
  946. <pre class="verbatim">C: m | | n
  947. A: m | p |
  948. B: | p | n
  949. </pre></div>
  950. <p>First we&rsquo;ll align the first axes of C and A using the cell ranks (1, 1, 2). The cell shapes are:
  951. </p>
  952. <div class="example">
  953. <pre class="verbatim">C: m | n
  954. A: m | p
  955. B: | p n
  956. </pre></div>
  957. <p>Then we&rsquo;ll use the ranks (1, 0, 1) on the cells:
  958. </p>
  959. <div class="example">
  960. <pre class="verbatim">C: m | | n
  961. A: m | p |
  962. B: | p | n
  963. </pre></div>
  964. <p>The final operation is a standard operation on arrays of scalars. In actual <code class="code">ra::</code> syntax:
  965. </p>
  966. <div class="example">
  967. <pre class="verbatim">ra::Big A({3, 2}, {1, 2, 3, 4, 5, 6});
  968. ra::Big B({2, 3}, {7, 8, 9, 10, 11, 12});
  969. ra::Big C({3, 3}, 0.);
  970. for_each(ra::wrank&lt;1, 1, 2&gt;(ra::wrank&lt;1, 0, 1&gt;([](auto &amp;&amp; c, auto &amp;&amp; a, auto &amp;&amp; b) { c += a*b; })), C, A, B);
  971. </pre><pre class="example-preformatted">&rArr; C = {{27, 30, 33}, {61, 68, 75}, {95, 106, 117}}
  972. </pre></div>
  973. <p>Note that <code class="code">wrank</code> cannot be used to transpose axes in general.
  974. </p>
  975. <p>I hope that in the future something like <code class="code">C(i, j) += A(i, k)*B(k, j)</code>, where <code class="code">i, j, k</code> are special objects, can be automatically translated to the requisite combination of <code class="code">wrank</code> and perhaps also <a class="ref" href="#x_002dtranspose"><code class="code">transpose</code></a>. For the time being, you have to align or transpose the axes yourself.
  976. </p>
  977. <hr>
  978. </div>
  979. <div class="section-level-extent" id="Compatibility">
  980. <div class="nav-panel">
  981. <p>
  982. Next: <a href="#Extension" accesskey="n" rel="next">Extension</a>, Previous: <a href="#The-rank-conjunction" accesskey="p" rel="prev">The rank conjunction</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  983. </div>
  984. <h3 class="section" id="Compatibility-1">2.9 Compatibility</h3>
  985. <ul class="mini-toc">
  986. <li><a href="#Using-other-C-and-C_002b_002b-types-with-ra_003a_003a" accesskey="1">Using other C and C++ types with <code class="code">ra::</code></a></li>
  987. <li><a href="#Using-ra_003a_003a-types-with-the-STL" accesskey="2">Using <code class="code">ra::</code> types with the STL</a></li>
  988. <li><a href="#Using-ra_003a_003a-types-with-other-libraries" accesskey="3">Using <code class="code">ra::</code> types with other libraries</a></li>
  989. </ul>
  990. <div class="subsection-level-extent" id="Using-other-C-and-C_002b_002b-types-with-ra_003a_003a">
  991. <h4 class="subsection">2.9.1 Using other C and C++ types with <code class="code">ra::</code></h4>
  992. <a class="index-entry-id" id="index-foreign-type"></a>
  993. <p><code class="code">ra::</code> accepts certain types from outside <code class="code">ra::</code> (<em class="dfn">foreign types</em>) as array expressions. Generally it is enough to mix the foreign type with a type from <code class="code">ra::</code> and let deduction work.
  994. </p>
  995. <div class="example">
  996. <pre class="verbatim">std::vector&lt;int&gt; x = {1, 2, 3};
  997. ra::Small&lt;int, 3&gt; y = {6, 5, 4};
  998. cout &lt;&lt; (x-y) &lt;&lt; endl;
  999. </pre><pre class="example-preformatted">-| -5 -3 -1
  1000. </pre></div>
  1001. <a class="index-entry-id" id="index-start"></a>
  1002. <p>Foreign types can be brought into <code class="code">ra::</code> explicitly with the function <a class="ref" href="#x_002dstart"><code class="code">start</code></a>.
  1003. </p>
  1004. <div class="example">
  1005. <pre class="verbatim">std::vector&lt;int&gt; x = {1, 2, 3};
  1006. // cout &lt;&lt; sum(x) &lt;&lt; endl; // error, sum not found
  1007. cout &lt;&lt; sum(ra::start(x)) &lt;&lt; endl;
  1008. cout &lt;&lt; ra::sum(x) &lt;&lt; endl;
  1009. </pre><pre class="example-preformatted">-| 6
  1010. </pre></div>
  1011. <p>The following types are accepted as foreign types:
  1012. </p>
  1013. <ul class="itemize mark-bullet">
  1014. <li>Built-in arrays <a class="index-entry-id" id="index-built_002din-array"></a>
  1015. produce an expression of positive rank and ct size.
  1016. </li><li><code class="code">std::array</code>
  1017. produces an expression of rank 1 and ct size.
  1018. </li><li>Other types conforming to <code class="code">std::ranges::random_access_range</code>, including <code class="code">std::vector</code>, <code class="code">std::string</code>, etc.
  1019. produce an expression of rank 1 and rt size.
  1020. </li></ul>
  1021. <p>Raw pointers must be brought into <code class="code">ra::</code> explicitly using the function <a class="ref" href="#x_002dptr"><code class="code">ptr</code></a>, which produces an expression of rank 1 and <em class="emph">undefined</em> size.
  1022. </p>
  1023. <p>Compare:
  1024. </p>
  1025. <div class="example">
  1026. <pre class="verbatim">int p[] = {1, 2, 3};
  1027. int * z = p;
  1028. ra::Big&lt;int, 1&gt; q {1, 2, 3};
  1029. q += p; // ok, q is ra::, p is foreign object with shape info
  1030. ra::start(p) += q; // can't redefine operator+=(int[]), foreign needs ra::start()
  1031. // z += q; // error: raw pointer needs ra::ptr()
  1032. ra::ptr(z) += p; // ok, shape is determined by foreign object p
  1033. </pre></div>
  1034. <a class="anchor" id="x_002dis_002dscalar"></a><p>Some types are accepted automatically as scalars. These include:
  1035. </p><ul class="itemize mark-bullet">
  1036. <li>Any type <code class="code">T</code> for which <code class="code">std::is_scalar_v&lt;T&gt;</code> is true, <em class="emph">except</em> pointers. These include <code class="code">char</code>, <code class="code">int</code>, <code class="code">double</code>, etc.
  1037. </li><li><code class="code">std::complex&lt;T&gt;</code>, if you import <code class="code">ra/complex.hh</code>.
  1038. </li></ul>
  1039. <p>You can add your own types as scalar types with the following declaration (see <code class="code">ra/complex.hh</code>):
  1040. </p>
  1041. <pre class="verbatim"> namespace ra { template &lt;&gt; constexpr bool is_scalar_def&lt;MYTYPE&gt; = true; }
  1042. </pre>
  1043. <p>Otherwise, you can bring a scalar object into <code class="code">ra::</code> on the spot, with the function <a class="ref" href="#x_002dscalar"><code class="code">scalar</code></a>.
  1044. </p>
  1045. </div>
  1046. <div class="subsection-level-extent" id="Using-ra_003a_003a-types-with-the-STL">
  1047. <h4 class="subsection">2.9.2 Using <code class="code">ra::</code> types with the STL</h4>
  1048. <p>General <code class="code">ra::</code> <a class="ref" href="#Containers-and-views">views</a> provide STL compatible <code class="code">ForwardIterator</code>s through the members <code class="code">begin()</code> and <code class="code">end()</code>. These iterators traverse the elements of the array (0-cells) in row major order, regardless of the storage order of the view.
  1049. </p>
  1050. <p>For <a class="ref" href="#Containers-and-views">containers</a> <code class="code">begin()</code> provides <code class="code">RandomAccessIterator</code>s, which is handy for certain functions such as <code class="code">sort</code>. There&rsquo;s no reason why all views couldn&rsquo;t provide <code class="code">RandomAccessIterator</code>, but these wouldn&rsquo;t be efficient for ranks above 1, and I haven&rsquo;t implemented them. The container <code class="code">RandomAccessIterator</code>s that are provided are in fact raw pointers.
  1051. </p>
  1052. <div class="example">
  1053. <pre class="verbatim">ra::Big&lt;int&gt; x {3, 2, 1}; // x is a Container
  1054. auto y = x(); // y is a View on x
  1055. // std::sort(y.begin(), y.end()); // error: y.begin() is not RandomAccessIterator
  1056. std::sort(x.begin(), x.end()); // ok, we know x is stored in row-major order
  1057. </pre><pre class="example-preformatted">&rArr; x = {1, 2, 3}
  1058. </pre></div>
  1059. <a class="index-entry-id" id="index-other-libraries_002c-interfacing-with"></a>
  1060. </div>
  1061. <div class="subsection-level-extent" id="Using-ra_003a_003a-types-with-other-libraries">
  1062. <h4 class="subsection">2.9.3 Using <code class="code">ra::</code> types with other libraries</h4>
  1063. <p>When you have to pass arrays back and forth between your program and an external library, perhaps even another language, it is necessary for both sides to agree on memory layout. <code class="code">ra::</code> gives you access to its own memory layout and allows you to obtain an <code class="code">ra::</code> view on any type of memory.
  1064. </p>
  1065. <ul class="mini-toc">
  1066. <li><a href="#The-good-array-citizen" accesskey="1">The good array citizen</a></li>
  1067. <li><a href="#The-bad-array-citizen" accesskey="2">The bad array citizen</a></li>
  1068. </ul>
  1069. <div class="subsubsection-level-extent" id="The-good-array-citizen">
  1070. <h4 class="subsubsection">2.9.3.1 The good array citizen</h4>
  1071. <a class="index-entry-id" id="index-BLIS"></a>
  1072. <p>The good array citizen describes its arrays with the same parameters as <code class="code">ra::</code>: a pointer, plus a length and a step per dimension. You don&rsquo;t have to worry about special cases. Say <a class="url" href="https://github.com/flame/blis">BLIS</a>:
  1073. </p>
  1074. <blockquote class="quotation">
  1075. <pre class="verbatim">#include &lt;blis.h&gt;
  1076. ra::Big&lt;double, 2&gt; A({M, K}, ...);
  1077. ra::Big&lt;double, 2&gt; B({K, N}, ...);
  1078. ra::Big&lt;double, 2&gt; C({M, N}, ...);
  1079. double alpha = ...;
  1080. double beta = ...;
  1081. // C := βC + αAB
  1082. bli_dgemm(BLIS_NO_TRANSPOSE, BLIS_NO_TRANSPOSE, M, N, K, &amp;alpha,
  1083. A.data(), A.step(0), A.step(1),
  1084. B.data(), B.step(0), B.step(1),
  1085. &amp;beta, C.data(), C.step(0), C.step(1));
  1086. </pre></blockquote>
  1087. <a class="index-entry-id" id="index-FFTW"></a>
  1088. <p>Another good array citizen, <a class="url" href="http://fftw.org">FFTW</a> handles arbitrary rank:
  1089. </p>
  1090. <blockquote class="quotation">
  1091. <pre class="verbatim">#include &lt;fftw3.h&gt;
  1092. ...
  1093. using complex = std::complex&lt;double&gt;;
  1094. static_assert(sizeof(complex)==sizeof(fftw_complex));
  1095. // forward DFT over the last r axes of a -&gt; b
  1096. void fftw(int r, ra::View&lt;complex&gt; const a, ra::View&lt;complex&gt; b)
  1097. {
  1098. int const rank = a.rank();
  1099. assert(r&gt;0 &amp;&amp; r&lt;=rank);
  1100. assert(every(shape(a)==shape(b)));
  1101. fftw_iodim dims[r];
  1102. fftw_iodim howmany_dims[rank-r];
  1103. for (int i=0; i!=rank; ++i) {
  1104. if (i&gt;=rank-r) {
  1105. dims[i-rank+r].n = a.len(i);
  1106. dims[i-rank+r].is = a.step(i);
  1107. dims[i-rank+r].os = b.step(i);
  1108. } else {
  1109. howmany_dims[i].n = a.len(i);
  1110. howmany_dims[i].is = a.step(i);
  1111. howmany_dims[i].os = b.step(i);
  1112. }
  1113. }
  1114. fftw_plan p;
  1115. p = fftw_plan_guru_dft(r, dims, rank-r, howmany_dims,
  1116. (fftw_complex *)(a.data()), (fftw_complex *)(b.data()),
  1117. FFTW_FORWARD, FFTW_ESTIMATE);
  1118. fftw_execute(p);
  1119. fftw_destroy_plan(p);
  1120. }
  1121. </pre></blockquote>
  1122. <a class="index-entry-id" id="index-Guile"></a>
  1123. <p>Translating array descriptors from a foreign language should be fairly simple. For example, this is how to convert a <a class="url" href="https://www.gnu.org/software/guile/manual/html_node/Accessing-Arrays-from-C.html#Accessing-Arrays-from-C">Guile</a> array view into an <code class="code">ra::</code> view:
  1124. </p>
  1125. <blockquote class="quotation">
  1126. <pre class="verbatim"> SCM a; // say a is #nf64(...)
  1127. ...
  1128. scm_t_array_handle h;
  1129. scm_array_get_handle(a, &amp;h);
  1130. scm_t_array_dim const * dims = scm_array_handle_dims(&amp;h);
  1131. View&lt;double&gt; v(map([](int i) { return ra::Dim { dims[i].ubnd-dims[i].lbnd+1, dims[i].inc }; },
  1132. ra::iota(scm_array_handle_rank(&amp;h))),
  1133. scm_array_handle_f64_writable_elements(&amp;h));
  1134. ...
  1135. scm_array_handle_release(&amp;h);
  1136. </pre></blockquote>
  1137. <a class="index-entry-id" id="index-Numpy-2"></a>
  1138. <a class="index-entry-id" id="index-Python"></a>
  1139. <p>Numpy&rsquo;s C API has the type <a class="url" href="https://docs.scipy.org/doc/numpy/reference/c-api.array.html"><code class="code">PyArrayObject</code></a> which can be used in the same way as Guile&rsquo;s <code class="code">scm_t_array_handle</code> in the example above.
  1140. </p>
  1141. <p>It is usually simpler to let the foreign language handle the memory, even though there should be ways to transfer ownership (e.g. Guile has <a class="url" href="https://www.gnu.org/software/guile/manual/html_node/SRFI_002d4-API.html#index-scm_005ftake_005ff64vector"><code class="code">scm_take_xxx</code></a>).
  1142. </p>
  1143. </div>
  1144. <div class="subsubsection-level-extent" id="The-bad-array-citizen">
  1145. <h4 class="subsubsection">2.9.3.2 The bad array citizen</h4>
  1146. <p>Unfortunately there are many libraries that don&rsquo;t accept arbitrary array parameters, or that do strange things with particular values of lengths and/or steps.
  1147. </p>
  1148. <p>The most common case is that a library doesn&rsquo;t handle steps at all, and it only accepts unit step for rank 1 arrays, or packed row-major or column-major storage for higher rank arrays. In that case, you might be forced to copy your array before passing it along.
  1149. </p>
  1150. <p>Other libraries do accept steps, but not arbitrary ones. For example <a class="url" href="https://www.netlib.org/blas">https://www.netlib.org/blas</a>&rsquo; <code class="code">cblas_dgemm</code> has this prototype:
  1151. </p>
  1152. <blockquote class="quotation">
  1153. <pre class="verbatim">cblas_dgemm(order, transA, transB, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
  1154. </pre></blockquote>
  1155. <p><code class="code">A</code>, <code class="code">B</code>, <code class="code">C</code> are (pointers to) 2-arrays, but the routine accepts only one step argument for each (<code class="code">lda</code>, etc.). CBLAS also doesn&rsquo;t understand <code class="code">lda</code> as a arbitrary step, but rather as the dimension of a larger array that you&rsquo;re slicing <code class="code">A</code> from, and some implementations will mishandle negative or zero <code class="code">lda</code>.
  1156. </p>
  1157. <p>Sometimes you can work around this by fiddling with <code class="code">transA</code> and <code class="code">transB</code>, but in general you need to check your array parameters and you may need to make copies.
  1158. </p>
  1159. <a class="index-entry-id" id="index-OpenGL"></a>
  1160. <p>OpenGL is another library that requires <a class="url" href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml">contortions:</a>
  1161. </p>
  1162. <blockquote class="quotation">
  1163. <pre class="verbatim">void glVertexAttribPointer(GLuint index,
  1164. GLint size,
  1165. GLenum type,
  1166. GLboolean normalized,
  1167. GLsizei step,
  1168. const GLvoid * pointer);
  1169. </pre>
  1170. <p>[...]
  1171. </p>
  1172. <p><em class="emph">step</em>
  1173. </p>
  1174. <blockquote class="quotation">
  1175. <p>Specifies the byte offset between consecutive generic vertex attributes. If step is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.
  1176. </p></blockquote>
  1177. </blockquote>
  1178. <p>It isn&rsquo;t clear whether negative steps are legal, either. So just as with CBLAS, passing arbitrary array views may require copies.
  1179. </p>
  1180. <hr>
  1181. </div>
  1182. </div>
  1183. </div>
  1184. <div class="section-level-extent" id="Extension">
  1185. <div class="nav-panel">
  1186. <p>
  1187. Next: <a href="#Functions" accesskey="n" rel="next">Functions</a>, Previous: <a href="#Compatibility" accesskey="p" rel="prev">Compatibility</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1188. </div>
  1189. <h3 class="section" id="Extension-1">2.10 Extension</h3>
  1190. <ul class="mini-toc">
  1191. <li><a href="#New-scalar-types" accesskey="1">New scalar types</a></li>
  1192. <li><a href="#New-array-operations" accesskey="2">New array operations</a></li>
  1193. </ul>
  1194. <div class="subsection-level-extent" id="New-scalar-types">
  1195. <h4 class="subsection">2.10.1 New scalar types</h4>
  1196. <p><code class="code">ra::</code> will let you construct arrays of arbitrary types out of the box. This is the same functionality you get with e.g. <code class="code">std::vector</code>.
  1197. </p>
  1198. <div class="example">
  1199. <pre class="verbatim">struct W { int x; }
  1200. ra::Big&lt;W, 2&gt; w = {{ {4}, {2} }, { {1}, {3} }};
  1201. cout &lt;&lt; W(1, 1).x &lt;&lt; endl;
  1202. cout &lt;&lt; amin(map([](auto &amp;&amp; x) { return w.x; }, w)) &lt;&lt; endl;
  1203. </pre><pre class="example-preformatted">-| 3
  1204. 1
  1205. </pre></div>
  1206. <p>However, if you want to mix arbitrary types in array operations, you&rsquo;ll need to tell <code class="code">ra::</code> that that is actually what you want. This is to avoid conflicts with other libraries.
  1207. </p>
  1208. <div class="example">
  1209. <pre class="verbatim">namespace ra { template &lt;&gt; constexpr bool is_scalar_def&lt;W&gt; = true; }
  1210. ...
  1211. W ww {11};
  1212. for_each([](auto &amp;&amp; x, auto &amp;&amp; y) { cout &lt;&lt; (x.x + y.y) &lt;&lt; &quot; &quot;; }, w, ww); // ok
  1213. </pre><pre class="example-preformatted">-| 15 13 12 14
  1214. </pre></div>
  1215. <p>but
  1216. </p>
  1217. <div class="example">
  1218. <pre class="verbatim">struct U { int x; }
  1219. U uu {11};
  1220. for_each([](auto &amp;&amp; x, auto &amp;&amp; y) { cout &lt;&lt; (x.x + y.y) &lt;&lt; &quot; &quot;; }, w, uu); // error: can't find ra::start(U)
  1221. </pre></div>
  1222. <a class="anchor" id="x_002dnew_002darray_002doperations"></a></div>
  1223. <div class="subsection-level-extent" id="New-array-operations">
  1224. <h4 class="subsection">2.10.2 New array operations</h4>
  1225. <p><code class="code">ra::</code> provides array extensions for standard operations such as <code class="code">+</code>, <code class="code">*</code>, <code class="code">cos</code> <a class="ref" href="#x_002dscalar_002dops">and so on</a>. You can add array extensions for your own operations in the obvious way, with <a class="ref" href="#x_002dmap"><code class="code">map</code></a> (but note the namespace qualifiers):
  1226. </p>
  1227. <div class="example">
  1228. <pre class="verbatim">return_type my_fun(...) { };
  1229. ...
  1230. namespace ra {
  1231. template &lt;class ... A&gt; inline auto
  1232. my_fun(A &amp;&amp; ... a)
  1233. {
  1234. return map(::my_fun, std::forward&lt;A&gt;(a) ...);
  1235. }
  1236. } // namespace ra
  1237. </pre></div>
  1238. <a class="index-entry-id" id="index-Blitz_002b_002b-2"></a>
  1239. <p>If you compare this with what Blitz++ had to do, modern C++ sure has made our lives easier.
  1240. </p>
  1241. <a class="index-entry-id" id="index-overload-set"></a>
  1242. <p>If <code class="code">my_fun</code> is an overload set, you can use<a class="footnote" id="DOCF12" href="#FOOT12"><sup>12</sup></a>
  1243. </p>
  1244. <div class="example">
  1245. <pre class="verbatim">namespace ra {
  1246. template &lt;class ... A&gt; inline auto
  1247. my_fun(A &amp;&amp; ... a)
  1248. {
  1249. return map([](auto &amp;&amp; ... a) { return ::my_fun(a ...); }, std::forward&lt;A&gt;(a) ...);
  1250. }
  1251. } // namespace ra
  1252. </pre></div>
  1253. <hr>
  1254. </div>
  1255. </div>
  1256. <div class="section-level-extent" id="Functions">
  1257. <div class="nav-panel">
  1258. <p>
  1259. Next: <a href="#Error-handling" accesskey="n" rel="next">Error handling</a>, Previous: <a href="#Extension" accesskey="p" rel="prev">Extension</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1260. </div>
  1261. <h3 class="section" id="Functions-1">2.11 Functions</h3>
  1262. <p>You don&rsquo;t need to use <a class="ref" href="#Array-operations"><code class="code">map</code></a> every time you want to do something with arrays in <code class="code">ra::</code>. A number of array functions are already defined.
  1263. </p>
  1264. <a class="anchor" id="x_002dscalar_002dops"></a><ul class="mini-toc">
  1265. <li><a href="#Standard-scalar-operations" accesskey="1">Standard scalar operations</a></li>
  1266. <li><a href="#Conditional-operations" accesskey="2">Conditional operations</a></li>
  1267. <li><a href="#Special-operations" accesskey="3">Special operations</a></li>
  1268. <li><a href="#Elementwise-reductions" accesskey="4">Elementwise reductions</a></li>
  1269. <li><a href="#Special-reductions" accesskey="5">Special reductions</a></li>
  1270. <li><a href="#Shortcut-reductions" accesskey="6">Shortcut reductions</a></li>
  1271. </ul>
  1272. <div class="subsection-level-extent" id="Standard-scalar-operations">
  1273. <h4 class="subsection">2.11.1 Standard scalar operations</h4>
  1274. <p><code class="code">ra::</code> defines array extensions for <code class="code">+</code>, <code class="code">-</code> (both unary and binary), <code class="code">*</code>, <code class="code">/</code>, <code class="code">!</code>, <code class="code">&amp;&amp;</code>, <code class="code">||</code><a class="footnote" id="DOCF13" href="#FOOT13"><sup>13</sup></a>, <code class="code">&gt;</code>, <code class="code">&lt;</code>, <code class="code">&gt;=</code>, <code class="code">&lt;=</code>, <code class="code">&lt;=&gt;</code>, <code class="code">==</code>, <code class="code">!=</code>, <code class="code">pow</code>, <code class="code">sqr</code>, <code class="code">abs</code>, <code class="code">cos</code>, <code class="code">sin</code>, <code class="code">exp</code>, <code class="code">expm1</code>, <code class="code">sqrt</code>, <code class="code">log</code>, <code class="code">log1p</code>, <code class="code">log10</code>, <code class="code">isfinite</code>, <code class="code">isnan</code>, <code class="code">isinf</code>, <code class="code">max</code>, <code class="code">min</code>, <code class="code">asin</code>, <code class="code">acos</code>, <code class="code">atan</code>, <code class="code">atan2</code>, <code class="code">cosh</code>, <code class="code">sinh</code>, <code class="code">tanh</code>, and <code class="code">lerp</code>.
  1275. Extending other scalar operations is straightforward; see <a class="ref" href="#x_002dnew_002darray_002doperations">New array operations</a>. <code class="code">ra::</code> also defines (and extends) the non-standard functions <code class="code">odd</code>, <a class="ref" href="#x_002dsqr"><code class="code">sqr</code></a>, <a class="ref" href="#x_002dsqrm"><code class="code">sqrm</code></a>, <a class="ref" href="#x_002dconj"><code class="code">conj</code></a>, <a class="ref" href="#x_002drel_002derror"><code class="code">rel_error</code></a>, and <a class="ref" href="#x_002dxI"><code class="code">xI</code></a>.
  1276. </p>
  1277. <p>For example:
  1278. </p><div class="example">
  1279. <pre class="verbatim">cout &lt;&lt; exp(ra::Small&lt;double, 3&gt; {4, 5, 6}) &lt;&lt; endl;
  1280. </pre><pre class="example-preformatted"> -| 54.5982 148.413 403.429
  1281. </pre></div>
  1282. </div>
  1283. <div class="subsection-level-extent" id="Conditional-operations">
  1284. <h4 class="subsection">2.11.2 Conditional operations</h4>
  1285. <p><a class="ref" href="#x_002dmap"><code class="code">map</code></a> evaluates all of its arguments before passing them along to its operator. This isn&rsquo;t always what you want. The simplest example is <code class="code">where(condition, iftrue, iffalse)</code>, which returns an expression that will evaluate <code class="code">iftrue</code> when <code class="code">condition</code> is true and <code class="code">iffalse</code> otherwise.
  1286. </p>
  1287. <div class="example">
  1288. <pre class="verbatim">ra::Big&lt;double&gt; x ...
  1289. ra::Big&lt;double&gt; y = where(x&gt;0, expensive_expr_1(x), expensive_expr_2(x));
  1290. </pre></div>
  1291. <p>Here <code class="code">expensive_expr_1</code> and <code class="code">expensive_expr_2</code> are array expressions. So the computation of the other arm would be wasted if one were to do instead
  1292. </p>
  1293. <div class="example">
  1294. <pre class="verbatim">ra::Big&lt;double&gt; y = map([](auto &amp;&amp; w, auto &amp;&amp; t, auto &amp;&amp; f) -&gt; decltype(auto) { return w ? t : f; }
  1295. x&gt;0, expensive_expr_1(x), expensive_function_2(x));
  1296. </pre></div>
  1297. <p>If the expressions have side effects, then <code class="code">map</code> won&rsquo;t even give the right result.
  1298. </p>
  1299. <div class="example">
  1300. <pre class="verbatim">ra::Big&lt;int, 1&gt; o = {};
  1301. ra::Big&lt;int, 1&gt; e = {};
  1302. ra::Big&lt;int, 1&gt; n = {1, 2, 7, 9, 12};
  1303. ply(where(odd(n), map([&amp;o](auto &amp;&amp; x) { o.push_back(x); }, n), map([&amp;e](auto &amp;&amp; x) { e.push_back(x); }, n)));
  1304. cout &lt;&lt; &quot;o: &quot; &lt;&lt; ra::noshape &lt;&lt; o &lt;&lt; &quot;, e: &quot; &lt;&lt; ra::noshape &lt;&lt; e &lt;&lt; endl;
  1305. </pre><pre class="example-preformatted">-| o: 1 7 9, e: 2 12
  1306. </pre></div>
  1307. <p>FIXME Artificial example.
  1308. FIXME Do we want to expose ply(); this is the only example in the manual that uses it.
  1309. </p>
  1310. <p>When the choice is between more than two expressions, there&rsquo;s <a class="ref" href="#x_002dpick"><code class="code">pick</code></a>, which operates similarly, but accepts an integer instead of a boolean selector.
  1311. </p>
  1312. </div>
  1313. <div class="subsection-level-extent" id="Special-operations">
  1314. <h4 class="subsection">2.11.3 Special operations</h4>
  1315. <p>Some operations are essentially scalar operations, but require special syntax and would need a lambda wrapper to be used with <code class="code">map</code>. <code class="code">ra::</code> comes with a few of these already defined.
  1316. </p>
  1317. <p>FIXME
  1318. </p>
  1319. </div>
  1320. <div class="subsection-level-extent" id="Elementwise-reductions">
  1321. <h4 class="subsection">2.11.4 Elementwise reductions</h4>
  1322. <p><code class="code">ra::</code> defines the whole-array one-argument reductions <code class="code">any</code>, <code class="code">every</code>, <code class="code">amax</code>, <code class="code">amin</code>, <code class="code">sum</code>, <code class="code">prod</code> and the two-argument reductions <code class="code">dot</code> and <code class="code">cdot</code>. Note that <code class="code">max</code> and <code class="code">min</code> are two-argument scalar operations with array extensions, while <code class="code">amax</code> and <code class="code">amin</code> are reductions. <code class="code">any</code> and <code class="code">every</code> are short-circuiting.
  1323. </p>
  1324. <p>You can define reductions the same way <code class="code">ra::</code> does:
  1325. </p>
  1326. <div class="example">
  1327. <pre class="verbatim">template &lt;class A&gt;
  1328. inline auto op_reduce(A &amp;&amp; a)
  1329. {
  1330. T c = op_default;
  1331. for_each([&amp;c](auto &amp;&amp; a) { c = op(c, a); }, a);
  1332. return c;
  1333. }
  1334. </pre></div>
  1335. <p>Often enough you need to reduce over particular axes. This is possible by combining assignment operators with the <a class="ref" href="#Rank-extension">rank extension</a> mechanism, or using the <a class="ref" href="#The-rank-conjunction">rank conjunction</a>, or iterating over <a class="ref" href="#Cell-iteration">cells of higher rank</a>. For example:
  1336. </p>
  1337. <div class="example">
  1338. <pre class="verbatim"> ra::Big&lt;double, 2&gt; a({m, n}, ...);
  1339. ra::Big&lt;double, 1&gt; sum_rows({n}, 0.);
  1340. iter&lt;1&gt;(sum_rows) += iter&lt;1&gt;(a);
  1341. // for_each(ra::wrank&lt;1, 1&gt;([](auto &amp; c, auto &amp;&amp; a) { c += a; }), sum_rows, a) // alternative
  1342. // sum_rows += transpose&lt;1, 0&gt;(a); // another
  1343. ra::Big&lt;double, 1&gt; sum_cols({m}, 0.);
  1344. sum_cols += a;
  1345. </pre></div>
  1346. <p>FIXME example with assignment op
  1347. </p>
  1348. <p>A few common operations of this type are already packaged in <code class="code">ra::</code>.
  1349. </p>
  1350. </div>
  1351. <div class="subsection-level-extent" id="Special-reductions">
  1352. <h4 class="subsection">2.11.5 Special reductions</h4>
  1353. <p><code class="code">ra::</code> defines the following special reductions.
  1354. </p>
  1355. <p>FIXME
  1356. </p>
  1357. </div>
  1358. <div class="subsection-level-extent" id="Shortcut-reductions">
  1359. <h4 class="subsection">2.11.6 Shortcut reductions</h4>
  1360. <p>Some reductions do not need to traverse the whole array if a certain condition is encountered early. The most obvious ones are the reductions of <code class="code">&amp;&amp;</code> and <code class="code">||</code>, which <code class="code">ra::</code> defines as <code class="code">every</code> and <code class="code">any</code>.
  1361. </p>
  1362. <p>FIXME
  1363. </p>
  1364. <p>These operations are defined on top of another function <code class="code">early</code>.
  1365. </p>
  1366. <p>FIXME early
  1367. </p>
  1368. <p>The following is often useful.
  1369. </p>
  1370. <p>FIXME lexicographical compare etc.
  1371. </p>
  1372. <a class="index-entry-id" id="index-error"></a>
  1373. <a class="index-entry-id" id="index-assert"></a>
  1374. <hr>
  1375. </div>
  1376. </div>
  1377. <div class="section-level-extent" id="Error-handling">
  1378. <div class="nav-panel">
  1379. <p>
  1380. Previous: <a href="#Functions" accesskey="p" rel="prev">Functions</a>, Up: <a href="#Usage" accesskey="u" rel="up">Usage</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1381. </div>
  1382. <h3 class="section" id="Error-handling-1">2.12 Error handling</h3>
  1383. <p>Error handling in <code class="code">ra::</code> is controlled by two macros:
  1384. </p>
  1385. <ul class="itemize mark-bullet">
  1386. <li><code class="code">RA_DO_CHECK</code>
  1387. is a binary flag that controls runtime checks. The default is 1 which means to check for errors. 0 means not to check. The checks themselves are done with <code class="code">RA_ASSERT</code>.
  1388. </li><li><code class="code">RA_ASSERT(cond, ...)</code>
  1389. is a function-like macro. <code class="code">cond</code> is an expression that evaluates to true (in the <code class="code">ra::</code> namespace) if the check passes. The other arguments are informative and do not need to be used. The default defintion of <code class="code">RA_ASSERT(cond, ...)</code> prints those arguments to <code class="code">std::cerr</code> and aborts.
  1390. </li></ul>
  1391. <p><code class="code">ra::</code> contains uses of <code class="code">assert</code> for checking invariants or for sanity checks that are separate from uses of <code class="code">RA_ASSERT</code>. Those can be disabled in the usual way with <samp class="option">-DNDEBUG</samp>.
  1392. </p>
  1393. <p>You can redefine <code class="code">RA_ASSERT</code> to something that is more appropriate for your program. <code class="code">examples/throw.cc</code> in the distribution shows how to throw a user-defined exception instead.
  1394. </p>
  1395. <hr>
  1396. </div>
  1397. </div>
  1398. <div class="chapter-level-extent" id="Extras">
  1399. <div class="nav-panel">
  1400. <p>
  1401. Next: <a href="#Hazards" accesskey="n" rel="next">Hazards</a>, Previous: <a href="#Usage" accesskey="p" rel="prev">Usage</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1402. </div>
  1403. <h2 class="chapter" id="Extras-1">3 Extras</h2>
  1404. <hr>
  1405. </div>
  1406. <div class="chapter-level-extent" id="Hazards">
  1407. <div class="nav-panel">
  1408. <p>
  1409. Next: <a href="#Internals" accesskey="n" rel="next">Internals</a>, Previous: <a href="#Extras" accesskey="p" rel="prev">Extras</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1410. </div>
  1411. <h2 class="chapter" id="Hazards-1">4 Hazards</h2>
  1412. <p>Some of these issues arise because <code class="code">ra::</code> applies its principles systematically, which can have surprising results. Still others are the result of unfortunate compromises. And a few are just bugs.
  1413. </p>
  1414. <ul class="mini-toc">
  1415. <li><a href="#Reuse-of-expression-objects" accesskey="1">Reuse of expression objects</a></li>
  1416. <li><a href="#Assignment-to-views" accesskey="2">Assignment to views</a></li>
  1417. <li><a href="#View-of-const-vs-const-view" accesskey="3">View of const vs const view</a></li>
  1418. <li><a href="#Rank-extension-in-assignments" accesskey="4">Rank extension in assignments</a></li>
  1419. <li><a href="#Performance-pitfalls-of-rank-extension" accesskey="5">Performance pitfalls of rank extension</a></li>
  1420. <li><a href="#Chained-assignment" accesskey="6">Chained assignment</a></li>
  1421. <li><a href="#Unregistered-scalar-types" accesskey="7">Unregistered scalar types</a></li>
  1422. </ul>
  1423. <div class="section-level-extent" id="Reuse-of-expression-objects">
  1424. <h3 class="section">4.1 Reuse of expression objects</h3>
  1425. <p>Expression objects are meant to be used once. This applies to anything produced with <code class="code">ra::map</code>, <code class="code">ra::iter</code>, <code class="code">ra::start</code>, <code class="code">ra::vector</code>, or <code class="code">ra::ptr</code>. Reuse errors are <em class="emph">not</em> checked. For example:
  1426. </p>
  1427. <div class="example">
  1428. <pre class="verbatim">ra::Big&lt;int, 2&gt; B({3, 3}, ra::_1 + ra::_0*3); // {{0 1 2} {3 4 5} {6 7 8}}
  1429. std::array&lt;int, 2&gt; l = { 1, 2 };
  1430. cout &lt;&lt; B(ra::vector(l), ra::vector(l)) &lt;&lt; endl; // ok =&gt; {{4 5} {7 8}}
  1431. auto ll = ra::vector(l);
  1432. cout &lt;&lt; B(ll, ll) &lt;&lt; endl; // ?? take cover
  1433. </pre></div>
  1434. </div>
  1435. <div class="section-level-extent" id="Assignment-to-views">
  1436. <h3 class="section">4.2 Assignment to views</h3>
  1437. <p>FIXME
  1438. With rt-shape containers (e.g. <code class="code">Big</code>), <code class="code">operator=</code> replaces the left hand side instead of writing over its contents. This behavior is inconsistent with <code class="code">View::operator=</code> and is there only so that istream <code class="code">&gt;&gt;</code> container may work; do not rely on it.
  1439. </p>
  1440. </div>
  1441. <div class="section-level-extent" id="View-of-const-vs-const-view">
  1442. <h3 class="section">4.3 View of const vs const view</h3>
  1443. <p>FIXME
  1444. Passing view arguments by reference
  1445. </p>
  1446. </div>
  1447. <div class="section-level-extent" id="Rank-extension-in-assignments">
  1448. <h3 class="section">4.4 Rank extension in assignments</h3>
  1449. <p>Assignment of an expression onto another expression of lower rank may not do what you expect. This example matches <code class="code">a</code> and 3 [both of shape ()] with a vector of shape (3). This is equivalent to <code class="code">{a=3+4; a=3+5; a=3+6;}</code>. You may get a different result depending on traversal order.
  1450. </p>
  1451. <div class="example">
  1452. <pre class="verbatim">int a = 0;
  1453. ra::scalar(a) = 3 + ra::Small&lt;int, 3&gt; {4, 5, 6}; // ?
  1454. </pre><pre class="example-preformatted"> &rArr; a = 9
  1455. </pre></div>
  1456. <p>Compare with
  1457. </p>
  1458. <div class="example">
  1459. <pre class="verbatim">int a = 0;
  1460. ra::scalar(a) += 3 + ra::Small&lt;int, 3&gt; {4, 5, 6}; // 0 + 3 + 4 + 5 + 6
  1461. </pre><pre class="example-preformatted"> &rArr; a = 18
  1462. </pre></div>
  1463. </div>
  1464. <div class="section-level-extent" id="Performance-pitfalls-of-rank-extension">
  1465. <h3 class="section">4.5 Performance pitfalls of rank extension</h3>
  1466. <p>In the following example where <code class="code">b</code> has its shape extended from (3) to (3, 4), <code class="code">f</code> is called 12 times, even though only 3 calls are needed if <code class="code">f</code> doesn&rsquo;t have side effects. In such cases it might be preferrable to write the outer loop explicitly, or to do some precomputation.
  1467. </p>
  1468. <div class="example">
  1469. <pre class="verbatim">ra::Big&lt;int, 2&gt; a = {{1, 2, 3, 4}, {5, 6, 7, 8} {9, 10, 11, 12}};
  1470. ra::Big&lt;int, 1&gt; b = {1, 2, 3};
  1471. ra::Big&lt;int, 2&gt; c = map(f, b) + a;
  1472. </pre></div>
  1473. </div>
  1474. <div class="section-level-extent" id="Chained-assignment">
  1475. <h3 class="section">4.6 Chained assignment</h3>
  1476. <p>FIXME
  1477. When <code class="code">a=b=c</code> works, it operates as <code class="code">b=c; a=b;</code> and not as an array expression.
  1478. </p>
  1479. </div>
  1480. <div class="section-level-extent" id="Unregistered-scalar-types">
  1481. <h3 class="section">4.7 Unregistered scalar types</h3>
  1482. <p>FIXME
  1483. <code class="code">View&lt;T, N&gt; x; x = T()</code> fails if <code class="code">T</code> isn&rsquo;t registered as <code class="code">is_scalar</code>.
  1484. </p>
  1485. <ol class="enumerate">
  1486. <li> Item 0
  1487. </li><li> Item 1
  1488. </li><li> Item 2
  1489. </li></ol>
  1490. <hr>
  1491. </div>
  1492. </div>
  1493. <div class="chapter-level-extent" id="Internals">
  1494. <div class="nav-panel">
  1495. <p>
  1496. Next: <a href="#The-future" accesskey="n" rel="next">The future</a>, Previous: <a href="#Hazards" accesskey="p" rel="prev">Hazards</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1497. </div>
  1498. <h2 class="chapter" id="Internals-1">5 Internals</h2>
  1499. <p><code class="code">ra::</code> has two main components: a set of container classes, and the expression template mechanism. The container classes provide leaves for the expression template trees, and the container classes also make some use of the expression template mechanism internally (e.g. in the selection operator, or for initialization).
  1500. </p>
  1501. <ul class="mini-toc">
  1502. <li><a href="#Type-hierarchy" accesskey="1">Type hierarchy</a></li>
  1503. <li><a href="#Term-agreement" accesskey="2">Term agreement</a></li>
  1504. <li><a href="#Loop-types" accesskey="3">Loop types</a></li>
  1505. <li><a href="#Introspection" accesskey="4">Introspection</a></li>
  1506. <li><a href="#Compiling-and-running" accesskey="5">Compiling and running</a></li>
  1507. </ul>
  1508. <hr>
  1509. <div class="section-level-extent" id="Type-hierarchy">
  1510. <div class="nav-panel">
  1511. <p>
  1512. Next: <a href="#Term-agreement" accesskey="n" rel="next">Term agreement</a>, Up: <a href="#Internals" accesskey="u" rel="up">Internals</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1513. </div>
  1514. <h3 class="section" id="Type-hierarchy-1">5.1 Type hierarchy</h3>
  1515. <p>Some of the categories below are actually C++20 ‘concepts’, some are still informal.
  1516. </p>
  1517. <ul class="itemize mark-bullet">
  1518. <li><b class="b">Container</b> &mdash; <code class="code">Big</code>, <code class="code">Shared</code>, <code class="code">Unique</code>, <code class="code">Small</code>
  1519. <p>These are array types that own their data in one way or another. Creating or destroying these objects may allocate or deallocate memory, respectively.
  1520. </p>
  1521. </li><li><b class="b">View</b> &mdash; <code class="code">View</code>, <code class="code">SmallView</code>
  1522. <p>These are array views into data in memory, which may be writable. Any of the <b class="b">Container</b> types can be treated as a <b class="b">View</b>, but one may also create <b class="b">View</b>s that aren&rsquo;t associated with any <b class="b">Container</b>, for example into memory allocated by a different library. Creating and destroying <b class="b">View</b>s doesn&rsquo;t allocate or deallocate memory for array elements.
  1523. </p>
  1524. </li><li><b class="b">Iterator</b> &mdash; <code class="code">CellBig</code>, <code class="code">CellSmall</code>, <code class="code">Iota</code>, <code class="code">Ptr</code>, <code class="code">Scalar</code>, <code class="code">Expr</code>, <code class="code">Pick</code>
  1525. <p>This is a traversable object. <b class="b">Iterator</b>s are accepted by all the array functions such as <code class="code">map</code>, <code class="code">for_each</code>, etc. <code class="code">map</code> produces an <b class="b">Iterator</b> itself, so most array expressions are <b class="b">Iterator</b>s. <b class="b">Iterator</b>s are created from <b class="b">View</b>s and from certain foreign array-like types primarily through the function <code class="code">start</code>. This is done automatically when those types are used in array expressions.
  1526. </p>
  1527. <p><b class="b">Iterator</b>s provide a <code class="code">flat()</code> method to obtain a linearized view of a section of the array. Together with the methods <code class="code">len()</code>, <code class="code">step()</code>, <code class="code">keep_step()</code> and <code class="code">adv()</code>, a loop involving <b class="b">Iterator</b>s can have its inner loop unfolded and traversed using <b class="b">Flat</b> objects. This is faster than a multidimensional loop, especially if the inner dimensions of the loop are small.
  1528. </p>
  1529. <p><b class="b">Iterator</b>s also provide an <code class="code">at(i ...)</code> method for random access to any element of the expression.
  1530. </p>
  1531. </li><li><b class="b">Flat</b> <code class="code">Iota::Flat</code>, <code class="code">Scalar</code>, <code class="code">Expr::Flat</code>, <code class="code">Pick::Flat</code>, <code class="code">CellFlat</code>
  1532. <p>These are types that support ‘forward iterator’ traversal. They have methods <code class="code">operator+=</code> (to advance) and <code class="code">operator*</code> (to derreference). <b class="b">Flat</b> objects are obtained from <b class="b">Iterator</b> objects through a method <code class="code">flat()</code>. <code class="code">Scalar</code> is its own <b class="b">Flat</b>.
  1533. </p>
  1534. </li></ul>
  1535. <hr>
  1536. </div>
  1537. <div class="section-level-extent" id="Term-agreement">
  1538. <div class="nav-panel">
  1539. <p>
  1540. Next: <a href="#Loop-types" accesskey="n" rel="next">Loop types</a>, Previous: <a href="#Type-hierarchy" accesskey="p" rel="prev">Type hierarchy</a>, Up: <a href="#Internals" accesskey="u" rel="up">Internals</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1541. </div>
  1542. <h3 class="section" id="Term-agreement-1">5.2 Term agreement</h3>
  1543. <p>The execution of an expression template begins with the determination of its shape — the length of each of its dimensions. This is done recursively by traversing the terms of the expression. For a given dimension <code class="code">k</code>≥0, terms that have rank less or equal than <code class="code">k</code> are ignored, following the prefix matching principle. Likewise terms where dimension <code class="code">k</code> has undefined length (such as <code class="code">iota()</code> or view axes created with <code class="code">insert</code>) are ignored. All the other terms must match.
  1544. </p>
  1545. <p>Then we select a traversal method depending on the types of the arguments. <code class="code">ra::</code> has two traversal methods, both based on pointer-like iterators. <code class="code">ply_ravel</code> is used for rt-size expressions and <code class="code">plyf</code> for ct-size expressions.
  1546. </p>
  1547. <p>Finally we select an order of traversal. <code class="code">ra::</code> supports ‘array’ orders, meaning that the dimensions are sorted in a certain way from outermost to innermost and a full dimension is traversed before one advances on the dimension outside. However, currently (v21) there is no heuristic to choose a dimension order, so traversal always happens in row-major order (which shouldn&rsquo;t be relied upon). <code class="code">ply_ravel</code> will unroll as many innermost dimensions as it can, and in some cases traversal will be executed as a flat loop.
  1548. </p>
  1549. <hr>
  1550. </div>
  1551. <div class="section-level-extent" id="Loop-types">
  1552. <div class="nav-panel">
  1553. <p>
  1554. Next: <a href="#Introspection" accesskey="n" rel="next">Introspection</a>, Previous: <a href="#Term-agreement" accesskey="p" rel="prev">Term agreement</a>, Up: <a href="#Internals" accesskey="u" rel="up">Internals</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1555. </div>
  1556. <h3 class="section" id="Loop-types-1">5.3 Loop types</h3>
  1557. <p>TODO
  1558. </p>
  1559. <hr>
  1560. </div>
  1561. <div class="section-level-extent" id="Introspection">
  1562. <div class="nav-panel">
  1563. <p>
  1564. Next: <a href="#Compiling-and-running" accesskey="n" rel="next">Compiling and running</a>, Previous: <a href="#Loop-types" accesskey="p" rel="prev">Loop types</a>, Up: <a href="#Internals" accesskey="u" rel="up">Internals</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1565. </div>
  1566. <h3 class="section" id="Introspection-1">5.4 Introspection</h3>
  1567. <hr>
  1568. </div>
  1569. <div class="section-level-extent" id="Compiling-and-running">
  1570. <div class="nav-panel">
  1571. <p>
  1572. Previous: <a href="#Introspection" accesskey="p" rel="prev">Introspection</a>, Up: <a href="#Internals" accesskey="u" rel="up">Internals</a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1573. </div>
  1574. <h3 class="section" id="Compiling-and-running-1">5.5 Compiling and running</h3>
  1575. <p>The following <code class="code">#define</code>s affect the behavior of <code class="code">ra::</code>.
  1576. </p>
  1577. <ul class="itemize mark-bullet">
  1578. <li><code class="code">RA_DO_CHECK</code> (default 1): Check shape agreement (e.g. <code class="code">Big&lt;int, 1&gt; {2, 3} + Big&lt;int, 1&gt; {1, 2, 3}</code>) and random array accesses (e.g. <code class="code">Small&lt;int, 2&gt; a = 0; int i = 10; a[i] = 0;</code>). See <a class="ref" href="#Error-handling">Error handling</a>.
  1579. </li><li><code class="code">RA_DO_OPT</code> (default 1): Sets the default for all <code class="code">RA_DO_OPT_XXX</code> flags.
  1580. </li><li><code class="code">RA_DO_OPT_IOTA</code> (default 1): Perform immediately (beat) certain operations on <code class="code">ra::Iota</code> objects. For example, <code class="code">ra::iota(3, 0) + 1</code> becomes <code class="code">ra::iota(3, 1)</code> instead of a two-operand expression template.
  1581. </li><li><code class="code">RA_DO_OPT_SMALLVECTOR</code> (default 0): Perform immediately certain operations on <code class="code">ra::Small</code> objects, using small vector intrinsics. Currently this only works on <b class="b">gcc</b> and doesn&rsquo;t necessarily result in improved performance.
  1582. </li></ul>
  1583. <p><code class="code">ra::</code> comes with three kinds of tests: examples, proper tests, and benchmarks. <code class="code">ra::</code> uses its own test and benchmark suites. Run <code class="code">CXXFLAGS=-O3 scons</code> from the top directory of the distribution to build and run them all. Alternatively, you can use <code class="code">CXXFLAGS=-O3 cmake . &amp;&amp; make &amp;&amp; make test</code>. Like most expression template libraries, <code class="code">ra::</code> is highly dependent on optimization by the compiler and will be orders of magnitude slower with <samp class="option">-O0</samp> compared to <samp class="option">-O2</samp>.
  1584. </p>
  1585. <p>The following environment variables affect the test suite under SCons:
  1586. </p>
  1587. <ul class="itemize mark-bullet">
  1588. <li><code class="code">RA_USE_BLAS</code> (default 0): Use BLAS for <code class="code">gemm</code> and <code class="code">gemv</code> benchmarks.
  1589. </li></ul>
  1590. <hr>
  1591. </div>
  1592. </div>
  1593. <div class="chapter-level-extent" id="The-future">
  1594. <div class="nav-panel">
  1595. <p>
  1596. Next: <a href="#Reference" accesskey="n" rel="next">Reference</a>, Previous: <a href="#Internals" accesskey="p" rel="prev">Internals</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1597. </div>
  1598. <h2 class="chapter" id="The-future-1">6 The future</h2>
  1599. <ul class="mini-toc">
  1600. <li><a href="#Error-messages" accesskey="1">Error messages</a></li>
  1601. <li><a href="#Reductions" accesskey="2">Reductions</a></li>
  1602. <li><a href="#Etc" accesskey="3">Etc</a></li>
  1603. </ul>
  1604. <div class="section-level-extent" id="Error-messages">
  1605. <h3 class="section">6.1 Error messages</h3>
  1606. <p>FIXME
  1607. </p>
  1608. </div>
  1609. <div class="section-level-extent" id="Reductions">
  1610. <h3 class="section">6.2 Reductions</h3>
  1611. <p>FIXME
  1612. </p>
  1613. </div>
  1614. <div class="section-level-extent" id="Etc">
  1615. <h3 class="section">6.3 Etc</h3>
  1616. <p>FIXME
  1617. </p>
  1618. <hr>
  1619. </div>
  1620. </div>
  1621. <div class="chapter-level-extent" id="Reference">
  1622. <div class="nav-panel">
  1623. <p>
  1624. Next: <a href="#Sources" accesskey="n" rel="next">Sources</a>, Previous: <a href="#The-future" accesskey="p" rel="prev">The future</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  1625. </div>
  1626. <h2 class="chapter" id="Reference-1">7 Reference</h2>
  1627. <a class="index-entry-id" id="index-agree"></a>
  1628. <a class="anchor" id="x_002dagree"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1629. <dt class="deffn defun-alias-deffn" id="index-agree-1"><span class="category-def">Function: </span><span><strong class="def-name">agree</strong> <var class="def-var-arguments">arg ...</var><a class="copiable-link" href='#index-agree-1'> &para;</a></span></dt>
  1630. <dd><p>Return true if the shapes of arguments <var class="var">arg...</var> match (see <a class="ref" href="#Rank-extension">Rank extension</a>), else return false.
  1631. </p>
  1632. <p>This is useful when <a class="ref" href="#Error-handling">error checking</a> is enabled and one wants to avoid the failure response.
  1633. </p><div class="example">
  1634. <pre class="verbatim"> ra::Small&lt;int, 2, 3&gt; A;
  1635. ra::Small&lt;int, 2&gt; B;
  1636. ra::Small&lt;int, 3&gt; C;
  1637. agree(A, B); // -&gt; true
  1638. static_assert(agree(A, B)); // ok for ct shapes
  1639. cout &lt;&lt; (A+B) &lt;&lt; endl; // ok
  1640. agree(A, C); // -&gt; false
  1641. cout &lt;&lt; (A+C) &lt;&lt; endl; // error. Maybe abort, maybe throw - cf Error Handling
  1642. </pre></div>
  1643. </dd></dl>
  1644. <a class="index-entry-id" id="index-agree_005fop"></a>
  1645. <a class="anchor" id="x_002dagree_005fop"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1646. <dt class="deffn defun-alias-deffn" id="index-agree_005fop-1"><span class="category-def">Function: </span><span><strong class="def-name">agree_op</strong> <var class="def-var-arguments">op arg ...</var><a class="copiable-link" href='#index-agree_005fop-1'> &para;</a></span></dt>
  1647. <dd><p>Return true if the shapes of arguments <var class="var">arg...</var> match (see <a class="ref" href="#Rank-extension">Rank extension</a>) relative to operator <var class="var">op</var>, else return false.
  1648. </p>
  1649. <p>This differs from <a class="ref" href="#x_002dagree"><code class="code">agree</code></a> when <var class="var">op</var> has non-zero argument ranks. For example:
  1650. </p><div class="example">
  1651. <pre class="verbatim"> ra::Big&lt;real, 1&gt; a({3}, 0.);
  1652. ra::Big&lt;real, 2&gt; b({2, 3}, 0.n);
  1653. agree(a, b); // -&gt; false
  1654. cout &lt;&lt; (a+b) &lt;&lt; endl; // error
  1655. agree_op(ra::wrank&lt;1, 1&gt;(std::plus()), a, b); // -&gt; true
  1656. cout &lt;&lt; map(ra::wrank&lt;1, 1&gt;(std::plus()), a, b) &lt;&lt; endl; // ok
  1657. </pre></div>
  1658. </dd></dl>
  1659. <a class="index-entry-id" id="index-at"></a>
  1660. <a class="anchor" id="x_002dat"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1661. <dt class="deffn defun-alias-deffn" id="index-at-1"><span class="category-def">Function: </span><span><strong class="def-name">at</strong> <var class="def-var-arguments">expr indices</var><a class="copiable-link" href='#index-at-1'> &para;</a></span></dt>
  1662. <dd><p>Look up <var class="var">expr</var> at each element of <var class="var">indices</var>, which shall be a multi-index into <var class="var">expr</var>.
  1663. </p>
  1664. <p>This can be used for sparse subscripting. For example:
  1665. </p><div class="example">
  1666. <pre class="verbatim"> ra::Big&lt;int, 2&gt; A = {{100, 101}, {110, 111}, {120, 121}};
  1667. ra::Big&lt;ra::Small&lt;int, 2&gt;, 2&gt; i = {{{0, 1}, {2, 0}}, {{1, 0}, {2, 1}}};
  1668. ra::Big&lt;int, 2&gt; B = at(A, i);
  1669. </pre><pre class="example-preformatted"> &rArr; B = {{101, 120}, {110, 121}}
  1670. </pre></div>
  1671. </dd></dl>
  1672. <a class="index-entry-id" id="index-cast"></a>
  1673. <a class="anchor" id="x_002dcast"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1674. <dt class="deffn defun-alias-deffn" id="index-cast-1"><span class="category-def">Function: </span><span><strong class="def-name">cast</strong> <var class="def-var-arguments">&lt;type&gt; expr</var><a class="copiable-link" href='#index-cast-1'> &para;</a></span></dt>
  1675. <dd><p>Create an array expression that casts <var class="var">expr</var> into <var class="var">type</var>.
  1676. </p></dd></dl>
  1677. <a class="index-entry-id" id="index-collapse"></a>
  1678. <a class="anchor" id="x_002dcollapse"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1679. <dt class="deffn defun-alias-deffn" id="index-collapse-1"><span class="category-def">Function: </span><span><strong class="def-name">collapse</strong><a class="copiable-link" href='#index-collapse-1'> &para;</a></span></dt>
  1680. <dd><p>TODO
  1681. See also <a class="ref" href="#x_002dexplode"><code class="code">explode</code></a>.
  1682. </p></dd></dl>
  1683. <a class="index-entry-id" id="index-concrete"></a>
  1684. <a class="anchor" id="x_002dconcrete"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1685. <dt class="deffn defun-alias-deffn" id="index-concrete-1"><span class="category-def">Function: </span><span><strong class="def-name">concrete</strong> <var class="def-var-arguments">a</var><a class="copiable-link" href='#index-concrete-1'> &para;</a></span></dt>
  1686. <dd><p>Convert the argument to a container of the same shape as <var class="var">a</var>.
  1687. </p>
  1688. <p>If the argument has rt or ct shape, it is the same for the result. The main use of this function is to obtain modifiable copy of an array expression without having to prepare a container beforehand, or compute the appropiate type.
  1689. </p>
  1690. </dd></dl>
  1691. <a class="index-entry-id" id="index-diag"></a>
  1692. <a class="anchor" id="x_002ddiag"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1693. <dt class="deffn defun-alias-deffn" id="index-diag-1"><span class="category-def">Function: </span><span><strong class="def-name">diag</strong> <var class="def-var-arguments">view</var><a class="copiable-link" href='#index-diag-1'> &para;</a></span></dt>
  1694. <dd><p>Equivalent to <code class="code">transpose&lt;0, 0&gt;(view)</code>.
  1695. </p></dd></dl>
  1696. <a class="index-entry-id" id="index-explode"></a>
  1697. <a class="anchor" id="x_002dexplode"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1698. <dt class="deffn defun-alias-deffn" id="index-explode-1"><span class="category-def">Function: </span><span><strong class="def-name">explode</strong><a class="copiable-link" href='#index-explode-1'> &para;</a></span></dt>
  1699. <dd><p>TODO
  1700. </p>
  1701. <p>See also <a class="ref" href="#x_002dcollapse"><code class="code">collapse</code></a>.
  1702. </p></dd></dl>
  1703. <a class="index-entry-id" id="index-for_005feach"></a>
  1704. <a class="anchor" id="x_002dfor_005feach"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1705. <dt class="deffn defun-alias-deffn" id="index-for_005feach-1"><span class="category-def">Function: </span><span><strong class="def-name">for_each</strong> <var class="def-var-arguments">op expr ...</var><a class="copiable-link" href='#index-for_005feach-1'> &para;</a></span></dt>
  1706. <dd><p>Create an array expression that applies <var class="var">op</var> to <var class="var">expr</var> ..., and traverse it.
  1707. </p>
  1708. <p><var class="var">op</var> is run for effect; whatever it returns is discarded. For example:
  1709. </p><div class="example">
  1710. <pre class="verbatim">double s = 0.;
  1711. for_each([&amp;s](auto &amp;&amp; a) { s+=a; }, ra::Small&lt;double, 1&gt; {1., 2., 3})
  1712. </pre><pre class="example-preformatted">&rArr; s = 6.
  1713. </pre></div>
  1714. <p>See also <a class="ref" href="#x_002dmap"><code class="code">map</code></a>.
  1715. </p>
  1716. </dd></dl>
  1717. <a class="index-entry-id" id="index-format_005farray"></a>
  1718. <a class="anchor" id="x_002dformat_005farray"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1719. <dt class="deffn defun-alias-deffn" id="index-format_005farray-1"><span class="category-def">Function: </span><span><strong class="def-name">format_array</strong> <var class="def-var-arguments">expr [last_axis_separator [second_last_axis_separator ...]]</var><a class="copiable-link" href='#index-format_005farray-1'> &para;</a></span></dt>
  1720. <dd><p>Formats an array for character output.
  1721. </p>
  1722. <p>For example:
  1723. </p>
  1724. <div class="example">
  1725. <pre class="verbatim">ra::Small&lt;int, 2, 2&gt; A = {{1, 2}, {3, 4}};
  1726. cout &lt;&lt; &quot;case a:\n&quot; &lt;&lt; A &lt;&lt; endl;
  1727. cout &lt;&lt; &quot;case b:\n&quot; &lt;&lt; format_array(A) &lt;&lt; endl;
  1728. cout &lt;&lt; &quot;case c:\n&quot; &lt;&lt; format_array(A, &quot;|&quot;, &quot;-&quot;) &lt;&lt; endl;
  1729. </pre><pre class="example-preformatted">-| case a:
  1730. 1 2
  1731. 3 4
  1732. case b:
  1733. 1 2
  1734. 3 4
  1735. case c:
  1736. 1|2-3|4
  1737. </pre></div>
  1738. <p>The shape that might be printed before the expression itself (depending on its type) is not subject to these separators.
  1739. </p>
  1740. <p>See also <a class="ref" href="#x_002dnoshape"><code class="code">noshape</code></a>, <a class="ref" href="#x_002dwithshape"><code class="code">withshape</code></a>.
  1741. </p>
  1742. </dd></dl>
  1743. <a class="index-entry-id" id="index-from"></a>
  1744. <a class="anchor" id="x_002dfrom"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1745. <dt class="deffn defun-alias-deffn" id="index-from-1"><span class="category-def">Function: </span><span><strong class="def-name">from</strong> <var class="def-var-arguments">op expr ...</var><a class="copiable-link" href='#index-from-1'> &para;</a></span></dt>
  1746. <dd><p>Create outer product expression. This is defined as
  1747. </p>
  1748. <div class="display">
  1749. <pre class="display-preformatted">E = from(op, e₀, e₁ ...) ⇒ E(i₀₀, i₀₁ ..., i₁₀, i₁₁, ..., ...) = op[expr₀(i₀₀, i₀₁, ...), expr₁(i₁₀, i₁₁, ...), ...].
  1750. </pre></div>
  1751. <p>For example:
  1752. </p><div class="example">
  1753. <pre class="verbatim"> ra::Big&lt;double, 1&gt; a {1, 2, 3};
  1754. ra::Big&lt;double, 1&gt; b {10, 20, 30};
  1755. ra::Big&lt;double, 2&gt; axb = from([](auto &amp;&amp; a, auto &amp;&amp; b) { return a*b; }, a, b)
  1756. </pre><pre class="example-preformatted"> &rArr; axb = {{10, 20, 30}, {20, 40, 60}, {30, 60, 90}}
  1757. </pre></div>
  1758. <div class="example">
  1759. <pre class="verbatim"> ra::Big&lt;int, 1&gt; i {2, 1};
  1760. ra::Big&lt;int, 1&gt; j {0, 1};
  1761. ra::Big&lt;double, 2&gt; A = {{1, 2}, {3, 4}, {5, 6}};
  1762. ra::Big&lt;double, 2&gt; Aij = from(A, i, j)
  1763. </pre><pre class="example-preformatted"> &rArr; Aij = {{6, 5}, {4, 3}}
  1764. </pre></div>
  1765. <p>The last example is more or less how <code class="code">A(i, j)</code> is implemented for arbitrary subscripts (see <a class="pxref" href="#The-rank-conjunction">The rank conjunction</a>).
  1766. </p>
  1767. </dd></dl>
  1768. <a class="index-entry-id" id="index-imag_005fpart"></a>
  1769. <a class="anchor" id="x_002dimag_005fpart"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1770. <dt class="deffn defun-alias-deffn" id="index-imag_005fpart-1"><span class="category-def">Function: </span><span><strong class="def-name">imag_part</strong><a class="copiable-link" href='#index-imag_005fpart-1'> &para;</a></span></dt>
  1771. <dd><p>Take imaginary part of a complex number. This can be used as reference.
  1772. </p>
  1773. <p>For example: </p>
  1774. <div class="example">
  1775. <pre class="verbatim">ra::Small&lt;std::complex&lt;double&gt;, 2, 2&gt; A = {{1., 2.}, {3., 4.}};
  1776. imag_part(A) = -2*real_part(A);
  1777. cout &lt;&lt; A &lt;&lt; endl;
  1778. </pre><pre class="example-preformatted">-|
  1779. (1, -2) (2, -4)
  1780. (3, -6) (4, -8)
  1781. </pre></div>
  1782. <p>See also <a class="ref" href="#x_002dreal_005fpart"><code class="code">real_part</code></a>.
  1783. </p></dd></dl>
  1784. <a class="index-entry-id" id="index-map"></a>
  1785. <a class="anchor" id="x_002dmap"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1786. <dt class="deffn defun-alias-deffn" id="index-map-1"><span class="category-def">Function: </span><span><strong class="def-name">map</strong> <var class="def-var-arguments">op expr ...</var><a class="copiable-link" href='#index-map-1'> &para;</a></span></dt>
  1787. <dd><p>Create an array expression that applies callable <var class="var">op</var> to <var class="var">expr</var> ...
  1788. </p>
  1789. <p>For example:
  1790. </p><div class="example">
  1791. <pre class="verbatim">ra::Big&lt;double, 1&gt; x = map(cos, std::array {0.});
  1792. </pre><pre class="example-preformatted">&rArr; x = { 1. }
  1793. </pre></div>
  1794. <p><var class="var">op</var> can return a reference. For example:
  1795. </p>
  1796. <div class="example">
  1797. <pre class="verbatim">ra::Big&lt;int, 2&gt; x = {{3, 3}, 0.};
  1798. ra::Big&lt;int, 2&gt; i = {0, 1, 1, 2};
  1799. ra::Big&lt;int, 2&gt; j = {1, 0, 2, 1};
  1800. map(x, i, j) = 1;
  1801. </pre><pre class="example-preformatted">&rArr; x = {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}
  1802. </pre></div>
  1803. <p>Note that <code class="code">map(x, i, j)</code> is <a class="ref" href="#x_002dsubscript_002douter_002dproduct">not the same</a> as <code class="code">x(i, j)</code>.
  1804. </p>
  1805. <p><var class="var">op</var> can be any callable. For example:
  1806. </p><div class="example">
  1807. <pre class="verbatim">struct A { int a, b; };
  1808. std::vector&lt;A&gt; v = {{1, 2}, {3, 4}};
  1809. ra::map(&amp;A::a, v) = -ra::map(&amp;A::b, v); // pointer to member
  1810. </pre><pre class="example-preformatted">&rArr; v = {{-2, 2}, {-4, 4}}
  1811. </pre></div>
  1812. <p>See also <a class="ref" href="#x_002dfor_005feach"><code class="code">for_each</code></a>.
  1813. </p>
  1814. </dd></dl>
  1815. <a class="index-entry-id" id="index-pack"></a>
  1816. <a class="anchor" id="x_002dpack"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1817. <dt class="deffn defun-alias-deffn" id="index-pack-1"><span class="category-def">Function: </span><span><strong class="def-name">pack</strong> <var class="def-var-arguments">&lt;type&gt; expr ...</var><a class="copiable-link" href='#index-pack-1'> &para;</a></span></dt>
  1818. <dd><p>Create an array expression that brace-constructs <var class="var">type</var> from <var class="var">expr</var> ...
  1819. </p></dd></dl>
  1820. <a class="index-entry-id" id="index-pick"></a>
  1821. <a class="anchor" id="x_002dpick"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1822. <dt class="deffn defun-alias-deffn" id="index-pick-1"><span class="category-def">Function: </span><span><strong class="def-name">pick</strong> <var class="def-var-arguments">select_expr expr ...</var><a class="copiable-link" href='#index-pick-1'> &para;</a></span></dt>
  1823. <dd><p>Create an array expression that selects the first of <var class="var">expr</var> ... if <var class="var">select_expr</var> is 0, the second if <var class="var">select_expr</var> is 1, and so on. The expressions that are not selected are not looked up.
  1824. </p>
  1825. <p>This function cannot be defined using <a class="ref" href="#x_002dmap"><code class="code">map</code></a>, because <code class="code">map</code> looks up each one of its argument expressions before calling <var class="var">op</var>.
  1826. </p>
  1827. <p>For example:
  1828. </p><div class="example">
  1829. <pre class="verbatim"> ra::Small&lt;int, 3&gt; s {2, 1, 0};
  1830. ra::Small&lt;double, 3&gt; z = pick(s, s*s, s+s, sqrt(s));
  1831. </pre><pre class="example-preformatted"> &rArr; z = {1.41421, 2, 0}
  1832. </pre></div>
  1833. </dd></dl>
  1834. <a class="index-entry-id" id="index-ply"></a>
  1835. <a class="anchor" id="x_002dply"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1836. <dt class="deffn defun-alias-deffn" id="index-ply-1"><span class="category-def">Function: </span><span><strong class="def-name">ply</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-ply-1'> &para;</a></span></dt>
  1837. <dd><p>Traverse <var class="var">expr</var>. <code class="code">ply</code> returns <code class="code">void</code> so <var class="var">expr</var> should be run for effect.
  1838. </p>
  1839. <p>It is rarely necessary to use <code class="code">ply</code>. Expressions are traversed automatically when they are assigned to views, for example, or printed out. <a class="ref" href="#x_002dfor_005feach"><code class="code">for_each</code></a><code class="code">(...)</code>, which is equivalent to <code class="code">ply(map(...))</code>, should cover most other uses.
  1840. </p>
  1841. <div class="example">
  1842. <pre class="verbatim">double s = 0.;
  1843. ply(map([&amp;s](auto &amp;&amp; a) { s+=a; }, ra::Small&lt;double, 1&gt; {1., 2., 3})) // same as for_each
  1844. </pre><pre class="example-preformatted">&rArr; s = 6.
  1845. </pre></div>
  1846. </dd></dl>
  1847. <a class="index-entry-id" id="index-real_005fpart"></a>
  1848. <a class="anchor" id="x_002dreal_005fpart"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1849. <dt class="deffn defun-alias-deffn" id="index-real_005fpart-1"><span class="category-def">Function: </span><span><strong class="def-name">real_part</strong><a class="copiable-link" href='#index-real_005fpart-1'> &para;</a></span></dt>
  1850. <dd><p>Take real part of a complex number. This can be used as reference.
  1851. </p>
  1852. <p>See also <a class="ref" href="#x_002dimag_005fpart"><code class="code">imag_part</code></a>.
  1853. </p></dd></dl>
  1854. <a class="index-entry-id" id="index-reverse"></a>
  1855. <a class="anchor" id="x_002dreverse"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1856. <dt class="deffn defun-alias-deffn" id="index-reverse-1"><span class="category-def">Function: </span><span><strong class="def-name">reverse</strong> <var class="def-var-arguments">view axis</var><a class="copiable-link" href='#index-reverse-1'> &para;</a></span></dt>
  1857. <dd><p>Create a new view by reversing axis <var class="var">k</var> of <var class="var">view</var>.
  1858. </p>
  1859. <p>This is equivalent to <code class="code">view(ra::dots&lt;k&gt;, ra::iota(ra::len, ra::len-1, -1))</code>.
  1860. </p>
  1861. <p>This operation does not work on arbitrary array expressions yet. TODO FILL
  1862. </p>
  1863. </dd></dl>
  1864. <a class="index-entry-id" id="index-shape-1"></a>
  1865. <a class="anchor" id="x_002dshape"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1866. <dt class="deffn defun-alias-deffn" id="index-shape-2"><span class="category-def">Function: </span><span><strong class="def-name">shape</strong> <var class="def-var-arguments">a</var><a class="copiable-link" href='#index-shape-2'> &para;</a></span></dt>
  1867. <dd><p>Get the shape of an <code class="code">ra::</code> object.
  1868. </p>
  1869. <p>The shape of a rt rank array is a rank-1 object with rt size, and the shape of a ct rank array is a rank-1 object with ct size.
  1870. </p>
  1871. <p>This function may return an expression object or an array object. If you need to operate on the result, it might be necessary to use <code class="code">concrete</code>.
  1872. </p>
  1873. </dd></dl>
  1874. <a class="index-entry-id" id="index-size"></a>
  1875. <a class="anchor" id="x_002dsize"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1876. <dt class="deffn defun-alias-deffn" id="index-size-1"><span class="category-def">Function: </span><span><strong class="def-name">size</strong> <var class="def-var-arguments">a</var><a class="copiable-link" href='#index-size-1'> &para;</a></span></dt>
  1877. <dd><p>Get the total size of an <code class="code">ra::</code> object: the product of all its lengths.
  1878. </p></dd></dl>
  1879. <a class="index-entry-id" id="index-stencil"></a>
  1880. <a class="anchor" id="x_002dstencil"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1881. <dt class="deffn defun-alias-deffn" id="index-stencil-1"><span class="category-def">Function: </span><span><strong class="def-name">stencil</strong> <var class="def-var-arguments">view lo hi</var><a class="copiable-link" href='#index-stencil-1'> &para;</a></span></dt>
  1882. <dd><p>Create a stencil on <var class="var">view</var> with lower bounds <var class="var">lo</var> and higher bounds <var class="var">hi</var>.
  1883. </p>
  1884. <p><var class="var">lo</var> and <var class="var">hi</var> are expressions of rank 1 indicating the extent of the stencil on each dimension. Scalars are rank extended, that is, <var class="var">lo</var>=0 is equivalent to <var class="var">lo</var>=(0, 0, ..., 0) with length equal to the rank <code class="code">r</code> of <var class="var">view</var>. The stencil view has twice as many axes as <var class="var">view</var>. The first <code class="code">r</code> dimensions are the same as those of <var class="var">view</var> except that they have their lengths reduced by <var class="var">lo</var>+<var class="var">hi</var>. The last <code class="code">r</code> dimensions correspond to the stencil around each element of <var class="var">view</var>; the center element is at <code class="code">s(i0, i1, ..., lo(0), lo(1), ...)</code>.
  1885. </p>
  1886. <p>This operation does not work on arbitrary array expressions yet. TODO FILL
  1887. </p>
  1888. </dd></dl>
  1889. <a class="index-entry-id" id="index-swap"></a>
  1890. <a class="anchor" id="x_002dswap"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1891. <dt class="deffn defun-alias-deffn" id="index-swap-1"><span class="category-def">Function: </span><span><strong class="def-name">swap</strong> <var class="def-var-arguments">a b</var><a class="copiable-link" href='#index-swap-1'> &para;</a></span></dt>
  1892. <dd><p>Swap the contents of containers <var class="var">a</var> and <var class="var">b</var>.
  1893. </p>
  1894. <p>Both containers must be of the same storage type. The containers may have different shapes, but if at least one of them is of ct rank, then both of them must have the same rank.
  1895. </p>
  1896. <p>This function reuses <code class="code">std::swap</code> for same-rank overloads, so it must not be qualified (i.e. use <code class="code">swap(a, b)</code>, not <code class="code">ra::swap(a, b)</code>).
  1897. </p></dd></dl>
  1898. <div class="example">
  1899. <pre class="verbatim"> ra::Big&lt;int&gt; a ({2, 3}, 1 + ra::_0 - ra::_1); // (1)
  1900. ra::Big&lt;int&gt; b ({2, 3, 4}, 1 - ra::_0 + ra::_1 + ra::_2); // (2)
  1901. swap(a, b);
  1902. // as if (1) had b and (2) had a
  1903. </pre></div>
  1904. <a class="index-entry-id" id="index-transpose"></a>
  1905. <a class="anchor" id="x_002dtranspose"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1906. <dt class="deffn defun-alias-deffn" id="index-transpose-1"><span class="category-def">Function: </span><span><strong class="def-name">transpose</strong> <var class="def-var-arguments">&lt;axes ...&gt; (view) | (axes, view)</var><a class="copiable-link" href='#index-transpose-1'> &para;</a></span></dt>
  1907. <dd><p>Create a new view by transposing the axes of <var class="var">view</var>. The number of <var class="var">axes</var> must match the rank of <var class="var">view</var>.
  1908. </p>
  1909. <p>For example:
  1910. </p>
  1911. <div class="example">
  1912. <pre class="verbatim"> ra::Unique&lt;double, 2&gt; a = {{1, 2, 3}, {4, 5, 6}};
  1913. cout &lt;&lt; transpose&lt;1, 0&gt;(a) &lt;&lt; endl;
  1914. </pre><pre class="example-preformatted"> -|
  1915. 3 2
  1916. 1 4
  1917. 2 5
  1918. 3 6
  1919. </pre></div>
  1920. <p>The rank of the result is <code class="code">maxᵢ(axesᵢ)+1</code> and it may be smaller or larger than that of <var class="var">view</var>. If an axis is repeated, the smallest of the dimensions of <var class="var">view</var> is used. For example:
  1921. </p>
  1922. <div class="example">
  1923. <pre class="verbatim"> ra::Unique&lt;double, 2&gt; a = {{1, 2, 3}, {4, 5, 6}};
  1924. cout &lt;&lt; transpose&lt;0, 0&gt;(a) &lt;&lt; endl; // { a(0, 0), a(1, 1) }
  1925. </pre><pre class="example-preformatted"> -|
  1926. 2
  1927. 1 5
  1928. </pre></div>
  1929. <p>If one of the destination axes isn&rsquo;t mentioned in <var class="var">axes</var>, then it becomes a ‘dead’ axis similar to those produced by <a class="ref" href="#x_002dinsert"><code class="code">insert</code></a>. For example:
  1930. </p>
  1931. <div class="example">
  1932. <pre class="verbatim"> ra::Unique&lt;double, 1&gt; a = {1, 2, 3};
  1933. cout &lt;&lt; ((a*10) + transpose&lt;1&gt;(a)) &lt;&lt; endl;
  1934. </pre><pre class="example-preformatted"> -|
  1935. 3 3
  1936. 11 21 31
  1937. 12 22 32
  1938. 13 23 33
  1939. </pre></div>
  1940. <p>The two argument form lets you specify the axis list at runtime. In that case the result will have rt rank as well. For example: </p>
  1941. <div class="example">
  1942. <pre class="verbatim"> ra::Small&lt;int, 2&gt; axes = {0, 1};
  1943. ra::Unique&lt;double, 2&gt; a = {{1, 2, 3}, {4, 5, 6}};
  1944. cout &lt;&lt; &quot;A: &quot; &lt;&lt; transpose(axes, a) &lt;&lt; endl;
  1945. axes = {1, 0};
  1946. cout &lt;&lt; &quot;B: &quot; &lt;&lt; transpose(axes, a) &lt;&lt; endl;
  1947. </pre><pre class="example-preformatted"> -|
  1948. A: 2
  1949. 2 3
  1950. 1 2 3
  1951. 4 5 6
  1952. B: 2
  1953. 3 2
  1954. 1 4
  1955. 2 5
  1956. 3 6
  1957. </pre></div>
  1958. <p>This operation does not work on arbitrary array expressions yet. TODO FILL
  1959. </p>
  1960. </dd></dl>
  1961. <a class="index-entry-id" id="index-where"></a>
  1962. <a class="anchor" id="x_002dwhere"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1963. <dt class="deffn defun-alias-deffn" id="index-where-1"><span class="category-def">Function: </span><span><strong class="def-name">where</strong> <var class="def-var-arguments">pred_expr true_expr false_expr</var><a class="copiable-link" href='#index-where-1'> &para;</a></span></dt>
  1964. <dd><p>Create an array expression that selects <var class="var">true_expr</var> if <var class="var">pred_expr</var> is <code class="code">true</code>, and <var class="var">false_expr</var> if <var class="var">pred_expr</var> is <code class="code">false</code>. The expression that is not selected is not looked up.
  1965. </p>
  1966. <p>For example:
  1967. </p><div class="example">
  1968. <pre class="verbatim"> ra::Big&lt;double, 1&gt; s {1, -1, 3, 2};
  1969. s = where(s&gt;=2, 2, s); // saturate s
  1970. </pre><pre class="example-preformatted"> &rArr; s = {1, -1, 2, 2}
  1971. </pre></div>
  1972. </dd></dl>
  1973. <a class="index-entry-id" id="index-wrank"></a>
  1974. <a class="anchor" id="x_002dwrank"></a><dl class="first-deffn first-defun-alias-first-deffn">
  1975. <dt class="deffn defun-alias-deffn" id="index-wrank-1"><span class="category-def">Function: </span><span><strong class="def-name">wrank</strong> <var class="def-var-arguments">&lt;input_rank ...&gt; op</var><a class="copiable-link" href='#index-wrank-1'> &para;</a></span></dt>
  1976. <dd><p>Wrap <var class="var">op</var> using a rank conjunction (see <a class="pxref" href="#The-rank-conjunction">The rank conjunction</a>).
  1977. </p>
  1978. <p>For example: TODO
  1979. </p><div class="example">
  1980. <pre class="verbatim"></pre><pre class="example-preformatted"> &rArr; x = 0
  1981. </pre></div>
  1982. </dd></dl>
  1983. <a class="index-entry-id" id="index-noshape"></a>
  1984. <a class="index-entry-id" id="index-withshape"></a>
  1985. <a class="anchor" id="x_002dnoshape"></a><a class="anchor" id="x_002dwithshape"></a><dl class="first-deffn">
  1986. <dt class="deffn" id="index-withshape-noshape"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">withshape noshape</strong><a class="copiable-link" href='#index-withshape-noshape'> &para;</a></span></dt>
  1987. <dd><p>If either of these objects is sent to <code class="code">std::ostream</code> before an expression object, the shape of that object will or will not be printed.
  1988. </p>
  1989. <p>If the object has ct shape, the default is not to print the shape, so <code class="code">noshape</code> isn&rsquo;t necessary, and conversely for <code class="code">withshape</code> if the object has rt shape. Note that the array readers [<code class="code">operator&gt;&gt;(std::istream &amp;, ...)</code>] expect the shape to be present or not according to the default.
  1990. </p>
  1991. <p>For example:
  1992. </p>
  1993. <div class="example">
  1994. <pre class="verbatim">ra::Small&lt;int, 2, 2&gt; A = {77, 99};
  1995. cout &lt;&lt; &quot;case a:\n&quot; &lt;&lt; A &lt;&lt; endl;
  1996. cout &lt;&lt; &quot;case b:\n&quot; &lt;&lt; ra::noshape &lt;&lt; A &lt;&lt; endl;
  1997. cout &lt;&lt; &quot;case c:\n&quot; &lt;&lt; ra::withshape &lt;&lt; A &lt;&lt; endl;
  1998. </pre><pre class="example-preformatted">-| case a:
  1999. 77 99
  2000. case b:
  2001. 77 99
  2002. case c:
  2003. 2
  2004. 77 99
  2005. </pre></div>
  2006. <p>but:
  2007. </p>
  2008. <div class="example">
  2009. <pre class="verbatim">ra::Big&lt;int&gt; A = {77, 99};
  2010. cout &lt;&lt; &quot;case a:\n&quot; &lt;&lt; A &lt;&lt; endl;
  2011. cout &lt;&lt; &quot;case b:\n&quot; &lt;&lt; ra::noshape &lt;&lt; A &lt;&lt; endl;
  2012. cout &lt;&lt; &quot;case c:\n&quot; &lt;&lt; ra::withshape &lt;&lt; A &lt;&lt; endl;
  2013. </pre><pre class="example-preformatted">-| case a:
  2014. 1
  2015. 2
  2016. 77 99
  2017. case b:
  2018. 77 99
  2019. case c:
  2020. 1
  2021. 2
  2022. 77 99
  2023. </pre></div>
  2024. <p>Note that in the last example the very shape of <code class="code">ra::Big&lt;int&gt;</code> has rt length, so that length (the rank of <code class="code">A</code>, that is 1) is printed as part of the shape of <code class="code">A</code>.
  2025. </p>
  2026. <p>See also <a class="ref" href="#x_002dformat_005farray"><code class="code">format_array</code></a>.
  2027. </p>
  2028. </dd></dl>
  2029. <a class="index-entry-id" id="index-ptr"></a>
  2030. <a class="anchor" id="x_002dptr"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2031. <dt class="deffn defun-alias-deffn" id="index-ptr-1"><span class="category-def">Function: </span><span><strong class="def-name">ptr</strong> <var class="def-var-arguments">random_access_iterator [len]</var><a class="copiable-link" href='#index-ptr-1'> &para;</a></span></dt>
  2032. <dd><p>Create rank-1 expression from <var class="var">random_access_iterator</var>, which can be a raw pointer.
  2033. </p>
  2034. <p>If <code class="code">len</code> is not given, the expression has undefined length, and it will need to be matched with other expressions whose length is defined. <code class="code">ra::</code> doesn&rsquo;t know what is actually accessible through the iterator, so be careful. For instance:
  2035. </p>
  2036. <div class="example">
  2037. <pre class="verbatim">int p[] = {1, 2, 3};
  2038. ra::Big&lt;int, 1&gt; v3 {1, 2, 3};
  2039. ra::Big&lt;int, 1&gt; v4 {1, 2, 3, 4};
  2040. v3 += ra::ptr(p); // ok, shape (3): v3 = {2, 4, 6}
  2041. v4 += ra::ptr(p); // undefined, shape (4): bad access to p[3]
  2042. // cout &lt;&lt; (ra::ptr(p)+ra::TensorIndex&lt;0&gt;{}) &lt;&lt; endl; // ct error, expression has undefined shape
  2043. cout &lt;&lt; (ra::ptr(p, 3)+ra::TensorIndex&lt;0&gt;{}) &lt;&lt; endl; // ok, prints { 1, 3, 5 }
  2044. cout &lt;&lt; (ra::ptr(p, 4)+ra::TensorIndex&lt;0&gt;{}) &lt;&lt; endl; // undefined, bad access at p[4]
  2045. </pre></div>
  2046. <p>Of course in this example one could simply have used <code class="code">p</code> instead of <code class="code">ra::ptr(p)</code>, since the array type retains shape information.
  2047. </p>
  2048. <div class="example">
  2049. <pre class="verbatim">v3 += p; // ok
  2050. v4 += p; // error checked by ra::, shape clash (4) += (3)
  2051. cout &lt;&lt; (p + ra::TensorIndex&lt;0&gt;{}) &lt;&lt; endl; // ok
  2052. </pre></div>
  2053. <p><code class="code">ptr</code> isn&rsquo;t meant to be used with STL containers, which are converted to rank-1 expressions automatically of the right size automatically. See also <a class="ref" href="#x_002dstart"><code class="code">start</code></a>.
  2054. </p>
  2055. </dd></dl>
  2056. <a class="index-entry-id" id="index-start-1"></a>
  2057. <a class="anchor" id="x_002dstart"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2058. <dt class="deffn defun-alias-deffn" id="index-start-2"><span class="category-def">Function: </span><span><strong class="def-name">start</strong> <var class="def-var-arguments">foreign_object</var><a class="copiable-link" href='#index-start-2'> &para;</a></span></dt>
  2059. <dd><p>Create array expression from <var class="var">foreign_object</var>.
  2060. </p>
  2061. <p><var class="var">foreign_object</var> can be a built-in array (e.g. <code class="code">int[3][2]</code>), a <code class="code">std::random_access_range</code> type (including <code class="code">std::vector</code> or <code class="code">std::array</code>, see <a class="pxref" href="#Compatibility">Compatibility</a>), an initializer list, or any object that <code class="code">ra::</code> accepts as scalar (see <a class="ref" href="#x_002dis_002dscalar"><code class="code">here</code></a>). The resulting expresion has shape according to the original object. Compare this with <a class="ref" href="#x_002dscalar"><code class="code">scalar</code></a>, which will always produce an expression of rank 0.
  2062. </p>
  2063. <p>Generally one can mix these types with <code class="code">ra::</code> expressions without needing <code class="code">ra::start</code>, but sometimes this isn&rsquo;t possible, for example for operators that must be class members.
  2064. </p>
  2065. <div class="example">
  2066. <pre class="verbatim">std::vector&lt;int&gt; x = {1, 2, 3};
  2067. ra::Big&lt;int, 1&gt; y = {10, 20, 30};
  2068. cout &lt;&lt; (x+y) &lt;&lt; endl; // same as ra::start(x)+y
  2069. // x += y; // error: no match for operator+=
  2070. ra::start(x) += y; // ok
  2071. </pre><pre class="example-preformatted">-| 3
  2072. 11 22 33
  2073. &rArr; x = { 11, 22, 33 }
  2074. </pre></div>
  2075. </dd></dl>
  2076. <a class="index-entry-id" id="index-scalar"></a>
  2077. <a class="anchor" id="x_002dscalar"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2078. <dt class="deffn defun-alias-deffn" id="index-scalar-1"><span class="category-def">Function: </span><span><strong class="def-name">scalar</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-scalar-1'> &para;</a></span></dt>
  2079. <dd><p>Create scalar expression from <var class="var">expr</var>.
  2080. </p>
  2081. <p>The primary use of this function is to bring a scalar object into the <code class="code">ra::</code> namespace. A somewhat artificial example:
  2082. </p>
  2083. <div class="example">
  2084. <pre class="verbatim">struct W { int x; }
  2085. ra::Big&lt;W, 1&gt; w { {1}, {2}, {3} };
  2086. // error: no matching function for call to start(W)
  2087. // for_each([](auto &amp;&amp; a, auto &amp;&amp; b) { cout &lt;&lt; (a.x + b.x) &lt;&lt; endl; }, w, W {7});
  2088. // bring W into ra:: with ra::scalar
  2089. for_each([](auto &amp;&amp; a, auto &amp;&amp; b) { cout &lt;&lt; (a.x + b.x) &lt;&lt; endl; }, w, ra::scalar(W {7}));
  2090. </pre><pre class="example-preformatted">-| 8
  2091. 9
  2092. 10
  2093. </pre></div>
  2094. <p>See also <a class="ref" href="#x_002dscalar_002dchar_002dstar"><code class="code">this example</code></a>.
  2095. </p>
  2096. <p>Since <code class="code">scalar</code> produces an object with rank 0, it&rsquo;s also useful when dealing with nested arrays, even for objects that are already in <code class="code">ra::</code>. Consider:
  2097. </p><div class="example">
  2098. <pre class="verbatim">using Vec2 = ra::Small&lt;double, 2&gt;;
  2099. Vec2 x {-1, 1};
  2100. ra::Big&lt;Vec2, 1&gt; c { {1, 2}, {2, 3}, {3, 4} };
  2101. // c += x // error: x has shape (2) and c has shape (3)
  2102. c += ra::scalar(x); // ok: scalar(x) has shape () and matches c.
  2103. </pre><pre class="example-preformatted"> &rArr; c = { {0, 3}, {1, 4}, {2, 5} }
  2104. </pre></div>
  2105. <p>The result is {c(0)+x, c(1)+x, c(2)+x}. Compare this with
  2106. </p><div class="example">
  2107. <pre class="verbatim">c(ra::iota(2)) += x; // c(ra::iota(2)) with shape (2) matches x with shape (2)
  2108. </pre><pre class="example-preformatted"> &rArr; c = { {-1, 2}, {2, 5}, {2, 5} }
  2109. </pre></div>
  2110. <p>where the result is {c(0)+x(0), c(1)+x(1), c(2)}.
  2111. </p>
  2112. </dd></dl>
  2113. <a class="index-entry-id" id="index-iter"></a>
  2114. <a class="anchor" id="x_002diter"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2115. <dt class="deffn defun-alias-deffn" id="index-iter-1"><span class="category-def">Function: </span><span><strong class="def-name">iter</strong> <var class="def-var-arguments">&lt;k&gt; (view)</var><a class="copiable-link" href='#index-iter-1'> &para;</a></span></dt>
  2116. <dd><p>Create iterator over the <var class="var">k</var>-cells of <var class="var">view</var>. If <var class="var">k</var> is negative, it is interpreted as the negative of the frame rank. In the current version of <code class="code">ra::</code>, <var class="var">view</var> may have rt or ct shape.
  2117. </p>
  2118. <div class="example">
  2119. <pre class="verbatim">ra::Big&lt;int, 2&gt; c {{1, 3, 2}, {7, 1, 3}};
  2120. cout &lt;&lt; &quot;max of each row: &quot; &lt;&lt; map([](auto &amp;&amp; a) { return amax(a); }, iter&lt;1&gt;(c)) &lt;&lt; endl;
  2121. ra::Big&lt;int, 1&gt; m({3}, 0);
  2122. scalar(m) = max(scalar(m), iter&lt;1&gt;(c));
  2123. cout &lt;&lt; &quot;max of each column: &quot; &lt;&lt; m &lt;&lt; endl;
  2124. m = 0;
  2125. for_each([&amp;m](auto &amp;&amp; a) { m = max(m, a); }, iter&lt;1&gt;(c));
  2126. cout &lt;&lt; &quot;max of each column again: &quot; &lt;&lt; m &lt;&lt; endl;
  2127. </pre><pre class="example-preformatted">-| max of each row: 2
  2128. 3 7
  2129. max of each column: 3
  2130. 7 3 3
  2131. max of each column again: 3
  2132. 7 3 3
  2133. </pre></div>
  2134. <p>In the following example, <code class="code">iter</code> emulates <code class="code">scalar</code>. Note that the shape () of <code class="code">iter&lt;1&gt;(m)</code> matches the shape (3) of <code class="code">iter&lt;1&gt;(c)</code>. Thus, each of the 1-cells of <code class="code">c</code> matches against the single 1-cell of <code class="code">m</code>.
  2135. </p>
  2136. <div class="example">
  2137. <pre class="verbatim">m = 0;
  2138. iter&lt;1&gt;(m) = max(iter&lt;1&gt;(m), iter&lt;1&gt;(c));
  2139. cout &lt;&lt; &quot;max of each column yet again: &quot; &lt;&lt; m &lt;&lt; endl;
  2140. </pre><pre class="example-preformatted">-| max of each column again: 3
  2141. 7 3 3
  2142. </pre></div>
  2143. <p>The following example computes the trace of each of the items [(-1)-cells] of <code class="code">c</code>. </p>
  2144. <div class="example">
  2145. <pre class="verbatim">ra::Small&lt;int, 3, 2, 2&gt; c = ra::_0 - ra::_1 - 2*ra::_2;
  2146. cout &lt;&lt; &quot;c: &quot; &lt;&lt; c &lt;&lt; endl;
  2147. cout &lt;&lt; &quot;s: &quot; &lt;&lt; map([](auto &amp;&amp; a) { return sum(diag(a)); }, iter&lt;-1&gt;(c)) &lt;&lt; endl;
  2148. </pre><pre class="example-preformatted">-| c: 0 -2
  2149. -1 -3
  2150. 1 -1
  2151. 0 -2
  2152. 2 0
  2153. 1 -1
  2154. s: -3 -1 -1
  2155. </pre></div>
  2156. </dd></dl>
  2157. <a class="index-entry-id" id="index-sum"></a>
  2158. <a class="anchor" id="x_002dsum"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2159. <dt class="deffn defun-alias-deffn" id="index-sum-1"><span class="category-def">Function: </span><span><strong class="def-name">sum</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-sum-1'> &para;</a></span></dt>
  2160. <dd><p>Return the sum (+) of the elements of <var class="var">expr</var>, or 0 if expr is empty. This sum is performed in unspecified order.
  2161. </p></dd></dl>
  2162. <a class="index-entry-id" id="index-prod"></a>
  2163. <a class="anchor" id="x_002dprod"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2164. <dt class="deffn defun-alias-deffn" id="index-prod-1"><span class="category-def">Function: </span><span><strong class="def-name">prod</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-prod-1'> &para;</a></span></dt>
  2165. <dd><p>Return the product (*) of the elements of <var class="var">expr</var>, or 1 if expr is empty. This product is performed in unspecified order.
  2166. </p></dd></dl>
  2167. <a class="index-entry-id" id="index-amax"></a>
  2168. <a class="anchor" id="x_002damax"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2169. <dt class="deffn defun-alias-deffn" id="index-amax-1"><span class="category-def">Function: </span><span><strong class="def-name">amax</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-amax-1'> &para;</a></span></dt>
  2170. <dd><p>Return the maximum of the elements of <var class="var">expr</var>. If <var class="var">expr</var> is empty, return <code class="code">-std::numeric_limits&lt;T&gt;::infinity()</code> if the type supports it, otherwise <code class="code">std::numeric_limits&lt;T&gt;::lowest()</code>, where <code class="code">T</code> is the value type of the elements of <var class="var">expr</var>.
  2171. </p></dd></dl>
  2172. <a class="index-entry-id" id="index-amin"></a>
  2173. <a class="anchor" id="x_002damin"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2174. <dt class="deffn defun-alias-deffn" id="index-amin-1"><span class="category-def">Function: </span><span><strong class="def-name">amin</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-amin-1'> &para;</a></span></dt>
  2175. <dd><p>Return the minimum of the elements of <var class="var">expr</var>. If <var class="var">expr</var> is empty, return <code class="code">+std::numeric_limits&lt;T&gt;::infinity()</code> if the type supports it, otherwise <code class="code">std::numeric_limits&lt;T&gt;::max()</code>, where <code class="code">T</code> is the value type of the elements of <var class="var">expr</var>.
  2176. </p></dd></dl>
  2177. <a class="index-entry-id" id="index-early"></a>
  2178. <a class="anchor" id="x_002dearly"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2179. <dt class="deffn defun-alias-deffn" id="index-early-1"><span class="category-def">Function: </span><span><strong class="def-name">early</strong> <var class="def-var-arguments">expr default</var><a class="copiable-link" href='#index-early-1'> &para;</a></span></dt>
  2180. <dd><p><var class="var">expr</var> shall be an array expression that returns <code class="code">std::tuple&lt;bool, T&gt;</code>. <var class="var">expr</var> is traversed as by <code class="code">for_each</code>; if the expression ever returns <code class="code">true</code> in the first element of the tuple, traversal stops and the second element is returned. If this never happens, <var class="var">default</var> is returned instead.
  2181. </p>
  2182. <p>The following definition of elementwise <code class="code">lexicographical_compare</code> relies on <code class="code">early</code>.
  2183. </p>
  2184. <div class="example">
  2185. <pre class="verbatim">template &lt;class A, class B&gt;
  2186. inline bool lexicographical_compare(A &amp;&amp; a, B &amp;&amp; b)
  2187. {
  2188. return early(map([](auto &amp;&amp; a, auto &amp;&amp; b)
  2189. { return a==b ? std::make_tuple(false, true) : std::make_tuple(true, a&lt;b); },
  2190. a, b),
  2191. false);
  2192. }
  2193. </pre></div>
  2194. </dd></dl>
  2195. <a class="index-entry-id" id="index-any"></a>
  2196. <a class="anchor" id="x_002dany"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2197. <dt class="deffn defun-alias-deffn" id="index-any-1"><span class="category-def">Function: </span><span><strong class="def-name">any</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-any-1'> &para;</a></span></dt>
  2198. <dd><p>Return <code class="code">true</code> if any element of <var class="var">expr</var> is true, <code class="code">false</code> otherwise. The traversal of the array expression will stop as soon as possible, but the traversal order is not specified.
  2199. </p></dd></dl>
  2200. <a class="index-entry-id" id="index-every"></a>
  2201. <a class="anchor" id="x_002devery"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2202. <dt class="deffn defun-alias-deffn" id="index-every-1"><span class="category-def">Function: </span><span><strong class="def-name">every</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-every-1'> &para;</a></span></dt>
  2203. <dd><p>Return <code class="code">true</code> if every element of <var class="var">expr</var> is true, <code class="code">false</code> otherwise. The traversal of the array expression will stop as soon as possible, but the traversal order is not specified.
  2204. </p></dd></dl>
  2205. <a class="index-entry-id" id="index-sqr"></a>
  2206. <a class="anchor" id="x_002dsqr"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2207. <dt class="deffn defun-alias-deffn" id="index-sqr-1"><span class="category-def">Function: </span><span><strong class="def-name">sqr</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-sqr-1'> &para;</a></span></dt>
  2208. <dd><p>Compute the square of <var class="var">expr</var>.
  2209. </p></dd></dl>
  2210. <a class="index-entry-id" id="index-sqrm"></a>
  2211. <a class="anchor" id="x_002dsqrm"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2212. <dt class="deffn defun-alias-deffn" id="index-sqrm-1"><span class="category-def">Function: </span><span><strong class="def-name">sqrm</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-sqrm-1'> &para;</a></span></dt>
  2213. <dd><p>Compute the square of the norm-2 of <var class="var">expr</var>, that is, <code class="code">conj(expr)*expr</code>.
  2214. </p></dd></dl>
  2215. <a class="index-entry-id" id="index-conj"></a>
  2216. <a class="anchor" id="x_002dconj"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2217. <dt class="deffn defun-alias-deffn" id="index-conj-1"><span class="category-def">Function: </span><span><strong class="def-name">conj</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-conj-1'> &para;</a></span></dt>
  2218. <dd><p>Compute the complex conjugate of <var class="var">expr</var>.
  2219. </p></dd></dl>
  2220. <a class="index-entry-id" id="index-xI"></a>
  2221. <a class="anchor" id="x_002dxI"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2222. <dt class="deffn defun-alias-deffn" id="index-xI-1"><span class="category-def">Function: </span><span><strong class="def-name">xI</strong> <var class="def-var-arguments">expr</var><a class="copiable-link" href='#index-xI-1'> &para;</a></span></dt>
  2223. <dd><p>Compute <code class="code">(0+1j)</code> times <var class="var">expr</var>.
  2224. </p></dd></dl>
  2225. <a class="index-entry-id" id="index-rel_005ferror"></a>
  2226. <a class="anchor" id="x_002drel_002derror"></a><dl class="first-deffn first-defun-alias-first-deffn">
  2227. <dt class="deffn defun-alias-deffn" id="index-rel_005ferror-1"><span class="category-def">Function: </span><span><strong class="def-name">rel_error</strong> <var class="def-var-arguments">a b</var><a class="copiable-link" href='#index-rel_005ferror-1'> &para;</a></span></dt>
  2228. <dd><p><var class="var">a</var> and <var class="var">b</var> are arbitrary array expressions. Compute the error of <var class="var">a</var> relative to <var class="var">b</var> as
  2229. </p>
  2230. <p><code class="code">(a==0. &amp;&amp; b==0.) ? 0. : 2.*abs(a, b)/(abs(a)+abs(b))</code>
  2231. </p>
  2232. </dd></dl>
  2233. <a class="index-entry-id" id="index-none-2"></a>
  2234. <a class="anchor" id="x_002dnone"></a><dl class="first-deffn">
  2235. <dt class="deffn" id="index-none-3"><span class="category-def">Special&nbsp;object<!-- /@w -->: </span><span><strong class="def-name">none</strong><a class="copiable-link" href='#index-none-3'> &para;</a></span></dt>
  2236. <dd><p>Pass <code class="code">none</code> to container constructors to indicate that the contents shouldn&rsquo;t be initialized. This is appropriate when the initialization you have in mind wouldn&rsquo;t fit in a constructor argument. For example:
  2237. </p>
  2238. <div class="example">
  2239. <pre class="verbatim">void old_style_initializer(int m, int n, double *);
  2240. ra::Big&lt;double&gt; b({2, 3}, ra::none);
  2241. old_style_initializer(2, 3, b.data());
  2242. </pre></div>
  2243. </dd></dl>
  2244. <hr>
  2245. </div>
  2246. <div class="chapter-level-extent" id="Sources">
  2247. <div class="nav-panel">
  2248. <p>
  2249. Next: <a href="#Indices" accesskey="n" rel="next">Indices</a>, Previous: <a href="#Reference" accesskey="p" rel="prev">Reference</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  2250. </div>
  2251. <h2 class="chapter" id="Sources-1">8 Sources</h2>
  2252. <table class="multitable">
  2253. <tbody><tr><td width="10%"></td></tr>
  2254. <tr><td width="10%"><a class="anchor" id="Abr70"></a>[Abr70]</td><td width="90%">Philip S. Abrams. An APL machine. Technical report SLAC-114 UC-32 (MISC), Stanford Linear Accelerator Center, Stanford University, Stanford, CA, USA, February 1970.</td></tr>
  2255. <tr><td width="10%"></td></tr>
  2256. <tr><td width="10%"><a class="anchor" id="Ber87"></a>[Ber87]</td><td width="90%">Robert Bernecky. An introduction to function rank. ACM SIGAPL APL Quote Quad, 18(2):39–43, December 1987.</td></tr>
  2257. <tr><td width="10%"></td></tr>
  2258. <tr><td width="10%"><a class="anchor" id="bli17"></a>[bli17]</td><td width="90%">The Blitz++ meta-template library. <a class="url" href="http://blitz.sourceforge.net">http://blitz.sourceforge.net</a>, November 2017.</td></tr>
  2259. <tr><td width="10%"></td></tr>
  2260. <tr><td width="10%"><a class="anchor" id="Cha86"></a>[Cha86]</td><td width="90%">Gregory J. Chaitin. Physics in APL2, June 1986.</td></tr>
  2261. <tr><td width="10%"></td></tr>
  2262. <tr><td width="10%"><a class="anchor" id="FI68"></a>[FI68]</td><td width="90%">Adin D. Falkoff and Kenneth Eugene Iverson. APL\360 User’s manual. IBM Thomas J. Watson Research Center, August 1968.</td></tr>
  2263. <tr><td width="10%"></td></tr>
  2264. <tr><td width="10%"><a class="anchor" id="FI73"></a>[FI73]</td><td width="90%">Adin D. Falkoff and Kenneth Eugene Iverson. The design of APL. IBM Journal of Research and Development, 17(4):5–14, July 1973.</td></tr>
  2265. <tr><td width="10%"></td></tr>
  2266. <tr><td width="10%"><a class="anchor" id="FI78"></a>[FI78]</td><td width="90%">Adin D. Falkoff and Kenneth Eugene Iverson. The evolution of APL. ACM SIGAPL APL, 9(1):30– 44, 1978.</td></tr>
  2267. <tr><td width="10%"></td></tr>
  2268. <tr><td width="10%"><a class="anchor" id="J-S"></a>[J S]</td><td width="90%">J Primer. J Software, <a class="url" href="https://www.jsoftware.com/help/primer/contents.htm">https://www.jsoftware.com/help/primer/contents.htm</a>, November 2017.</td></tr>
  2269. <tr><td width="10%"></td></tr>
  2270. <tr><td width="10%"><a class="anchor" id="Mat"></a>[Mat]</td><td width="90%">MathWorks. MATLAB documentation, <a class="url" href="https://www.mathworks.com/help/matlab/">https://www.mathworks.com/help/matlab/</a>, November 2017.</td></tr>
  2271. <tr><td width="10%"></td></tr>
  2272. <tr><td width="10%"><a class="anchor" id="num17"></a>[num17]</td><td width="90%">NumPy. <a class="url" href="http://www.numpy.org">http://www.numpy.org</a>, November 2017.</td></tr>
  2273. <tr><td width="10%"></td></tr>
  2274. <tr><td width="10%"><a class="anchor" id="Ric08"></a>[Ric08]</td><td width="90%">Henry Rich. J for C programmers, February 2008.</td></tr>
  2275. <tr><td width="10%"></td></tr>
  2276. <tr><td width="10%"><a class="anchor" id="SSM14"></a>[SSM14]</td><td width="90%">Justin Slepak, Olin Shivers, and Panagiotis Manolios. An array-oriented language with static rank polymorphism. In Z. Shao, editor, ESOP 2014, LNCS 8410, pages 27–46, 2014.</td></tr>
  2277. <tr><td width="10%"></td></tr>
  2278. <tr><td width="10%"><a class="anchor" id="Vel01"></a>[Vel01]</td><td width="90%">Todd Veldhuizen. Blitz++ user’s guide, February 2001.</td></tr>
  2279. <tr><td width="10%"></td></tr>
  2280. <tr><td width="10%"><a class="anchor" id="Wad90"></a>[Wad90]</td><td width="90%">Philip Wadler. Deforestation: transforming programs to eliminate trees. Theoretical Computer Science, 73(2): 231&ndash;248, June 1990. <a class="url" href="https://doi.org/10.1016/0304-3975%2890%2990147-A">https://doi.org/10.1016/0304-3975%2890%2990147-A</a></td></tr>
  2281. </tbody>
  2282. </table>
  2283. <hr>
  2284. </div>
  2285. <div class="unnumbered-level-extent" id="Indices">
  2286. <div class="nav-panel">
  2287. <p>
  2288. Next: <a href="#Notes" accesskey="n" rel="next">Notes</a>, Previous: <a href="#Sources" accesskey="p" rel="prev">Sources</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  2289. </div>
  2290. <h2 class="unnumbered" id="Indices-1">Indices</h2>
  2291. <div class="printindex cp-printindex">
  2292. <table class="cp-letters-header-printindex"><tr><th>Jump to: &nbsp; </th><td><a class="summary-letter-printindex" href="#Indices_cp_letter-A"><b>A</b></a>
  2293. &nbsp;
  2294. <a class="summary-letter-printindex" href="#Indices_cp_letter-B"><b>B</b></a>
  2295. &nbsp;
  2296. <a class="summary-letter-printindex" href="#Indices_cp_letter-C"><b>C</b></a>
  2297. &nbsp;
  2298. <a class="summary-letter-printindex" href="#Indices_cp_letter-D"><b>D</b></a>
  2299. &nbsp;
  2300. <a class="summary-letter-printindex" href="#Indices_cp_letter-E"><b>E</b></a>
  2301. &nbsp;
  2302. <a class="summary-letter-printindex" href="#Indices_cp_letter-F"><b>F</b></a>
  2303. &nbsp;
  2304. <a class="summary-letter-printindex" href="#Indices_cp_letter-G"><b>G</b></a>
  2305. &nbsp;
  2306. <a class="summary-letter-printindex" href="#Indices_cp_letter-I"><b>I</b></a>
  2307. &nbsp;
  2308. <a class="summary-letter-printindex" href="#Indices_cp_letter-J"><b>J</b></a>
  2309. &nbsp;
  2310. <a class="summary-letter-printindex" href="#Indices_cp_letter-L"><b>L</b></a>
  2311. &nbsp;
  2312. <a class="summary-letter-printindex" href="#Indices_cp_letter-M"><b>M</b></a>
  2313. &nbsp;
  2314. <a class="summary-letter-printindex" href="#Indices_cp_letter-N"><b>N</b></a>
  2315. &nbsp;
  2316. <a class="summary-letter-printindex" href="#Indices_cp_letter-O"><b>O</b></a>
  2317. &nbsp;
  2318. <a class="summary-letter-printindex" href="#Indices_cp_letter-P"><b>P</b></a>
  2319. &nbsp;
  2320. <a class="summary-letter-printindex" href="#Indices_cp_letter-R"><b>R</b></a>
  2321. &nbsp;
  2322. <a class="summary-letter-printindex" href="#Indices_cp_letter-S"><b>S</b></a>
  2323. &nbsp;
  2324. <a class="summary-letter-printindex" href="#Indices_cp_letter-T"><b>T</b></a>
  2325. &nbsp;
  2326. <a class="summary-letter-printindex" href="#Indices_cp_letter-U"><b>U</b></a>
  2327. &nbsp;
  2328. <a class="summary-letter-printindex" href="#Indices_cp_letter-V"><b>V</b></a>
  2329. &nbsp;
  2330. <a class="summary-letter-printindex" href="#Indices_cp_letter-W"><b>W</b></a>
  2331. &nbsp;
  2332. <a class="summary-letter-printindex" href="#Indices_cp_letter-X"><b>X</b></a>
  2333. &nbsp;
  2334. </td></tr></table>
  2335. <table class="cp-entries-printindex" border="0">
  2336. <tr><td></td><th class="entries-header-printindex">Index Entry</th><td>&nbsp;</td><th class="sections-header-printindex"> Section</th></tr>
  2337. <tr><td colspan="4"> <hr></td></tr>
  2338. <tr><th id="Indices_cp_letter-A">A</th><td></td><td></td></tr>
  2339. <tr><td></td><td class="printindex-index-entry"><a href="#index-agree"><code class="code">agree</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2340. <tr><td></td><td class="printindex-index-entry"><a href="#index-agree_005fop"><code class="code">agree_op</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2341. <tr><td></td><td class="printindex-index-entry"><a href="#index-amax"><code class="code">amax</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2342. <tr><td></td><td class="printindex-index-entry"><a href="#index-amin"><code class="code">amin</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2343. <tr><td></td><td class="printindex-index-entry"><a href="#index-any"><code class="code">any</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2344. <tr><td></td><td class="printindex-index-entry"><a href="#index-APL">APL</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Why-C_002b_002b">Why C++</a></td></tr>
  2345. <tr><td></td><td class="printindex-index-entry"><a href="#index-assert">assert</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Functions">Functions</a></td></tr>
  2346. <tr><td></td><td class="printindex-index-entry"><a href="#index-at"><code class="code">at</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2347. <tr><td colspan="4"> <hr></td></tr>
  2348. <tr><th id="Indices_cp_letter-B">B</th><td></td><td></td></tr>
  2349. <tr><td></td><td class="printindex-index-entry"><a href="#index-BLIS">BLIS</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2350. <tr><td></td><td class="printindex-index-entry"><a href="#index-Blitz_002b_002b">Blitz++</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Overview">Overview</a></td></tr>
  2351. <tr><td></td><td class="printindex-index-entry"><a href="#index-Blitz_002b_002b-1">Blitz++</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Other-libraries">Other libraries</a></td></tr>
  2352. <tr><td></td><td class="printindex-index-entry"><a href="#index-Blitz_002b_002b-2">Blitz++</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Extension">Extension</a></td></tr>
  2353. <tr><td></td><td class="printindex-index-entry"><a href="#index-broadcasting_002c-singleton_002c-newaxis">broadcasting, singleton, newaxis</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-extension">Rank extension</a></td></tr>
  2354. <tr><td></td><td class="printindex-index-entry"><a href="#index-broadcasting_002c-singleton_002c-Numpy">broadcasting, singleton, Numpy</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2355. <tr><td></td><td class="printindex-index-entry"><a href="#index-built_002din-array">built-in array</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2356. <tr><td colspan="4"> <hr></td></tr>
  2357. <tr><th id="Indices_cp_letter-C">C</th><td></td><td></td></tr>
  2358. <tr><td></td><td class="printindex-index-entry"><a href="#index-cast"><code class="code">cast</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2359. <tr><td></td><td class="printindex-index-entry"><a href="#index-cell">cell</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
  2360. <tr><td></td><td class="printindex-index-entry"><a href="#index-collapse"><code class="code">collapse</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2361. <tr><td></td><td class="printindex-index-entry"><a href="#index-compile_002dtime">compile-time</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2362. <tr><td></td><td class="printindex-index-entry"><a href="#index-concrete"><code class="code">concrete</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2363. <tr><td></td><td class="printindex-index-entry"><a href="#index-conj"><code class="code">conj</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2364. <tr><td></td><td class="printindex-index-entry"><a href="#index-container">container</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Using-the-library">Using the library</a></td></tr>
  2365. <tr><td></td><td class="printindex-index-entry"><a href="#index-ct">ct</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2366. <tr><td colspan="4"> <hr></td></tr>
  2367. <tr><th id="Indices_cp_letter-D">D</th><td></td><td></td></tr>
  2368. <tr><td></td><td class="printindex-index-entry"><a href="#index-diag"><code class="code">diag</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2369. <tr><td colspan="4"> <hr></td></tr>
  2370. <tr><th id="Indices_cp_letter-E">E</th><td></td><td></td></tr>
  2371. <tr><td></td><td class="printindex-index-entry"><a href="#index-early"><code class="code">early</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2372. <tr><td></td><td class="printindex-index-entry"><a href="#index-elision_002c-index">elision, index</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2373. <tr><td></td><td class="printindex-index-entry"><a href="#index-end_002c-Octave_002fMatlab"><code class="code">end</code>, Octave/Matlab</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2374. <tr><td></td><td class="printindex-index-entry"><a href="#index-error">error</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Functions">Functions</a></td></tr>
  2375. <tr><td></td><td class="printindex-index-entry"><a href="#index-every"><code class="code">every</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2376. <tr><td></td><td class="printindex-index-entry"><a href="#index-explode"><code class="code">explode</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2377. <tr><td colspan="4"> <hr></td></tr>
  2378. <tr><th id="Indices_cp_letter-F">F</th><td></td><td></td></tr>
  2379. <tr><td></td><td class="printindex-index-entry"><a href="#index-FFTW">FFTW</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2380. <tr><td></td><td class="printindex-index-entry"><a href="#index-foreign-type">foreign type</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2381. <tr><td></td><td class="printindex-index-entry"><a href="#index-format_005farray"><code class="code">format_array</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2382. <tr><td></td><td class="printindex-index-entry"><a href="#index-for_005feach"><code class="code">for_each</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2383. <tr><td></td><td class="printindex-index-entry"><a href="#index-frame">frame</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
  2384. <tr><td></td><td class="printindex-index-entry"><a href="#index-from"><code class="code">from</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2385. <tr><td colspan="4"> <hr></td></tr>
  2386. <tr><th id="Indices_cp_letter-G">G</th><td></td><td></td></tr>
  2387. <tr><td></td><td class="printindex-index-entry"><a href="#index-Guile">Guile</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2388. <tr><td colspan="4"> <hr></td></tr>
  2389. <tr><th id="Indices_cp_letter-I">I</th><td></td><td></td></tr>
  2390. <tr><td></td><td class="printindex-index-entry"><a href="#index-imag_005fpart"><code class="code">imag_part</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2391. <tr><td></td><td class="printindex-index-entry"><a href="#index-insert"><code class="code">insert</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2392. <tr><td></td><td class="printindex-index-entry"><a href="#index-iter"><code class="code">iter</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2393. <tr><td colspan="4"> <hr></td></tr>
  2394. <tr><th id="Indices_cp_letter-J">J</th><td></td><td></td></tr>
  2395. <tr><td></td><td class="printindex-index-entry"><a href="#index-J">J</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Why-C_002b_002b">Why C++</a></td></tr>
  2396. <tr><td colspan="4"> <hr></td></tr>
  2397. <tr><th id="Indices_cp_letter-L">L</th><td></td><td></td></tr>
  2398. <tr><td></td><td class="printindex-index-entry"><a href="#index-len"><code class="code">len</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2399. <tr><td></td><td class="printindex-index-entry"><a href="#index-length">length</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Overview">Overview</a></td></tr>
  2400. <tr><td colspan="4"> <hr></td></tr>
  2401. <tr><th id="Indices_cp_letter-M">M</th><td></td><td></td></tr>
  2402. <tr><td></td><td class="printindex-index-entry"><a href="#index-map"><code class="code">map</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2403. <tr><td colspan="4"> <hr></td></tr>
  2404. <tr><th id="Indices_cp_letter-N">N</th><td></td><td></td></tr>
  2405. <tr><td></td><td class="printindex-index-entry"><a href="#index-none"><code class="code">none</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2406. <tr><td></td><td class="printindex-index-entry"><a href="#index-none-1"><code class="code">none</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2407. <tr><td></td><td class="printindex-index-entry"><a href="#index-none-2"><code class="code">none</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2408. <tr><td></td><td class="printindex-index-entry"><a href="#index-noshape"><code class="code">noshape</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2409. <tr><td></td><td class="printindex-index-entry"><a href="#index-Numpy">Numpy</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-extension">Rank extension</a></td></tr>
  2410. <tr><td></td><td class="printindex-index-entry"><a href="#index-Numpy-1">Numpy</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-extension">Rank extension</a></td></tr>
  2411. <tr><td></td><td class="printindex-index-entry"><a href="#index-Numpy-2">Numpy</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2412. <tr><td colspan="4"> <hr></td></tr>
  2413. <tr><th id="Indices_cp_letter-O">O</th><td></td><td></td></tr>
  2414. <tr><td></td><td class="printindex-index-entry"><a href="#index-OpenGL">OpenGL</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2415. <tr><td></td><td class="printindex-index-entry"><a href="#index-order_002c-column_002dmajor">order, column-major</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2416. <tr><td></td><td class="printindex-index-entry"><a href="#index-order_002c-row_002dmajor">order, row-major</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
  2417. <tr><td></td><td class="printindex-index-entry"><a href="#index-other-libraries_002c-interfacing-with">other libraries, interfacing with</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2418. <tr><td></td><td class="printindex-index-entry"><a href="#index-overload-set">overload set</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Extension">Extension</a></td></tr>
  2419. <tr><td colspan="4"> <hr></td></tr>
  2420. <tr><th id="Indices_cp_letter-P">P</th><td></td><td></td></tr>
  2421. <tr><td></td><td class="printindex-index-entry"><a href="#index-pack"><code class="code">pack</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2422. <tr><td></td><td class="printindex-index-entry"><a href="#index-pick"><code class="code">pick</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2423. <tr><td></td><td class="printindex-index-entry"><a href="#index-ply"><code class="code">ply</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2424. <tr><td></td><td class="printindex-index-entry"><a href="#index-prod"><code class="code">prod</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2425. <tr><td></td><td class="printindex-index-entry"><a href="#index-ptr"><code class="code">ptr</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2426. <tr><td></td><td class="printindex-index-entry"><a href="#index-Python">Python</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2427. <tr><td colspan="4"> <hr></td></tr>
  2428. <tr><th id="Indices_cp_letter-R">R</th><td></td><td></td></tr>
  2429. <tr><td></td><td class="printindex-index-entry"><a href="#index-rank">rank</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Overview">Overview</a></td></tr>
  2430. <tr><td></td><td class="printindex-index-entry"><a href="#index-rank_002c-compile_002dtime">rank, compile-time</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2431. <tr><td></td><td class="printindex-index-entry"><a href="#index-rank_002c-runtime">rank, runtime</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2432. <tr><td></td><td class="printindex-index-entry"><a href="#index-real_005fpart"><code class="code">real_part</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2433. <tr><td></td><td class="printindex-index-entry"><a href="#index-rel_005ferror"><code class="code">rel_error</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2434. <tr><td></td><td class="printindex-index-entry"><a href="#index-reverse"><code class="code">reverse</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2435. <tr><td></td><td class="printindex-index-entry"><a href="#index-rt">rt</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2436. <tr><td></td><td class="printindex-index-entry"><a href="#index-runtime">runtime</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2437. <tr><td colspan="4"> <hr></td></tr>
  2438. <tr><th id="Indices_cp_letter-S">S</th><td></td><td></td></tr>
  2439. <tr><td></td><td class="printindex-index-entry"><a href="#index-scalar"><code class="code">scalar</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2440. <tr><td></td><td class="printindex-index-entry"><a href="#index-shape">shape</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Overview">Overview</a></td></tr>
  2441. <tr><td></td><td class="printindex-index-entry"><a href="#index-shape-1"><code class="code">shape</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2442. <tr><td></td><td class="printindex-index-entry"><a href="#index-shape-agreement_002c-prefix">shape agreement, prefix</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-extension">Rank extension</a></td></tr>
  2443. <tr><td></td><td class="printindex-index-entry"><a href="#index-shape-agreement_002c-suffix">shape agreement, suffix</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-extension">Rank extension</a></td></tr>
  2444. <tr><td></td><td class="printindex-index-entry"><a href="#index-size"><code class="code">size</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2445. <tr><td></td><td class="printindex-index-entry"><a href="#index-sqr"><code class="code">sqr</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2446. <tr><td></td><td class="printindex-index-entry"><a href="#index-sqrm"><code class="code">sqrm</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2447. <tr><td></td><td class="printindex-index-entry"><a href="#index-start"><code class="code">start</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Compatibility">Compatibility</a></td></tr>
  2448. <tr><td></td><td class="printindex-index-entry"><a href="#index-start-1"><code class="code">start</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2449. <tr><td></td><td class="printindex-index-entry"><a href="#index-stencil"><code class="code">stencil</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2450. <tr><td></td><td class="printindex-index-entry"><a href="#index-step">step</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
  2451. <tr><td></td><td class="printindex-index-entry"><a href="#index-stride">stride</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
  2452. <tr><td></td><td class="printindex-index-entry"><a href="#index-sum"><code class="code">sum</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2453. <tr><td></td><td class="printindex-index-entry"><a href="#index-swap"><code class="code">swap</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2454. <tr><td colspan="4"> <hr></td></tr>
  2455. <tr><th id="Indices_cp_letter-T">T</th><td></td><td></td></tr>
  2456. <tr><td></td><td class="printindex-index-entry"><a href="#index-transpose"><code class="code">transpose</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2457. <tr><td colspan="4"> <hr></td></tr>
  2458. <tr><th id="Indices_cp_letter-U">U</th><td></td><td></td></tr>
  2459. <tr><td></td><td class="printindex-index-entry"><a href="#index-uninitialized-container">uninitialized container</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2460. <tr><td></td><td class="printindex-index-entry"><a href="#index-uninitialized-container-1">uninitialized container</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2461. <tr><td colspan="4"> <hr></td></tr>
  2462. <tr><th id="Indices_cp_letter-V">V</th><td></td><td></td></tr>
  2463. <tr><td></td><td class="printindex-index-entry"><a href="#index-view">view</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Containers-and-views">Containers and views</a></td></tr>
  2464. <tr><td></td><td class="printindex-index-entry"><a href="#index-view_002c-rank-0">view, rank 0</a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Slicing">Slicing</a></td></tr>
  2465. <tr><td colspan="4"> <hr></td></tr>
  2466. <tr><th id="Indices_cp_letter-W">W</th><td></td><td></td></tr>
  2467. <tr><td></td><td class="printindex-index-entry"><a href="#index-where"><code class="code">where</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2468. <tr><td></td><td class="printindex-index-entry"><a href="#index-withshape"><code class="code">withshape</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2469. <tr><td></td><td class="printindex-index-entry"><a href="#index-wrank"><code class="code">wrank</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2470. <tr><td colspan="4"> <hr></td></tr>
  2471. <tr><th id="Indices_cp_letter-X">X</th><td></td><td></td></tr>
  2472. <tr><td></td><td class="printindex-index-entry"><a href="#index-xI"><code class="code">xI</code></a>:</td><td>&nbsp;</td><td class="printindex-index-section"><a href="#Reference">Reference</a></td></tr>
  2473. <tr><td colspan="4"> <hr></td></tr>
  2474. </table>
  2475. <table class="cp-letters-footer-printindex"><tr><th>Jump to: &nbsp; </th><td><a class="summary-letter-printindex" href="#Indices_cp_letter-A"><b>A</b></a>
  2476. &nbsp;
  2477. <a class="summary-letter-printindex" href="#Indices_cp_letter-B"><b>B</b></a>
  2478. &nbsp;
  2479. <a class="summary-letter-printindex" href="#Indices_cp_letter-C"><b>C</b></a>
  2480. &nbsp;
  2481. <a class="summary-letter-printindex" href="#Indices_cp_letter-D"><b>D</b></a>
  2482. &nbsp;
  2483. <a class="summary-letter-printindex" href="#Indices_cp_letter-E"><b>E</b></a>
  2484. &nbsp;
  2485. <a class="summary-letter-printindex" href="#Indices_cp_letter-F"><b>F</b></a>
  2486. &nbsp;
  2487. <a class="summary-letter-printindex" href="#Indices_cp_letter-G"><b>G</b></a>
  2488. &nbsp;
  2489. <a class="summary-letter-printindex" href="#Indices_cp_letter-I"><b>I</b></a>
  2490. &nbsp;
  2491. <a class="summary-letter-printindex" href="#Indices_cp_letter-J"><b>J</b></a>
  2492. &nbsp;
  2493. <a class="summary-letter-printindex" href="#Indices_cp_letter-L"><b>L</b></a>
  2494. &nbsp;
  2495. <a class="summary-letter-printindex" href="#Indices_cp_letter-M"><b>M</b></a>
  2496. &nbsp;
  2497. <a class="summary-letter-printindex" href="#Indices_cp_letter-N"><b>N</b></a>
  2498. &nbsp;
  2499. <a class="summary-letter-printindex" href="#Indices_cp_letter-O"><b>O</b></a>
  2500. &nbsp;
  2501. <a class="summary-letter-printindex" href="#Indices_cp_letter-P"><b>P</b></a>
  2502. &nbsp;
  2503. <a class="summary-letter-printindex" href="#Indices_cp_letter-R"><b>R</b></a>
  2504. &nbsp;
  2505. <a class="summary-letter-printindex" href="#Indices_cp_letter-S"><b>S</b></a>
  2506. &nbsp;
  2507. <a class="summary-letter-printindex" href="#Indices_cp_letter-T"><b>T</b></a>
  2508. &nbsp;
  2509. <a class="summary-letter-printindex" href="#Indices_cp_letter-U"><b>U</b></a>
  2510. &nbsp;
  2511. <a class="summary-letter-printindex" href="#Indices_cp_letter-V"><b>V</b></a>
  2512. &nbsp;
  2513. <a class="summary-letter-printindex" href="#Indices_cp_letter-W"><b>W</b></a>
  2514. &nbsp;
  2515. <a class="summary-letter-printindex" href="#Indices_cp_letter-X"><b>X</b></a>
  2516. &nbsp;
  2517. </td></tr></table>
  2518. </div>
  2519. <hr>
  2520. </div>
  2521. <div class="unnumbered-level-extent" id="Notes">
  2522. <div class="nav-panel">
  2523. <p>
  2524. Previous: <a href="#Indices" accesskey="p" rel="prev">Indices</a>, Up: <a href="#Top" accesskey="u" rel="up"><code class="code">ra::</code></a> &nbsp; [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
  2525. </div>
  2526. <h2 class="unnumbered" id="Notes-1">Notes</h2>
  2527. <ol class="enumerate">
  2528. <li> <code class="code">ra::</code> uses the non standard <code class="code">#pragma once</code> (supported on all major compilers).
  2529. </li></ol>
  2530. </div>
  2531. </div>
  2532. <div class="footnotes-segment">
  2533. <hr>
  2534. <h4 class="footnotes-heading">Footnotes</h4>
  2535. <h5 class="footnote-body-heading"><a id="FOOT1" href="#DOCF1">(1)</a></h5>
  2536. <p>/ə&rsquo;ɹ-eɪ/, I guess.</p>
  2537. <h5 class="footnote-body-heading"><a id="FOOT2" href="#DOCF2">(2)</a></h5>
  2538. <p>Sometimes &lsquo;strides&rsquo;. Cf. <a class="url" href="https://en.wikipedia.org/wiki/Dope_vector"><em class="dfn">dope vector</em></a></p>
  2539. <h5 class="footnote-body-heading"><a id="FOOT3" href="#DOCF3">(3)</a></h5>
  2540. <p>This particular decision may be revisited in the future.</p>
  2541. <h5 class="footnote-body-heading"><a id="FOOT4" href="#DOCF4">(4)</a></h5>
  2542. <p>Examples given without context assume that one has declared <code class="code">using std::cout;</code>, etc.</p>
  2543. <h5 class="footnote-body-heading"><a id="FOOT5" href="#DOCF5">(5)</a></h5>
  2544. <p>Diagram generated using Graphviz and <a class="url" href="https://www.flourish.org/cinclude2dot">https://www.flourish.org/cinclude2dot</a>.
  2545. </p>
  2546. <pre class="verbatim">cd ra &amp;&amp; cinclude2dot.pl --include . &gt; headers.dot
  2547. dot -Tpng headers.dot -Gdpi=100 &gt; headers.png
  2548. </pre>
  2549. <h5 class="footnote-body-heading"><a id="FOOT6" href="#DOCF6">(6)</a></h5>
  2550. <p>The brace-list constructors of rank 2 and higher aren&rsquo;t supported on types of rt rank, because in the C++ grammar, a nested initializer list doesn&rsquo;t always define a rank unambiguously.</p>
  2551. <h5 class="footnote-body-heading"><a id="FOOT7" href="#DOCF7">(7)</a></h5>
  2552. <p>You can still use pointers or <code class="code">std::initializer_list</code>s for shape by wrapping them in the functions <code class="code">ptr</code> or <code class="code">vector</code>, respectively.</p>
  2553. <h5 class="footnote-body-heading"><a id="FOOT8" href="#DOCF8">(8)</a></h5>
  2554. <p>The brace-list constructors aren&rsquo;t rank extending, because giving the ravel is incompatible with rank extension. They are shape-strict —you must give every element.</p>
  2555. <h5 class="footnote-body-heading"><a id="FOOT9" href="#DOCF9">(9)</a></h5>
  2556. <p>Prefix agreement is chosen for <code class="code">ra::</code> because of the availability of a <a class="ref" href="#The-rank-conjunction">rank conjunction</a> [<a class="ref" href="#Sources">Ber87</a>]
  2557. and <a class="ref" href="#Cell-iteration">cell iterators of arbitrary rank</a>. This allows rank extension to be performed at multiple axes of an array expression.</p>
  2558. <h5 class="footnote-body-heading"><a id="FOOT10" href="#DOCF10">(10)</a></h5>
  2559. <p>The multi-argument square bracket form <code class="code">A[i₀, i₁, ...]</code> is supported under C++23 compilers (e.g. gcc ≥ 12 with <code class="code">-std=c++2b</code>), with the same meaning as <code class="code">A(i₀, i₁, ...)</code>. Under C++20 only a single-argument square bracket form <code class="code">A[i₀]</code> is available.</p>
  2560. <h5 class="footnote-body-heading"><a id="FOOT11" href="#DOCF11">(11)</a></h5>
  2561. <p>Currently, <code class="code">ra::len</code> can only be used in scalar expressions or <code class="code">ra::iota</code> expressions.</p>
  2562. <h5 class="footnote-body-heading"><a id="FOOT12" href="#DOCF12">(12)</a></h5>
  2563. <p>Simplified; see the references in <a class="url" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1170r0.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1170r0.html</a>.</p>
  2564. <h5 class="footnote-body-heading"><a id="FOOT13" href="#DOCF13">(13)</a></h5>
  2565. <p><code class="code">&amp;&amp;</code>, <code class="code">||</code> are short-circuiting as array operations; the elements of the second operand won&rsquo;t be evaluated if the elements of the first one evaluate to <code class="code">false</code> or <code class="code">true</code>, respectively.
  2566. Note that if both operands are of rank 0 and at least one of them is an <code class="code">ra::</code> object, they is no way to preserve the behavior of <code class="code">&amp;&amp;</code> and <code class="code">||</code> with built in types and avoid evaluating both, since the overloaded operators <a class="url" href="http://en.cppreference.com/w/cpp/language/operators">are normal functions</a>.</p>
  2567. </div>
  2568. <a href="js_licenses.html" rel="jslicense"><small>JavaScript license information</small></a>
  2569. </body>
  2570. </html>