123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!-- Created by GNU Texinfo 6.8, http://www.gnu.org/software/texinfo/ -->
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <!-- Version 1, updated 2023 January 5
- -->
- <title>newra — An alternative array library for Guile 3</title>
- <meta name="description" content="newra — An alternative array library for Guile 3">
- <meta name="keywords" content="newra — An alternative array library for Guile 3">
- <meta name="resource-type" content="document">
- <meta name="distribution" content="global">
- <meta name="Generator" content="makeinfo">
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <link href="#Top" rel="start" title="Top">
- <link href="#Indices" rel="index" title="Indices">
- <link href="#Introduction" rel="next" title="Introduction">
- <style type="text/css">
- <!--
- a.copiable-anchor {visibility: hidden; text-decoration: none; line-height: 0em}
- a.summary-letter {text-decoration: none}
- blockquote.indentedblock {margin-right: 0em}
- div.display {margin-left: 3.2em}
- div.example {margin-left: 3.2em}
- kbd {font-style: oblique}
- pre.display {font-family: inherit}
- pre.format {font-family: inherit}
- pre.menu-comment {font-family: serif}
- pre.menu-preformatted {font-family: serif}
- span.nolinebreak {white-space: nowrap}
- span.roman {font-family: initial; font-weight: normal}
- span.sansserif {font-family: sans-serif; font-weight: normal}
- span:hover a.copiable-anchor {visibility: visible}
- ul.no-bullet {list-style: none}
- -->
- </style>
- <script type='text/javascript'>
- MathJax = {
- options: {
- skipHtmlTags: {'[-]': ['pre']},
- ignoreHtmlClass: 'tex2jax_ignore',
- processHtmlClass: 'tex2jax_process'
- },
- };
- </script><script type="text/javascript" id="MathJax-script" async
- src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
- </script>
- </head>
- <body lang="en">
- <h1 class="settitle" align="center">newra — An alternative array library for Guile 3</h1>
- <div class="top" id="Top">
- <div class="header">
- <p>
- Next: <a href="#Introduction" accesskey="n" rel="next">Introduction</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="newra"></span><h1 class="top"><code>newra</code></h1>
- <p>Version 1, updated 2023 January 5
- <a id="DOCF1" href="#FOOT1"><sup>1</sup></a>
- </p>
- <p><code>newra</code> is a pure Scheme replacement for the built-in C-based array facility in Guile 3.0.
- </p>
- <p>This document uses ‘array’ to refer both to the old built-in array type and to the new type introduced in <code>newra</code>. The distinction is made as necessary.
- </p>
- <ul class="section-toc">
- <li><a href="#Introduction" accesskey="1">Introduction</a></li>
- <li><a href="#The-array-library" accesskey="2">The array library</a></li>
- <li><a href="#The-array-language" accesskey="3">The array language</a></li>
- <li><a href="#Hazards" accesskey="4">Hazards</a></li>
- <li><a href="#Reference" accesskey="5">Reference</a></li>
- <li><a href="#Cheatsheet" accesskey="6">Cheatsheet</a></li>
- <li><a href="#Sources" accesskey="7">Sources</a></li>
- <li><a href="#Indices" accesskey="8">Indices</a></li>
- </ul>
- <hr>
- <div class="chapter" id="Introduction">
- <div class="header">
- <p>
- Next: <a href="#The-array-library" accesskey="n" rel="next">The array library</a>, Previous: <a href="#Top" accesskey="p" rel="prev"><code>newra</code></a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Introduction-1"></span><h2 class="chapter">1 Introduction</h2>
- <span id="index-bounds"></span>
- <span id="index-view"></span>
- <p>A multidimensional array is a container (or rather a container <em>view</em>) whose elements can be looked up using a multi-index (i₀, i₁, ...). Each of the indices i₀, i₁, ... has constant bounds [l₀, h₀], [l₁, h₁], ... independent of the values of the other indices, so the array is ‘rectangular’. The number of indices in the multi-index is the <em>rank</em> of the array, and the list ([l₀ h₀] [l₁ h₁] ... [lᵣ₋₁ hᵣ₋₁]) is the <em>shape</em> of the array. We speak of a rank-<em class='tex2jax_process'>\(r\)</em> array or of an <em class='tex2jax_process'>\(r\)</em>-array.
- </p>
- <p>This is a 2-array with bounds [0, 2] on both axes:
- </p><pre class="verbatim">┌───────┬───────┬───────┐
- │A(0, 0)│A(0, 1)│A(0, 2)│
- ├───────┼───────┼───────┤
- │A(1, 0)│A(1, 1)│A(1, 2)│
- ├───────┼───────┼───────┤
- │A(2, 0)│A(2, 1)│A(2, 2)│
- └───────┴───────┴───────┘
- </pre>
- <p>This is a 3-array with bounds [0, 1] on axis 0, [2, 5] on axis 1, bounds [-2, 0] on axis 2:<a id="DOCF2" href="#FOOT2"><sup>2</sup></a>
- </p><pre class="verbatim">║───────────┬───────────┬──────────║───────────┬───────────┬──────────║
- ║A(0, 2, -2)│A(0, 2, -1)│A(0, 2, 0)║A(1, 2, -2)│A(1, 2, -1)│A(1, 2, 0)║
- ║───────────┼───────────┼──────────║───────────┼───────────┼──────────║
- ║A(0, 3, -2)│A(0, 3, -1)│A(0, 3, 0)║A(1, 3, -2)│A(1, 3, -1)│A(1, 3, 0)║
- ║───────────┼───────────┼──────────║───────────┼───────────┼──────────║
- ║A(0, 4, -2)│A(0, 4, -1)│A(0, 4, 0)║A(1, 4, -2)│A(1, 4, -1)│A(1, 4, 0)║
- ║───────────┼───────────┼──────────║───────────┼───────────┼──────────║
- ║A(0, 5, -2)│A(0, 5, -1)│A(0, 5, 0)║A(1, 5, -2)│A(1, 5, -1)│A(1, 5, 0)║
- ║───────────┴───────────┴──────────║───────────┴───────────┴──────────║
- </pre>
- <p>Sometimes we deal with multidimensional <em>expressions</em> where the elements aren’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. Such an array would be immutable.
- </p>
- <p>Arrays (in the form of <em>vectors</em>, <em>matrices</em>, or <em>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 — that is one of the main purposes of <code>newra</code>.
- </p>
- <p>The rest of this section discusses the motivation for <code>newra</code> in more detail. To start using the library, please jump ahead to <a href="#The-array-library">The array library</a>.
- </p>
- <ul class="section-toc">
- <li><a href="#Rank-polymorphism" accesskey="1">Rank polymorphism</a></li>
- <li><a href="#Rank-extension" accesskey="2">Rank extension</a></li>
- <li><a href="#The-pieces-of-an-array" accesskey="3">The pieces of an array</a></li>
- <li><a href="#Built_002din-Guile-arrays" accesskey="4">Built-in Guile arrays</a></li>
- </ul>
- <hr>
- <div class="section" id="Rank-polymorphism">
- <div class="header">
- <p>
- Next: <a href="#Rank-extension" accesskey="n" rel="next">Rank extension</a>, Up: <a href="#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Rank-polymorphism-1"></span><h3 class="section">1.1 Rank polymorphism</h3>
- <span id="index-rank-polymorphism"></span>
- <p><em>Rank polymorphism</em> is the ability to treat an array of rank <em class='tex2jax_process'>\(r\)</em> as an array of lower rank where the elements are themselves arrays.
- </p>
- <span id="index-cell"></span>
- <span id="index-frame"></span>
- <p>Think of a matrix A, a 2-array with lengths (l₀, l₁) where the elements A(i₀, i₁) are numbers. If we consider the subarrays (rows) A(0, ...), A(1, ...), ..., A(l₀-1, ...) as individual elements, then we have a new view of A as a 1-array of length l₀ with those rows as elements. We say that the rows A(i₀)≡A(i₀, ...) are the 1-<em>cells</em> of A, and the numbers A(i₀, i₁) are 0-cells of A. For an array of arbitrary rank <em class='tex2jax_process'>\(r\)</em> the (<em class='tex2jax_process'>\(r\)</em>-1)-cells of A are called its <em>items</em>. The prefix of the shape (l₀, l₁, ... lₙ₋₁₋ₖ) that is not taken up by the k-cell is called the (r-k)-<em>frame</em>.
- </p>
- <table>
- <tr><td width="40%"><pre class="verbatim">┌───────┬───────┬───────┐
- │A(0, 0)│A(0, 1)│A(0, 2)│
- ├───────┼───────┼───────┤
- │A(1, 0)│A(1, 1)│A(1, 2)│
- ├───────┼───────┼───────┤
- │A(2, 0)│A(2, 1)│A(2, 2)│
- └───────┴───────┴───────┘
- </pre></td><td width="10%">≡</td><td width="40%"><pre class="verbatim">────
- A(0)
- ────
- A(1)
- ────
- A(2)
- ────
- </pre></td></tr>
- </table>
- <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
- </p>
- <blockquote>
- <p>A: [A(0), A(1), ...]
- </p></blockquote>
- <p>and the items of A(i₀), etc. are in turn stored in the same way, so
- </p>
- <blockquote>
- <p>A: [A(0): [A(0, 0), A(0, 1) ...], ...]
- </p></blockquote>
- <p>and the same for the items of A(i₀, i₁), etc.
- </p>
- <blockquote>
- <p>A: [[A(0, 0): [A(0, 0, 0), A(0, 0, 1) ...], A(0, 1): [A(0, 1, 0), A(0, 1, 1) ...]], ...]
- </p></blockquote>
- <span id="index-order_002c-row_002dmajor"></span>
- <span id="index-order_002c-C"></span>
- <p>This way to lay out an array in memory is called <em>row-major order</em> or <em>C-order</em>, since it’s the default order for built-in arrays in C. A row-major array A with lengths (l₀, l₁, ... lᵣ₋₁) can be looked up like this:
- </p>
- <span id="x_002dsteps"></span><blockquote>
- <p>A(i₀, i₁, ...) = (storage-of-A) [(((i₀l₁ + i₁)l₂ + i₂)l₃ + ...)+iᵣ₋₁] = (storage-of-A) [o + s₀·i₀ + s₁·i₁ + ...]
- </p></blockquote>
- <p>where the numbers (s₀, s₁, ...) are called the <em>steps</em><a id="DOCF3" href="#FOOT3"><sup>3</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
- </p>
- <blockquote>
- <p>A ≡ ((storage-of-A), o, (s₀, s₁, ...))
- </p></blockquote>
- <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 very common operations such as: <a href="#x_002dra_002dtranspose">transposing</a> axes, <a href="#x_002dra_002dreverse">reversing</a> the order along an axis, most cases of <a href="#Slicing">slicing</a>, and sometimes even reshaping or tiling the array.
- </p>
- <p>A basic example is obtaining the i₀-th item of A:
- </p>
- <blockquote>
- <p>A(i₀) ≡ ((storage-of-A), o+s₀·i₀, (s₁, ...))
- </p></blockquote>
- <p>Note that we can iterate over these items by simply bumping the pointer o+s₀·i₀. This means that iterating over (k>0)-cells doesn’t have to cost any more than iterating over 0-cells (<a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>). Rank polymorphism isn’t just a high level property of arrays; it is enabled and supported by the way they are laid out in memory.
- </p>
- <hr>
- </div>
- <div class="section" id="Rank-extension">
- <div class="header">
- <p>
- Next: <a href="#The-pieces-of-an-array" accesskey="n" rel="next">The pieces of an array</a>, Previous: <a href="#Rank-polymorphism" accesskey="p" rel="prev">Rank polymorphism</a>, Up: <a href="#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Rank-extension-1"></span><h3 class="section">1.2 Rank extension</h3>
- <p>Rank extension is the mechanism that allows <code>R+S</code> to be defined even when <code>R</code>, <code>S</code> may have different ranks. The idea is an interpolation of the following basic cases.
- </p>
- <p>Suppose first that <code>R</code> and <code>S</code> have the same rank. We require that the shapes be the same. Then the shape of <code>R+S</code> will be the same as the shape of either <code>R</code> or <code>S</code> and the elements of <code>R+S</code> will be
- </p>
- <blockquote>
- <p><code>(R+S)(i₀ i₁ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ᵣ₋₁₎) + S(i₀ i₁ ... i₍ᵣ₋₁₎)</code>
- </p></blockquote>
- <p>where <code>r</code> is the rank of <code>R</code>.
- </p>
- <p>Now suppose that <code>S</code> has rank 0. The shape of <code>R+S</code> is the same as the shape of <code>R</code> and the elements of <code>R+S</code> will be
- </p>
- <blockquote>
- <p><code>(R+S)(i₀ i₁ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ᵣ₋₁₎) + S()</code>.
- </p></blockquote>
- <p>The two rules above are supported by all primitive array languages. But suppose that <code>S</code> has rank <code>s</code>, where <code>0<s<r</code>. Looking at the expressions above, it seems natural to define <code>R+S</code> by
- </p>
- <blockquote>
- <p><code>(R+S)(i₀ i₁ ... i₍ₛ₋₁₎ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ₛ₋₁₎ ... i₍ᵣ₋₁₎) + S(i₀ i₁ ... i₍ₛ₋₁₎)</code>.
- </p></blockquote>
- <p>That is, after we run out of indices in <code>S</code>, we simply repeat the elements. We have aligned the shapes so:
- </p>
- <blockquote>
- <pre class="verbatim">[n₀ n₁ ... n₍ₛ₋₁₎ ... n₍ᵣ₋₁₎]
- [n₀ n₁ ... n₍ₛ₋₁₎]
- </pre></blockquote>
- <span id="index-shape-agreement_002c-prefix"></span>
- <span id="index-shape-agreement_002c-suffix"></span>
- <span id="index-NumPy"></span>
- <p>This rank extension rule is used by the J language [<a href="#Sources">J S</a>]
- and is known as <em>prefix agreement</em>. The opposite rule of <em>suffix agreement</em> is used, for example, in NumPy [<a href="#Sources">num17</a>]
- .
- </p>
- <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>newra</code>, even in assignments. For example,
- </p>
- <div class="example">
- <pre class="verbatim">(define a (make-ra-root #(3 5 9)))
- (define b (make-ra #f 3 2))
- (ra-copy! b a) ; copy each aᵢ on each bᵢ
- </pre><pre class="example">⇒ <code>#%2:3:2((3 3) (5 5) (9 9))</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(define a (make-ra 0 3))
- (define b (ra-reshape (ra-iota 6 1) 0 3 2))
- (ra-map! a + a b) ; sum the rows of b
- </pre><pre class="example">⇒ <code>#%1:3(3 7 11)</code>
- </pre></div>
- <span id="index-NumPy-1"></span>
- <span id="index-broadcasting_002c-singleton_002c-newaxis"></span>
- <p>A weakness of prefix agreement is that the axes you want to match aren’t always the prefix axes. Other array systems (e.g. [<a href="#Sources">num17</a>]
- ) offer a feature similar to rank extension called ‘broadcasting’ that is a bit more flexible. For example an array of shape [A B 1 D] will match an array of shape [A B C D] for any value of C. The process of broadcasting consists in inserting so-called ‘singleton dimensions’ (axes with length one) to align the axes that one wishes to match. One may think of rank extension as a particular case of broadcasting where the singleton dimensions are added to the end of the shorter shapes automatically.
- </p>
- <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 error, it isn’t obvious why 1≠2 shouldn’t be. For this reason <code>newra</code>’s support for explicit broadcasting is based on <a href="#x_002ddead_002daxes">dead axes</a>.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (ra-i 5 3))
- (define b (make-ra 0 3))
- (let ((b1 (ra-transpose b 1))) ; align axis 0 of b with axis 1 of a
- (ra-map! b1 + b1 a) ; sum the columns of a
- b)
- </pre><pre class="example">⇒ b = <code>#%1:5(30 35 40)</code>
- </pre></div>
- <hr>
- </div>
- <div class="section" id="The-pieces-of-an-array">
- <div class="header">
- <p>
- Next: <a href="#Built_002din-Guile-arrays" accesskey="n" rel="next">Built-in Guile arrays</a>, Previous: <a href="#Rank-extension" accesskey="p" rel="prev">Rank extension</a>, Up: <a href="#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="The-pieces-of-an-array-1"></span><h3 class="section">1.3 The pieces of an array</h3>
- <p>A <code>newra</code> array is an aggregate of the following pieces:
- </p>
- <span id="index-rank"></span>
- <span id="index-dim-vector"></span>
- <span id="index-root-vector"></span>
- <ul>
- <li> A <em>root vector</em>, or root for short.
- This can be a Scheme vector, as well as one of several other vector-like types.
- </li><li> A <em>zero</em>.
- An arbitary integer.
- </li><li> A <em>dim vector</em>.
- Each dim consists of a length (<em>len</em>), a lower bound (<em>lo</em>), and a <em>step</em>. The length of the dim vector is the <em>rank</em> of the array.
- </li></ul>
- <span id="index-view-1"></span>
- <p>Together, the dim vector and the zero define an affine function of array indices <code>i₀, i₁, ...</code> that produces an index into the root. Thus, the array is a multidimensional view of the root.
- </p>
- <p>For example, the following pieces
- </p>
- <ul>
- <li> root: v = <code>#(1 2 3 4 5 6 7)</code>
- </li><li> zero: 1
- </li><li> dims: <code>#(#<<dim> len: 2 lo: 0 step: 2> #<<dim> len: 2 lo: 0 step: 1>)</code>
- </li></ul>
- <p>define an array A(i₀, i₁) = v(1 + 2·i₀ + 1·i₁), 0≤i₀<2, 0≤i₁<2, that is A = [[2 3] [4 5]].
- </p>
- <p>In <code>newra</code> code,
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra-root (vector 1 2 3 4 5 6 7) 1 (vector (make-dim 2 0 2) (make-dim 2 0 1)))
- </pre><pre class="example">⇒ <code>#%2:2:2((2 3) (4 5))</code>
- </pre></div>
- <p>The default print style means <code>#%RANK:LEN₀:LEN₁(...)</code> (<a href="#Writing-and-reading">Writing and reading</a>).
- </p>
- <p>It’s unusual to need to specify the dims directly. More commonly, one creates an array of whatever size
- </p>
- <div class="example">
- <pre class="verbatim">> (define a (make-ra #f 3 4))
- > a
- </pre><pre class="example">⇒ <code>#%2:3:4((#f #f #f #f) (#f #f #f #f) (#f #f #f #f))</code>
- </pre></div>
- <p>which automatically creates a root of the required size, so that all the array elements are distinct. Then one operates on the array without making reference to the underlying root,
- </p>
- <div class="example">
- <pre class="verbatim">> (ra-set! a 99 2 2)
- </pre><pre class="example">⇒ <code>#%2:3:4((#f #f #f #f) (#f #f 99 #f) (#f #f #f #f))</code>
- </pre></div>
- <p>Still, since the array is just a view of the root, any changes on the array are reflected there as well
- </p>
- <div class="example">
- <pre class="verbatim">> (ra-root a)
- </pre><pre class="example">⇒ <code>#(#f #f #f #f #f #f #f #f #f #f 99 #f)</code>
- </pre></div>
- <p>and the other way around,
- </p>
- <div class="example">
- <pre class="verbatim">> (define b (make-ra-root (vector 'x) 0 (vector (make-dim 3 0 0) (make-dim 2 0 0))))
- > b
- </pre><pre class="example">⇒ <code>#%2:3:2((x x) (x x) (x x))</code>
- </pre><pre class="verbatim">> (vector-set! (ra-root b) 0 'Z)
- > b
- </pre><pre class="example">⇒ <code>#%2:3:2((Z Z) (Z Z) (Z Z))</code>
- </pre></div>
- <span id="index-shared-root"></span>
- <span id="index-new-array"></span>
- <p>It is often important to know whether an operation on an array returns a different view of its argument, or instead it allocates a new root which can be modified without affecting the original argument. When we say that a function ‘creates a new array’, we mean that it allocates a new root.
- </p>
- <p>Generally a given function will always do one or the other, e.g. the result of <a href="#x_002dra_002dtile"><code>ra-tile</code></a> always shares the root of its argument, while <a href="#x_002dra_002dcopy"><code>ra-copy</code></a> always creates a new array. Some functions, like <a href="#x_002dra_002dravel"><code>ra-ravel</code></a> or <a href="#x_002dra_002dfrom"><code>ra-from</code></a>, may do either, depending on their arguments. For example, the result of
- </p>
- <div class="example">
- <pre class="verbatim">(ra-ravel (ra-iota 3 4))
- </pre><pre class="example">⇒ <code>#%1d:12(0 1 2 3 4 5 6 7 8 9 10 11)</code>
- </pre></div>
- <p>shares the root of <code>(ra-iota 3 4)</code>, but
- </p>
- <div class="example">
- <pre class="verbatim">(ra-ravel (ra-transpose (ra-iota 3 4) 1 0))
- </pre><pre class="example">⇒ <code>#%1:12(0 4 8 1 5 9 2 6 10 3 7 11)</code>
- </pre></div>
- <p>doesn’t.
- </p>
- <hr>
- </div>
- <div class="section" id="Built_002din-Guile-arrays">
- <div class="header">
- <p>
- Previous: <a href="#The-pieces-of-an-array" accesskey="p" rel="prev">The pieces of an array</a>, Up: <a href="#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Built_002din-Guile-arrays-1"></span><h3 class="section">1.4 Built-in Guile arrays</h3>
- <p>Dense multidimensional arrays work similarly in every language that offers them, and built-in Guile arrays are no different — they also have a root (<code>shared-array-root</code>), a zero (computable from <code>shared-array-offset</code> and <code>array-shape</code>), and a dim vector (<code>array-shape</code>, <code>shared-array-increments</code>). Functionally, they are entirely equivalent to the objects offered by <code>newra</code>. Why replace them?
- </p>
- <span id="index-libguile"></span>
- <p>Built-in Guile arrays are implemented in C, as part of libguile. As a Guile type they have their own low-level type tag, and all the basic array operations are C stubs, even the most basic functions such as <code>array-ref</code> or <code>array-rank</code>. Obtaining any of the components of the array requires calling into C. There are several problems with this.
- </p>
- <p>First, the built-in library offers a single function to manipulate array dims, <code>make-shared-array</code>. Although this is a sufficient interface, it is excessively generic, and also very cumbersome and inefficient. The array dims cannot be manipulated directly from Scheme, so any alternative interface written in Scheme is forced to go through <code>make-shared-array</code>.
- </p>
- <p>Second, the C stubs create a barrier to optimization by the Scheme compiler. The main loop of an operation such as <code>(array-map! c + a b)</code> has to be implemented in C (for the reasons given above) and then it has to call back to Scheme on each iteration in order to apply <code>+</code>. Since the Scheme compiler doesn’t have any special support for <code>array-map!</code>, it doesn’t know what the types of the arguments are, etc. and those checks and dispatches are repeated over and over. <a id="DOCF4" href="#FOOT4"><sup>4</sup></a>
- </p>
- <p>Third, some of the the larger functions of the array interface, such as <code>array-map!</code>, etc. are not interruptible. This is especially inconvenient when operating on large arrays.
- </p>
- <p>These problems are solved if the built-in type is replaced with a new type defined in Scheme.
- </p>
- <hr>
- </div>
- </div>
- <div class="chapter" id="The-array-library">
- <div class="header">
- <p>
- Next: <a href="#The-array-language" accesskey="n" rel="next">The array language</a>, Previous: <a href="#Introduction" accesskey="p" rel="prev">Introduction</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="The-array-library-1"></span><h2 class="chapter">2 The array library</h2>
- <ul class="section-toc">
- <li><a href="#Creating-and-accessing-arrays" accesskey="1">Creating and accessing arrays</a></li>
- <li><a href="#Special-arrays" accesskey="2">Special arrays</a></li>
- <li><a href="#Writing-and-reading" accesskey="3">Writing and reading</a></li>
- <li><a href="#Iteration" accesskey="4">Iteration</a></li>
- <li><a href="#Slicing" accesskey="5">Slicing</a></li>
- <li><a href="#Reshaping" accesskey="6">Reshaping</a></li>
- <li><a href="#Concatenation" accesskey="7">Concatenation</a></li>
- <li><a href="#Transposition" accesskey="8">Transposition</a></li>
- <li><a href="#Other-operations-on-arrays" accesskey="9">Other operations on arrays</a></li>
- <li><a href="#Automatic-result-arrays">Automatic result arrays</a></li>
- <li><a href="#Foreign-interface">Foreign interface</a></li>
- <li><a href="#Compatibility-with-old-Guile-arrays">Compatibility with old Guile arrays</a></li>
- </ul>
- <hr>
- <div class="section" id="Creating-and-accessing-arrays">
- <div class="header">
- <p>
- Next: <a href="#Special-arrays" accesskey="n" rel="next">Special arrays</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Creating-and-accessing-arrays-1"></span><h3 class="section">2.1 Creating and accessing arrays</h3>
- <p>An array can be created anew (<a href="#x_002dmake_002dra_002dnew"><code>make-ra-new</code></a>, <a href="#x_002dmake_002dra"><code>make-ra</code></a>, <a href="#x_002dmake_002dtyped_002dra"><code>make-typed-ra</code></a>), or over an existing root (<a href="#x_002dmake_002dra_002droot"><code>make-ra-root</code></a>).
- </p>
- <p><a href="#x_002dmake_002dra"><code>make-ra</code></a> or <a href="#x_002dmake_002dtyped_002dra"><code>make-typed-ra</code></a> take a fill element and array lengths and use row-major order by default. The fill element may be <code>*unspecified*</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra 99 2 3)
- </pre><pre class="example">⇒ #%2:3:2((9 9) (9 9) (9 9))
- </pre></div>
- <div class="example">
- <pre class="verbatim">(make-typed-ra 's16 *unspecified* 2 3)
- </pre><pre class="example">⇒ #%2s16:2:3((26414 26997 25964) (24878 26994 26996)) ; likely different values
- </pre></div>
- <p>The functions <code>make-ra-new</code> and <code>make-ra-root</code> are lower level. <a href="#x_002dmake_002dra_002dnew"><code>make-ra-new</code></a> takes an array type, a fill value, and a dim vector. <a href="#x_002dc_002ddims"><code>c-dims</code></a> can be used to create a row-major dim vector.
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra-new #t 'x (vector (make-dim 3 0 2) (make-dim 2 0 1)))
- (make-ra-new #t 'x (c-dims 3 2)) ; more simply
- </pre><pre class="example">⇒ #%2:3:2((x x) (x x) (x x))
- </pre></div>
- <div class="example">
- <pre class="verbatim">(make-ra-new 'f32 0.0 (c-dims 3 2))
- </pre><pre class="example">⇒ #%2f32:3:2((0.0 0.0) (0.0 0.0) (0.0 0.0))
- </pre></div>
- <p><a href="#x_002dmake_002dra_002droot"><code>make-ra-root</code></a> takes the type from the root.
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra-root (vector 1 2 3 4 5 6) (c-dims 3 2))
- </pre><pre class="example">⇒ #%2:3:2((1 2) (3 4) (5 6))
- </pre></div>
- <p>The default dims produce a view of the root as is (rank 1, zero offset, same length)<a id="DOCF5" href="#FOOT5"><sup>5</sup></a>.
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra-root (vector 1 2 3 4 5 6))
- </pre><pre class="example">⇒ #%1:6(1 2 3 4 5 6)
- </pre></div>
- <span id="index-applicative"></span>
- <p><code>newra</code> arrays are applicative; to look up or assign an element of an array, use it as a function of the indices.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (make-ra #f 3 2))
- (set! (a 0 0) 9)
- (set! (a 1 1) 3)
- </pre><pre class="example">⇒ #%2:3:4((9 #f) (#f 3) (#f #f))
- </pre><pre class="verbatim">(a 0 0)
- </pre><pre class="example">⇒ 9
- </pre></div>
- <span id="index-prefix-slice"></span>
- <p>If you give fewer indices than the rank, you get a prefix slice. This slice shares the root of the original array.
- </p>
- <div class="example">
- <pre class="verbatim">(a 1)
- </pre><pre class="example">⇒ #%1:2(#f 3)
- </pre><pre class="verbatim">(set! ((a 1) 0) 'b)
- </pre><pre class="example">⇒ #%1:2(b 3)
- </pre><pre class="verbatim">a
- </pre><pre class="example">⇒ #%2:3:4((9 #f) (b 3) (#f #f))
- </pre></div>
- <p>Generalized indices are handled as in <a href="#x_002dra_002dfrom"><code>ra-from</code></a>:
- </p>
- <div class="example">
- <pre class="verbatim">((ra-i 3 4) #t 1) ; second column
- </pre><pre class="example">⇒ #%1d:3(1 5 9)
- </pre></div>
- <p>You can also access arrays in the more usual way with the functions <a href="#x_002dra_002dref"><code>ra-ref</code></a> and <a href="#x_002dra_002dset_0021"><code>ra-set!</code></a>. See <a href="#Slicing">Slicing</a> for all the options.
- </p>
- <hr>
- </div>
- <div class="section" id="Special-arrays">
- <div class="header">
- <p>
- Next: <a href="#Writing-and-reading" accesskey="n" rel="next">Writing and reading</a>, Previous: <a href="#Creating-and-accessing-arrays" accesskey="p" rel="prev">Creating and accessing arrays</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Special-arrays-1"></span><h3 class="section">2.2 Special arrays</h3>
- <p>Any type that is usable as the root of an old built-in Guile array is also usable as root of a <code>newra</code> array. These include
- </p>
- <ul>
- <li> vectors, like <code>(vector 3)</code>
- </li><li> SRFI-4 typed vectors, like <code>(c64vector 1 2+0i)</code>
- </li><li> strings, like <code>"hello"</code>
- </li><li> bitvectors, like <code>(bitvector #f #t #f #t)</code>
- </li></ul>
- <p><code>newra</code> supports an additional root type, <code><aseq></code>, representing an unbounded arithmetic sequence.
- </p>
- <span id="index-make_002daseq"></span>
- <span id="x_002dnone"></span><dl class="def">
- <dt id="index-make_002daseq-1"><span class="category">Function<!-- /@w -->: </span><span><strong>make-aseq</strong> <em>[org [inc]]</em><a href='#index-make_002daseq-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Create an arithmetic sequence [<code>org, org+inc, org+2·inc, ...</code>]. The default values of <code>org</code> and <code>inc</code> are respectively 0 and 1. For example:
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra-root (make-aseq 0 3) (vector (make-dim 10)) 0)
- </pre><pre class="example">⇒ #%1d:10(0 3 6 9 12 15 18 21 24 27)
- </pre></div>
- <p>This can be written more succinctly as <code>(<a href="#x_002dra_002diota">ra-iota</a> 10 0 3)</code>.
- </p></dd></dl>
- <span id="index-d"></span>
- <p><code>aseq</code> roots are immutable. The type tag of <code>aseq</code> roots is <code>d</code>. Arrays with integer-valued <code>aseq</code> roots have some special uses; one of them is as arguments in <a href="#Slicing">slicing</a>.
- </p>
- <span id="index-infinite-axes"></span>
- <span id="index-unbounded-axes"></span>
- <p>To make <code><aseq></code> even more useful, <code>newra</code> supports unbounded axes.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-ref (make-ra-root (make-aseq) (vector (make-dim #f)) 0) #e1e12) ; or more simply
- (ra-ref (ra-iota) #e1e12)
- </pre><pre class="example">⇒ 1000000000000
- </pre></div>
- <p>These are treated especially when used in iteration (<a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>), in that they match axes of any finite length. Effectively this lets one use <code>(<a href="#x_002dra_002dtranspose"><code>ra-transpose</code></a> (ra-iota) k)</code> as a placeholder for the index over axis <code>k</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-map! (make-ra 0 3) + (ra-iota 3) (ra-iota))
- </pre><pre class="example">⇒ #1%3(0 2 4)
- </pre></div>
- <span id="index-dead-axes"></span>
- <span id="x_002ddead_002daxes"></span><p><code>newra</code> also supports ‘dead axes’, which are axes with step 0 and undefined length. These axes can match axes of any length and can exist on arrays of any type, not only on arrays of type <code>d</code>, because effectively only one position (the lower bound) is ever accessed.
- </p>
- <span id="index-singleton-axis"></span>
- <p>Dead axes operate essentially as ‘singleton axes’ do in other array languages. The main diference is that the ability to match any finite length is explicit; an axis with length 1 will still fail to match an axis with length 2 (say).
- </p>
- <p>Some functions work by creating axes with step 0, usually with defined lengths.
- </p>
- <div class="example">
- <pre class="verbatim">(define A (make-ra-root #(1 2 3) (c-dims 3)))
- (ra-tile A 0 2 2)
- </pre><pre class="example">⇒ #%3d:2:2:3(((0 1 2) (0 1 2)) ((0 1 2) (0 1 2)))
- </pre><pre class="verbatim">(ra-dims (ra-tile A 0 2 2))
- </pre><pre class="example">⇒ #(#<<dim> len: 2 lo: 0 step: 0> #<<dim> len: 2 lo: 0 step: 0> #<<dim> len: 3 lo: 0 step: 1>)
- </pre></div>
- <hr>
- </div>
- <div class="section" id="Writing-and-reading">
- <div class="header">
- <p>
- Next: <a href="#Iteration" accesskey="n" rel="next">Iteration</a>, Previous: <a href="#Special-arrays" accesskey="p" rel="prev">Special arrays</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Writing-and-reading-1"></span><h3 class="section">2.3 Writing and reading</h3>
- <p>The read syntax for arrays is <a href="https://www.gnu.org/software/guile/manual/html_node/Array-Syntax.html">the same</a> as for built-in Guile arrays, except that <code>#%</code> is used instead of <code>#</code>. Full dimensions are printed by default, even when they are not required to read an array.
- </p>
- <div class="example">
- <pre class="verbatim">(call-with-input-string "#%1(2 2 2)" read)
- </pre><pre class="example">⇒ <code>#%1:3(2 2 2)</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(call-with-input-string "#%1:3(2 2 2)" read)
- </pre><pre class="example">⇒ <code>#%1:3(2 2 2)</code>
- </pre></div>
- <p>Dead axes print as <code>d</code>, and unbounded (not dead) axes print as <code>f</code>. These cannot be read back.
- </p>
- <div class="example">
- <pre class="verbatim">(display (ra-transpose (ra-copy (ra-iota 3)) 1))
- </pre><pre class="example">⇒ <code>#%2:d:3((0 1 2))</code>
- </pre></div>
- <p>Arrays with root of type <code>d</code> cannot be read back either.
- </p>
- <div class="example">
- <pre class="verbatim">(define s (format #f "~a" (ra-i 2 3)))
- s
- </pre><pre class="example">⇒ <code>"#%2d:2:3((0 1 2) (3 4 5))"</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(call-with-input-string s read)
- </pre><pre class="example">⇒ error: cannot make array of type d
- </pre></div>
- <p>Truncated output is not supported yet.
- </p>
- <div class="example">
- <pre class="verbatim">(format #f "~@y" (ra-i 2 3))
- </pre><pre class="example">⇒ <code>"#%2d:2:3((0 1 2) (3 4 5))"</code> ; ok, but we didn't need to truncate
- </pre></div>
- <div class="example">
- <pre class="verbatim">(format #f "~@y" (ra-i 99 99))
- </pre><pre class="example">⇒ <code>"#" ; ouch</code>
- </pre></div>
- <p>The function <a href="#x_002dra_002dformat"><code>ra-format</code></a> can be used to pretty print arrays. This type of output cannot be read back, either.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (list->ra 2 '((1 hello) ("try" 2) (never 3.14))) #:fmt "~s")
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2:3:2─────┐
- │ 1│hello│
- ├─────┼─────┤
- │"try"│ 2│
- ├─────┼─────┤
- │never│ 3.14│
- └─────┴─────┘
- </pre></div>
- <p>The writing mode can be configured with the following parameter.
- </p>
- <span id="index-_002ara_002dprint_002a"></span>
- <span id="x_002dstar_002dra_002dprint_002dstar"></span><dl class="def">
- <dt id="index-_002ara_002dprint_002a-1"><span class="category">Parameter<!-- /@w -->: </span><span><strong>*ra-print*</strong> <em>(λ (array port) ...)</em><a href='#index-_002ara_002dprint_002a-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Set the default printer for arrays. This parameter is available from <code>(newra print)</code>.
- </p>
- <span id="index-box"></span>
- <span id="index-box1"></span>
- <span id="index-box2"></span>
- <span id="index-default"></span>
- <p>The parameter can be set to a function <code>(λ (array port) ...)</code> or to one of the values <code>#f</code>, <code>'default</code>, <code>'box</code>, <code>'box1</code>, or <code>'box2</code>.
- </p>
- <p>For example
- </p><div class="example">
- <pre class="verbatim">(import (newra print))
- (*ra-print* (λ (ra o) (ra-print ra o #:dims? #f)))
- (ra-i 2 3)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">$1 = #%2d((0 1 2) (3 4 5))
- </pre></div>
- <p>or
- </p>
- <div class="example">
- <pre class="verbatim">(*ra-print* (λ (ra o) (newline o) (ra-format ra o)))
- ; (*ra-print* 'box) ; same thing
- (ra-i 2 3)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">$1 =
- #%2d:2:3
- │0│1│2│
- ├─┼─┼─┤
- │3│4│5│
- └─┴─┴─┘
- </pre></div>
- <p>The options <code>'box1</code> and <code>'box2</code> use <a href="#x_002dra_002dformat"><code>ra-format</code></a> like <code>'box</code> but pass 1 or 2 to the <code>#:compact</code> argument.
- </p>
- <p>The default printer can be reset with <code>(*ra-print* #f)</code> or <code>(*ra-print* 'default)</code>.
- </p></dd></dl>
- <span id="index-SRFI_002d163"></span>
- <p>By default, rank-0 arrays are printed like the built-in Guile arrays, with extra parentheses around the content. In the read syntax specified in [<a href="#Sources">SRFI-163</a>]
- , those parentheses are not used. The following parameter allows one to choose either behavior for both the printer and the reader.
- </p>
- <span id="index-_002ara_002dparenthesized_002drank_002dzero_002a"></span>
- <span id="x_002dstar_002dra_002dparenthesized_002drank_002dzero_002dstar"></span><dl class="def">
- <dt id="index-_002ara_002dparenthesized_002drank_002dzero_002a-1"><span class="category">Parameter<!-- /@w -->: </span><span><strong>*ra-parenthesized-rank-zero*</strong> <em>boolean</em><a href='#index-_002ara_002dparenthesized_002drank_002dzero_002a-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Control read syntax of rank-0 arrays. This parameter is available from <code>(newra print)</code> or <code>(newra read)</code>.
- </p>
- <p>If <code>(*ra-parenthesized-rank-zero*)</code> is true, the read syntax for rank-0 arrays is
- </p>
- <div class="display">
- <pre class="display"><code>#%0TYPE(item)</code>
- </pre></div>
- <p>If it is <code>#f</code>, it is
- </p>
- <div class="display">
- <pre class="display"><code>#%0TYPE item</code>
- </pre></div>
- <p>with <code>TYPE</code> being optional in either case. Note that these are not compatible:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-ref (parameterize ((*ra-parenthesized-rank-zero* #t))
- (call-with-input-string "#%0(a)" read)))
- </pre><pre class="example">⇒ <code>a</code>
- </pre><pre class="verbatim">(ra-ref (parameterize ((*ra-parenthesized-rank-zero* #f))
- (call-with-input-string "#%0(a)" read)))
- </pre><pre class="example">⇒ <code>(a)</code>
- </pre><pre class="verbatim">(ra-ref (parameterize ((*ra-parenthesized-rank-zero* #f))
- (call-with-input-string "#%0 a" read)))
- </pre><pre class="example">⇒ <code>a</code>
- </pre></div>
- <p>In the last example, the space is necessary (unlike in [<a href="#Sources">SRFI-163</a>]
- ) since the array type tag is optional in Guile.
- </p>
- <div class="example">
- <pre class="verbatim">(parameterize ((*ra-parenthesized-rank-zero* #f))
- (call-with-input-string "#%0a" read))
- </pre><pre class="example">⇒ Wrong type (expecting character): #<eof>
- </pre></div>
- <p>The printer always uses a space in this mode:
- </p>
- <div class="example">
- <pre class="verbatim">(parameterize ((*ra-parenthesized-rank-zero* #f))
- (display (make-ra '(a))))
- </pre><pre class="example">⇒ <code>#%0 (a)</code>
- </pre></div>
- <p>Note that setting this parameter to <code>#f</code> still doesn’t make the array read syntax fully compatible with that of [<a href="#Sources">SRFI-163</a>]
- , since the type tag <code>a</code> is reserved (in Guile) for character arrays.
- </p>
- <p>The default value of this parameter is <code>#t</code>.
- </p>
- </dd></dl>
- <hr>
- </div>
- <div class="section" id="Iteration">
- <div class="header">
- <p>
- Next: <a href="#Slicing" accesskey="n" rel="next">Slicing</a>, Previous: <a href="#Writing-and-reading" accesskey="p" rel="prev">Writing and reading</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Iteration-1"></span><h3 class="section">2.4 Iteration</h3>
- <p>The basic array iteration operations in <code>newra</code> all operate by effect. This gives you control of how the result is allocated. If one of the arguments is designated as destination, as is the case with <a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>, then that is the result of the whole iteration. For example:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-map! (make-ra #f 3) - (ra-iota 3 1))
- </pre><pre class="example">⇒ #%1:3(-1 -2 -3)
- </pre></div>
- <p>It is common to need the indices of the elements during array iteration. <code>newra</code> iteration operations do not keep track of those indices<a id="DOCF6" href="#FOOT6"><sup>6</sup></a> because that has a cost. You need to pass the indices you need as arguments, but it’s easy to do so by using an unbounded index vector together with <a href="#x_002dra_002dtranspose"><code>ra-transpose</code></a>.
- </p>
- <div class="example">
- <pre class="verbatim">(define i0 (ra-iota))
- (define i1 (ra-transpose (ra-iota) 1))
- (ra-map! (make-ra #f 2 2) list (list->ra 2 '((A B) (C D))) i0 i1)
- </pre><pre class="example">⇒ #%2:2:2(((A 0 0) (B 0 1)) ((C 1 0) (D 1 1)))
- </pre></div>
- <p>One can iterate not only over the whole array, but also over any <code>n</code>-frame (the first <code>n</code> axes of an array), using <a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>. In this case the operation takes array slices as arguments, even when they are of rank 0; this allows writing to any of the arguments. When there are several arrays involved, all the frames must match.
- </p>
- <p>In the following example, <code>xys</code> is of rank 2, <code>angle</code> is of rank 1, and their first axes have the same length.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-slice-for-each 1
- (λ (xy angle)
- ; inside the op, xy is rank 1, angle is rank 0
- (ra-set! angle (atan (ra-ref xy 1) (ra-ref xy 0))))
- xys angles)
- </pre></div>
- <span id="index-prefix-matching"></span>
- <p>The iteration procedures in <code>newra</code> all perform rank extension of their arguments through prefix matching (see <a href="#Rank-extension">Rank extension</a>). In the following example, the shapes of the arguments are (5 5), (5) and (<code>#f</code> 5), and the common prefixes all match.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-map! (make-ra 5 5) * (ra-iota 5 1) (ra-transpose (ra-iota 5 1) 1))
- </pre><pre class="example">⇒ <code>#%2:5:5((1 2 3 4 5) (2 4 6 8 10) (3 6 9 12 15) (4 8 12 16 20) (5 10 15 20 25))</code>
- </pre></div>
- <p>Another example using <a href="#x_002dra_002dcopy_0021"><code>ra-copy!</code></a>,
- </p>
- <div class="example">
- <pre class="verbatim">(ra-copy! (list->ra 2 '((a b) (p q) (x y)))
- (list->ra 1 '(1 2 3)))
- </pre><pre class="example">⇒ <code>#%2:3:2((1 1) (2 2) (3 3))</code>
- </pre></div>
- <hr>
- </div>
- <div class="section" id="Slicing">
- <div class="header">
- <p>
- Next: <a href="#Reshaping" accesskey="n" rel="next">Reshaping</a>, Previous: <a href="#Iteration" accesskey="p" rel="prev">Iteration</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Slicing-1"></span><h3 class="section">2.5 Slicing</h3>
- <p>Slicing refers to the operation of taking a partial view of an array (e.g. a row or a column out of a matrix) through modification of the dim vector. This can be done with creative uses of <a href="#x_002dra_002dravel"><code>ra-ravel</code></a>, <a href="#x_002dra_002dreshape"><code>ra-reshape</code></a> and <a href="#x_002dra_002dtranspose"><code>ra-transpose</code></a>, and of course by direct modification of the dim vector, but the facilities described in this section are usually a lot clearer.
- </p>
- <span id="index-prefix-slice-1"></span>
- <p>The simplest form of slicing uses <a href="#x_002dra_002dslice">ra-slice</a> to produce ‘prefix slices’.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (list->ra 3 '(((a b) (x y)) ((A B) (X Y)))))
- </pre><pre class="example">⇒ <code>#%3:2:2:2(((a b) (x y)) ((A B) (X Y)))</code>
- </pre><pre class="verbatim">(ra-slice a 0 1 0)
- </pre><pre class="example">⇒ <code>#%0(x)</code>
- </pre><pre class="verbatim">(ra-slice a 0 1)
- </pre><pre class="example">⇒ <code>#%1:2(x y)</code>
- </pre><pre class="verbatim">(ra-slice a 0)
- </pre><pre class="example">⇒ <code>#%2:2:2((a b) (x y))</code>
- </pre><pre class="verbatim">(ra-slice a)
- </pre><pre class="example">⇒ <code>#%3:2:2:2(((a b) (x y)) ((A B) (X Y)))</code>
- </pre></div>
- <p>The prefix slice always shares the root of the source array, so it can be used to modify the source array.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-fill! (ra-slice a 1 0) '99)
- </pre><pre class="example">⇒ <code>#%1:2(99 99)</code>
- </pre><pre class="verbatim">a
- </pre><pre class="example">⇒ <code>#%3:2:2:2(((a b) (x y)) ((99 99) (X Y)))</code>
- </pre></div>
- <p>The variant <a href="#x_002dra_002dcell"><code>ra-cell</code></a> is identical to <code>ra-slice</code> except that it returns an element (and not a rank 0 array) when the full set of indices is given.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-slice a 0 1 0)
- </pre><pre class="example">⇒ <code>x</code>
- </pre></div>
- <p><code>ra-cell</code> is a <a href="#Rank-polymorphism">rank-polymorphic</a> generalization of the basic element lookup function <a href="#x_002dra_002dref"><code>ra-ref</code></a>, which requires the full set of indices.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-ref a 0 1 0) ; same as ra-cell
- </pre><pre class="example">⇒ <code>x</code>
- </pre><pre class="verbatim">(ra-ref a 0 1)
- </pre><pre class="example">⇒ <code>"<unnamed port>":...: Throw to key `bad-number-of-indices' with args `(3 2)'.</code>
- </pre></div>
- <p>Both <code>ra-cell</code> and <code>ra-slice</code> (and <code>ra-ref</code>) take scalar indices as arguments. The more powerful function <a href="#x_002dra_002dfrom"><code>ra-from</code></a> is able to handle arrays of indices.
- </p>
- <span id="index-_007b_002c-from"></span>
- <blockquote>
- <pre class="verbatim">(ra-from a i₀ ...) ⇒ b
- </pre></blockquote>
- <p>Each of the <code>i₀...</code> is either 1. an integer; 2. an array of integers; 3. the special value <code>#t</code>. Integer arguments contain indices into the respective axis of <code>a</code>. <code>#t</code> for <code>iₖ</code> is a shortcut for ‘the whole of axis <code>k</code>’<a id="DOCF7" href="#FOOT7"><sup>7</sup></a>. The result <code>b</code> has rank equal to the sum of all the ranks of the <code>i₀...</code>, and is defined as
- </p>
- <blockquote>
- <pre class="verbatim">(ra-ref b j₀ ...) = (ra-ref a (ra-ref i₀ j₀ ...) ...)
- </pre></blockquote>
- <p>In other words, <code>ra-from</code> produces the outer product of the indices <code>i₀...</code> with operator <code>a</code> (if one thinks of <code>(a i₀ ...)</code> as <code>(ra-ref a i₀ ...)</code>). The rank of this outer product is <em class='tex2jax_process'>\(\mathrm{rank}\,A + \sum_i (\mathrm{rank}\,i - 1)\)</em>.
- </p>
- <p>If all of the <code>i...</code> are integers or arrays of type <code>d</code> (such as those produced by <code>ra-iota</code> or <code>ra-i</code>) then the result of <code>ra-from</code> shares the root of <code>a</code>. Otherwise <code>newra</code> cannot tell whether the indices are an arithmetic sequence, so the result has to be copied to a new root. For example:
- </p>
- <div class="example">
- <pre class="verbatim">(define a (list->ra 2 '((a b c) (d e f))))
- </pre><pre class="example">⇒ <code>#%2:2:3((a b c) (d e f))</code>
- </pre><pre class="verbatim">(ra-from a 0 #t) ; row 0, will share root
- </pre><pre class="example">⇒ <code>#%1:3(a b c)</code>
- </pre><pre class="verbatim">(ra-from a #t 1) ; column 1, will share root
- </pre><pre class="example">⇒ <code>#%1:2(b e)</code>
- </pre><pre class="verbatim">(ra-from a #t (make-ra-root #(2 0))) ; cols 2 & 0, won't share root
- </pre><pre class="example">⇒ <code>#%2:2:2((c a) (f d))</code>
- </pre><pre class="verbatim">(ra-from a #t (ra-iota 2 2 -2)) ; cols 2 & 0, will share root
- </pre><pre class="example">⇒ <code>#%2:2:2((c a) (f d))</code>
- </pre></div>
- <p>One may give fewer <code>i</code> than the rank of <code>a</code>. The missing arguments are taken as <code>#t</code> (see <a href="#Rank-polymorphism">Rank polymorphism</a>).
- </p>
- <div class="example">
- <pre class="verbatim">(ra-from a 0) ; row 0, same as (ra-from a 0 #t)
- </pre><pre class="example">⇒ <code>#%1d:3(0 1 2)</code>
- </pre></div>
- <span id="index-dots"></span>
- <p>When used as an argument to <code>ra-from</code> (or <code>ra-amend!</code>), the special object <code>(<a href="#x_002ddots">dots</a> n)</code> stands for <code>n</code> times <code>#t</code>. <code>(dots)</code> alone will expand to fill the rank of the array argument, so the indices that come after are pushed to the last axes.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-from A 0 (dots 1) 1) ; same as (ra-from A 0 #t 1)
- (ra-from B 0 (dots 2) 1) ; same as (ra-from B 0 #t #t 1)
- (ra-from C 0 (dots) 1) ; same as (ra-from C 1 (dots (- (ra-rank C) 2)) 1)
- </pre></div>
- <p>For instance:
- </p><div class="example">
- <pre class="verbatim">(ra-i 4 3 2)
- </pre><pre class="example">⇒ #%3d:4:3:2(((0 1) (2 3) (4 5)) ((6 7) (8 9) (10 11)) ((12 13) (14 15) (16 17)) ((18 19) (20 21) (22 23)))
- </pre><pre class="verbatim">(ra-from (ra-i 4 3 2) (dots) 1) ; select second element on last axis
- </pre><pre class="example">⇒ #%2d:4:3((1 3 5) (7 9 11) (13 15 17) (19 21 23))
- </pre></div>
- <p>Array application <code>(A i₀ ...)</code> is equivalent to <code>(ra-from A i₀ ...)</code>, except that whenever the result of <code>(ra-from A i₀ ...)</code> has rank-0, <code>(A i₀ ...)</code> returns the element of that result instead.<a id="DOCF8" href="#FOOT8"><sup>8</sup></a>
- </p>
- <div class="example">
- <pre class="verbatim">(ra-from (ra-i 2 3) 1 1)
- </pre><pre class="example">⇒ <code>#%0(4)</code>
- </pre><pre class="verbatim">((ra-i 2 3) 0 0)
- </pre><pre class="example">⇒ 4
- </pre></div>
- <p>When it is known that the result of <code>ra-from</code> will share the root with its argument, that can be used to modify the original array. For example:
- </p>
- <div class="example">
- <pre class="verbatim">(define a (list->ra 2 '((a b c) (d e f))))
- (ra-fill! (ra-from a 1) x)
- </pre><pre class="example">⇒ <code>#%2:3((a b c) (x x x)</code>
- </pre><pre class="verbatim">a
- </pre><pre class="example">⇒ <code>#%2:3((a b c) (x x x))</code>
- </pre></div>
- <p><a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a> handles the general case:
- </p>
- <div class="example">
- <pre class="verbatim">(define a (list->ra 2 '((a b c) (d e f))))
- (ra-amend! a 'Y #t (make-ra-root #(2 0)))
- </pre><pre class="example">⇒ <code>#%2:3((Y b Y) (Y e Y))</code>
- </pre><pre class="verbatim">a
- </pre><pre class="example">⇒ <code>#%2:3((Y b Y) (Y e Y))</code>
- </pre></div>
- <p>while on the other hand
- </p><div class="example">
- <pre class="verbatim">(define a (list->ra 2 '((a b c) (d e f))))
- (ra-fill! (ra-from a #t (make-ra-root #(2 0))) 'Y)
- </pre><pre class="example">⇒ <code>#%2:3((Y Y) (Y Y))</code>
- </pre><pre class="verbatim">a
- </pre><pre class="example">⇒ <code>#%2:3((a b c) (d e f))</code>
- </pre></div>
- <hr>
- </div>
- <div class="section" id="Reshaping">
- <div class="header">
- <p>
- Next: <a href="#Concatenation" accesskey="n" rel="next">Concatenation</a>, Previous: <a href="#Slicing" accesskey="p" rel="prev">Slicing</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Reshaping-1"></span><h3 class="section">2.6 Reshaping</h3>
- <span id="index-APL"></span>
- <span id="index-_002c_002c-ravel"></span>
- <span id="index-_005b_003f_005d_002c-reshape"></span>
- <p>To match APL ρ, <code>newra</code> offers three separate functions.
- </p>
- <p><a href="#x_002dra_002dreshape"><code>ra-reshape</code></a> and <a href="#x_002dra_002dravel"><code>ra-ravel</code></a> are in a way the inverse of each other. <code>ra-reshape</code> folds an axis into (potentially) many, while <code>ra-ravel</code> makes a block of axes into a single axis. Neither is able to increase the size of the array (although <code>ra-reshape</code> can <em>reduce</em> it). For that purpose <a href="#x_002dra_002dtile"><code>ra-tile</code></a> is provided.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-dimensions (ra-i 2 3 4))
- </pre><pre class="example">⇒ (2 3 4)
- </pre><pre class="verbatim">; insert new axis of size 5 before axis 0
- (ra-dimensions (ra-tile (ra-i 2 3 4) 0 5))
- </pre><pre class="example">⇒ (5 2 3 4)
- </pre><pre class="verbatim">; collapse axes 0 and 1
- (ra-dimensions (ra-ravel (ra-tile (ra-i 2 3 4) 0 5) 2))
- </pre><pre class="example">⇒ (10 3 4)
- </pre><pre class="verbatim">; reshape axis 0 into two axes with shape [3 3]
- (ra-dimensions (ra-reshape (ra-ravel (ra-tile (ra-i 2 3 4) 0 5) 2) 0 3 3))
- </pre><pre class="example">⇒ (3 3 3 4)
- </pre></div>
- <p><code>ra-reshape</code> and <code>ra-tile</code> always reuse the root of the argument. On the other hand <code>ra-ravel</code> may not be able to, depending on the storage order of the array — this is one of the reasons to have three different functions instead of only one. You can check in advance whether <code>ra-ravel</code> will reuse the root with the function <a href="#x_002dra_002dorder_002dc_003f"><code>ra-order-c?</code></a>.
- </p>
- <hr>
- </div>
- <div class="section" id="Concatenation">
- <div class="header">
- <p>
- Next: <a href="#Transposition" accesskey="n" rel="next">Transposition</a>, Previous: <a href="#Reshaping" accesskey="p" rel="prev">Reshaping</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Concatenation-1"></span><h3 class="section">2.7 Concatenation</h3>
- <span id="index-concatenation"></span>
- <p><code>newra</code> offers two concatenation operations: <a href="#x_002dra_002dcat"><code>ra-cat</code></a> (prefix cat) and <a href="#x_002dra_002dcats"><code>ra-cats</code></a> (cat suffix).
- </p>
- <p>For <code>ra-cat</code>, the arguments are prefix-matched, and the concatenation axis is counted from the left. E.g. for three arrays <var>r</var>, <var>s</var>, <var>t</var> with shapes
- </p>
- <div class="example">
- <pre class="verbatim">(r₀ r₁ r₂ r₃)
- (s₀ s₁ s₂ s₃ s₄ s₅)
- (t₀ t₁)
- </pre></div>
- <p>Then <code>(define val (ra-cat #t 1 r s t))</code> will prefix-match these to (it is an error if any of <code>r₀=s₀=t₀</code>, <code>r₂=s₂</code>, or <code>r₃=s₃</code> don’t hold)
- </p>
- <div class="example">
- <pre class="verbatim">(s₀ |r₁| s₂ s₃ s₄ s₅)
- (s₀ |s₁| s₂ s₃ s₄ s₅)
- (s₀ |t₁| s₂ s₃ s₄ s₅)
- </pre></div>
- <p>and then concatenate them along axis 1 into an array of shape <code>(s₀ (r₁+s₁+t₁) s₂ s₃ s₄ s₅)</code>.
- </p>
- <p>For <code>ra-cats</code>, the arguments are suffix-matched, and the concatenation axis is counted from the right. For example
- </p>
- <div class="example">
- <pre class="verbatim">(define r (ra-i 2 3 2))
- (define s (list->ra 1 '(a b)))
- (ra-cats #t 1 r s)
- </pre></div>
- <p>the axes are aligned as
- </p>
- <div class="example">
- <pre class="verbatim">(r₀ r₁ r₂)
- (s₀)
- </pre></div>
- <p>and suffix-matched (s₀ and r₂ must match)
- </p>
- <div class="example">
- <pre class="verbatim">(r₀ |r₁| r₂)
- (r₀ | 1| s₀)
- </pre></div>
- <p>for a result
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cats #t 1 r s)
- </pre><pre class="example">⇒ <code>#%3(((0 1) (2 3) (4 5) (a b)) ((6 7) (8 9) (10 11) (a b)))</code>
- </pre></div>
- <p>Note that the rank extension of <code>s</code> on the concatenation axis yields a length of 1 (and not <code>r₁</code>). It can be useful to think of the axis argument of <code>ra-cats</code> as indicating cell rank, so the code above means ‘concatenate 1-cells’.
- </p>
- <p>For both <code>ra-cat</code> and <code>ra-cats</code>, axes other than the concatenation axis must match across all of the arguments.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cat #t 0 (ra-i 3 2) (ra-i 2))
- </pre><pre class="example">⇒ <code>#%2:4:2((0 1) (2 3) (4 5) (0 0) (1 1))</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-cats #t 1 (ra-i 3 2) (ra-i 2))
- </pre><pre class="example">⇒ <code>#%2:4:2((0 1) (2 3) (4 5) (0 1))</code>
- </pre></div>
- <p>In particular, it is not enough for the lengths to be the same; both bounds must match.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cat #t 0 (make-ra 'a '(1 1) '(1 4))
- (make-ra 'b '(2 2) '(1 4)))
- </pre><pre class="example">⇒ <code>#%2:2@1:4((a a a a) (b b b b))</code> ; axes 1 match, axes 0 don't need to
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-cat #t 1 (make-ra 'a '(1 1) '(1 4))
- (make-ra 'b '(2 2) '(1 4)))
- </pre><pre class="example">⇒ error ; axes 0 don't match
- </pre></div>
- <p>Here <a href="#x_002dra_002dreshape"><code>ra-reshape</code></a> is used to move axis 0 of the second argument into agreement.<a id="DOCF9" href="#FOOT9"><sup>9</sup></a>
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cat #t 1 (make-ra 'a '(1 1) '(1 4))
- (ra-reshape (make-ra 'b '(2 2) '(1 4)) 0 '(1 1)))
- </pre><pre class="example">⇒ <code>#%2@1:1:8((a a a a b b b b))</code>
- </pre></div>
- <p>On the concatenation axis, only lengths matter; for both <code>ra-cat</code> and <code>ra-cats</code>, the lower bound is 0 in the result, and the lower bounds of the arguments are ignored.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (make-ra 'a '(1 2) '(2 3)))
- (define b (make-ra 'b '(1 2)))
- (define c (make-ra 'c '(1 2) '(-1 0)))
- (ra-format (ra-cat #t 1 a b c))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2@1:2:5─┐
- │a│a│b│c│c│
- ├─┼─┼─┼─┼─┤
- │a│a│b│c│c│
- └─┴─┴─┴─┴─┘
- </pre></div>
- <p>Both <code>ra-cat</code> and <code>ra-cats</code> accept a negative concatenation axis. That will rank-extend all the arguments to the left (<code>ra-cat</code>) or to the right (<code>ra-cats</code>) before concatenating on the leftmost (<code>ra-cat</code>) or rightmost (<code>ra-cats</code>) axis. In the same way, one may give a concatenation axis which is beyond the rank of the argument with the highest rank. Consider
- </p>
- <div class="example">
- <pre class="verbatim">(define abc (list->ra 1 #(a b c)))
- (ra-cat #t -1 (ra-i 3) abc)
- </pre><pre class="example">⇒ <code>#%2:2:3((0 1 2) (a b c))</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-cat #t 0 (ra-i 3) abc)
- </pre><pre class="example">⇒ <code>#%1:6(0 1 2 a b c)</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-cat #t 1 (ra-i 3) abc)
- </pre><pre class="example">⇒ <code>#%2:3:2((0 a) (1 b) (2 c))</code>
- </pre></div>
- <p>vs
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cats #t -1 (ra-i 3) abc)
- </pre><pre class="example">⇒ <code>#%2:3:2((0 a) (1 b) (2 c))</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-cats #t 0 (ra-i 3) abc)
- </pre><pre class="example">⇒ <code>#%1:6(0 1 2 a b c)</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-cats #t 1 (ra-i 3) abc)
- </pre><pre class="example">⇒ <code>#%2:2:3((0 1 2) (a b c))</code>
- </pre></div>
- <p>Cf J append (,) stitch (,.).
- </p>
- <hr>
- </div>
- <div class="section" id="Transposition">
- <div class="header">
- <p>
- Next: <a href="#Other-operations-on-arrays" accesskey="n" rel="next">Other operations on arrays</a>, Previous: <a href="#Concatenation" accesskey="p" rel="prev">Concatenation</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Transposition-1"></span><h3 class="section">2.8 Transposition</h3>
- <span id="index-_005b_003f_005d_002c-transpose"></span>
- <span id="index-transpose"></span>
- <p><a href="#x_002dra_002dtranspose"><code>ra-transpose</code></a> takes a source array and one axis argument for each of the dimensions of the source array. The values of the arguments are the corresponding axes of the result array.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-dimensions (ra-transpose (ra-i 10 20 30) 2 0 1))
- </pre><pre class="example">⇒ <code>'(20 30 10)</code>
- </pre></div>
- <p>That is, axis 0 in the source array is mapped to axis 2 in the destination array, axis 1 to axis 0, and axis 2 to axis 1. The result array always shares the root of the source array.
- </p>
- <p>As you’d expect
- </p>
- <div class="example">
- <pre class="verbatim">(ra-transpose (ra-i 2 3) 1 0)
- </pre><pre class="example">⇒ <code>#%2d:3:2((0 3) (1 4) (2 5))</code>
- </pre></div>
- <p>One can map more than one axis of the source array to the same axis of the destination array. In that case the step of the destination axis becomes the sum of the steps of all the source axes. The classic example is
- </p>
- <span id="index-diagonal"></span>
- <div class="example">
- <pre class="verbatim">(define A (ra-copy #t (ra-i 3 3)))
- (ra-fill! (ra-transpose A 0 0) 'x)
- A
- </pre><pre class="example">⇒ <code>#%2:3:3((x 1 2) (3 x 5) (6 7 x))</code>
- </pre></div>
- <p>If one doesn’t give values for all of the source axes, the missing axes are sent beyond the highest one that was given. These are equivalent:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-transpose (ra-i 2 3 4) 1 0 2)
- (ra-transpose (ra-i 2 3 4) 1 0) ; fill with (+ 1 (max 1 0))
- </pre></div>
- <p>as are these:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-transpose (ra-i 2 3) 1) ; fill with (+ 1 (max 1))
- (ra-transpose (ra-i 2 3) 1 2)
- </pre></div>
- <p>Note that in the last example there is no source axis for destination axis 0. Destination axes not mentioned in the axis argument list become <a href="#x_002ddead_002daxes">dead axes</a>. The rank of the result array is always just large enough to fit all the destination axes.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-dimensions (ra-transpose (ra-i 2 3) 1))
- </pre><pre class="example">⇒ (#f 2 3)
- </pre></div>
- <p>In particular, <code>(ra-transpose A)</code> is equivalent to <code>(ra-transpose A 0 1 ... (- (ra-rank A) 1))</code> (which is of course the same array as <code>A</code>).
- </p>
- <span id="index-outer-product"></span>
- <p>This ability of <code>ra-transpose</code> can be exploited to compute ‘outer products’. In the following example the shape <code>[2 2]</code> of <code>A</code> matches with the two leading dead axes of <code>(ra-transpose B 2)</code>:
- </p>
- <div class="example">
- <pre class="verbatim"> A : [ 2 2]
- (ra-transpose B 2) : [#f #f 2 2]
- </pre></div>
- <span id="index-prefix-matching-1"></span>
- <p>The trailing axes then match through <a href="#Rank-extension">prefix matching</a>.
- </p>
- <div class="example">
- <pre class="verbatim">(define A (list->ra 2 '((a b) (c d))))
- (define B (ra-i 2 2))
- (ra-format (ra-map! (make-ra #f 2 2 2 2)
- (λ i (format #f "~{~a~}" i))
- A (ra-transpose B 2)))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%4:2:2:2:2═╗
- ║a0│a1║b0│b1║
- ║──┼──║──┼──║
- ║a2│a3║b2│b3║
- ╠═════╬═════╣
- ║c0│c1║d0│d1║
- ║──┼──║──┼──║
- ║c2│c3║d2│d3║
- ╚═════╩═════╝
- </pre></div>
- <span id="index-index-placeholder"></span>
- <p>Another use is the creation of ‘index placeholders’, e.g.
- </p><div class="example">
- <pre class="verbatim">(define (tensor-index i) (ra-transpose (ra-iota) i))
- (ra-format (ra-map! (make-ra #f 3 4) list (tensor-index 0) (tensor-index 1)))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2:3:4─────┬─────┬─────┐
- │(0 0)│(0 1)│(0 2)│(0 3)│
- ├─────┼─────┼─────┼─────┤
- │(1 0)│(1 1)│(1 2)│(1 3)│
- ├─────┼─────┼─────┼─────┤
- │(2 0)│(2 1)│(2 2)│(2 3)│
- └─────┴─────┴─────┴─────┘
- </pre></div>
- <span id="index-_005b_003f_005d_002c-grade"></span>
- <span id="index-grade"></span>
- <p>The function <a href="#x_002dra_002duntranspose"><code>ra-untranspose</code></a> takes its axis arguments the other way from <code>ra-transpose</code>; the value of each argument is the axis of the original array and the position in the argument list is the axis of the result array. This is less flexible than <code>ra-transpose</code>, but can be used to reverse an application of <code>ra-transpose</code> without having to sort (‘grade’) the original axis arguments.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (ra-i 2 3 4))
- (ra-equal? a (ra-untranspose (ra-transpose a 2 0 1) 2 0 1))
- </pre><pre class="example">⇒ <code>#t</code>
- </pre></div>
- <hr>
- </div>
- <div class="section" id="Other-operations-on-arrays">
- <div class="header">
- <p>
- Next: <a href="#Automatic-result-arrays" accesskey="n" rel="next">Automatic result arrays</a>, Previous: <a href="#Transposition" accesskey="p" rel="prev">Transposition</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Other-operations-on-arrays-1"></span><h3 class="section">2.9 Other operations on arrays</h3>
- <hr>
- </div>
- <div class="section" id="Automatic-result-arrays">
- <div class="header">
- <p>
- Next: <a href="#Foreign-interface" accesskey="n" rel="next">Foreign interface</a>, Previous: <a href="#Other-operations-on-arrays" accesskey="p" rel="prev">Other operations on arrays</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Automatic-result-arrays-1"></span><h3 class="section">2.10 Automatic result arrays</h3>
- <p>Most of the functions of <code>newra</code> do not create arrays, but instead they expect result arrays to be passed as arguments. This means that they must have been allocated in advance. However, there are a few functions, such as <a href="#x_002dra_002dcopy"><code>ra-copy</code></a> or <a href="#x_002dra_002dmap"><code>ra-map</code></a>, that do create a result array. The type and shape of that result array is deduced from the source arguments, as follows.
- </p>
- <ul>
- <li> The default type of the result array is the type of the first of the source arguments. If that type is <code>'d</code>, however, the default type of the result array is <code>#t</code>. Usually, a function will allow this default to be overriden with an explicit argument. If that argument is required, then <code>#f</code> will select the default.
- </li><li> The rank of the result array will be the rank of the source argument with the largest rank. On each dimension, the lower bound and the length of the result will match those of the source arguments, with the precision that if any of those is finite, then it will be finite in the result as well. (If there is only one source argument, as is the case for <code>ra-copy</code>, then it follows that that is the shape of the result.)
- </li></ul>
- <p>For example:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-map #t *
- ; shape '((0 1))
- (ra-iota 2 1)
- ; shape '((#f #f) (1 3))
- (ra-transpose (make-ra 9 '(1 3)) 1))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">; shape of result is '((0 1) (1 3))
- #%2:2@1:3((9 9 9) (18 18 18)
- </pre></div>
- <hr>
- </div>
- <div class="section" id="Foreign-interface">
- <div class="header">
- <p>
- Next: <a href="#Compatibility-with-old-Guile-arrays" accesskey="n" rel="next">Compatibility with old Guile arrays</a>, Previous: <a href="#Automatic-result-arrays" accesskey="p" rel="prev">Automatic result arrays</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Foreign-interface-1"></span><h3 class="section">2.11 Foreign interface</h3>
- <p>One of the major reasons to use arrays instead of other Scheme data structures is that they let one pass a large amount of data through a C interface very efficiently. The data doesn’t need to be copied — one only needs to pass a pointer to the data, plus the lengths and the steps in some order. C doesn’t have a standard consolidated array type, so the particulars are variable. In any case, the required items can be obtained trivially from a <code>newra</code> array object.
- </p>
- <p>For example:
- </p>
- <p>TODO
- </p>
- <hr>
- </div>
- <div class="section" id="Compatibility-with-old-Guile-arrays">
- <div class="header">
- <p>
- Previous: <a href="#Foreign-interface" accesskey="p" rel="prev">Foreign interface</a>, Up: <a href="#The-array-library" accesskey="u" rel="up">The array library</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Compatibility-with-old-Guile-arrays-1"></span><h3 class="section">2.12 Compatibility with old Guile arrays</h3>
- <p>The functions <a href="#x_002dra_002d_003earray"><code>ra->array</code></a> and <a href="#x_002darray_002d_003era"><code>array->ra</code></a> are provided to convert to and from <code>newra</code> arrays and built-in Guile arrays. It is an error to use <code>ra->array</code> on arrays whose root isn’t supported by the built-in arrays, or that have an unbounded axis. Except in those two cases, the conversion is transparent both ways, and the result always shares the root of the argument.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (make-array 'o 2 3))
- (define b (array->ra a))
- (ra-set! b 'x 1 1)
- (array-set! a 'y 0 2)
- a
- </pre><pre class="example">⇒ <code>#2((o o y) (o x o))</code>
- </pre><pre class="verbatim">b
- </pre><pre class="example">⇒ <code>#%2((o o y) (o x o))</code>
- </pre></div>
- <p><code><aseq></code>-root arrays must be type converted before using <code>ra->array</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(ra->array (ra-copy #t (ra-i 2 3)))
- </pre><pre class="example">⇒ #2((0 1 2) (3 4 5))
- </pre></div>
- <p>On dead axes, lengths can be set to 1 (with <a href="#x_002dra_002dsingletonize"><code>ra-singletonize</code></a>) to allow conversion with <code>ra->array</code> or to other array systems that do singleton broadcasting.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (ra-transpose (ra-i 2 3) 1 3))
- a
- </pre><pre class="example">⇒ <code>#%4d:d:2:d:3((((0 1 2)) ((3 4 5))))</code>
- </pre><pre class="verbatim">(ra-singletonize a)
- </pre><pre class="example">⇒ <code>#%4d:1:2:1:3((((0 1 2)) ((3 4 5))))</code>
- </pre></div>
- <p>One important difference between the built-in array functions and <code>newra</code> is that bounds matching in <code>newra</code> is strict: finite bounds must be identical for axes to match, while for <code>array-map!</code>, <code>array-for-each</code>, <code>array-copy!</code>, etc. the iteration range is the intersection of the ranges of the arguments<a id="DOCF10" href="#FOOT10"><sup>10</sup></a>. <code>newra</code> provides <a href="#x_002dra_002dclip"><code>ra-clip</code></a> to match ranges easily.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (make-ra-root (vector 'a 'b 'c 'd 'e 'f 'g))) ; range is 0..6
- (define b (ra-reshape (ra-iota 4) 0 '(2 5))) ; range is 2..5
- (ra-copy! a b)
- </pre><pre class="example">⇒ <code>Throw to key `mismatched-lens' with args `(7 4 at-dim 0)'.</code>
- </pre><pre class="verbatim">(ra-copy! (ra-clip a b) b)
- a
- </pre><pre class="example">⇒ <code>#%1:7(a b 0 1 2 3 g)</code>
- </pre></div>
- <hr>
- </div>
- </div>
- <div class="chapter" id="The-array-language">
- <div class="header">
- <p>
- Next: <a href="#Hazards" accesskey="n" rel="next">Hazards</a>, Previous: <a href="#The-array-library" accesskey="p" rel="prev">The array library</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="The-array-language-1"></span><h2 class="chapter">3 The array language</h2>
- <p>NOTE This section is about a facility that hasn’t been implemented yet.
- </p>
- <p>In array languages such as APL, scalar operations are implicitly extended (or ‘lifted’) to work on arrays, so one can just write (the equivalent of) <code>(+ A B)</code> instead of <code>(ra-map #f + A B)</code>. The basic <code>newra</code> iteration operations such as <code>ra-map</code> already perform rank extension of their arguments (so <code>A</code> or <code>B</code> can have a different rank from the result, as long as the prefix axes match). We still need ways to:
- </p>
- <ul>
- <li> associate an operation to the ranks of their arguments, so that the right frame of iteration can be chosen.
- </li><li> compute the shape and type of the result (if any).
- </li><li> handle scalar (non-array) arguments.
- </li></ul>
- <ul class="section-toc">
- <li><a href="#Verbs" accesskey="1">Verbs</a></li>
- <li><a href="#Reductions" accesskey="2">Reductions</a></li>
- </ul>
- <hr>
- <div class="section" id="Verbs">
- <div class="header">
- <p>
- Next: <a href="#Reductions" accesskey="n" rel="next">Reductions</a>, Up: <a href="#The-array-language" accesskey="u" rel="up">The array language</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Verbs-1"></span><h3 class="section">3.1 Verbs</h3>
- <hr>
- </div>
- <div class="section" id="Reductions">
- <div class="header">
- <p>
- Previous: <a href="#Verbs" accesskey="p" rel="prev">Verbs</a>, Up: <a href="#The-array-language" accesskey="u" rel="up">The array language</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Reductions-1"></span><h3 class="section">3.2 Reductions</h3>
- <hr>
- </div>
- </div>
- <div class="chapter" id="Hazards">
- <div class="header">
- <p>
- Next: <a href="#Reference" accesskey="n" rel="next">Reference</a>, Previous: <a href="#The-array-language" accesskey="p" rel="prev">The array language</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Hazards-1"></span><h2 class="chapter">4 Hazards</h2>
- <ul class="section-toc">
- <li><a href="#Differences-with_002e_002e_002e" accesskey="1">Differences with...</a></li>
- <li><a href="#Pitfalls-and-common-mistakes" accesskey="2">Pitfalls and common mistakes</a></li>
- </ul>
- <hr>
- <div class="section" id="Differences-with_002e_002e_002e">
- <div class="header">
- <p>
- Next: <a href="#Pitfalls-and-common-mistakes" accesskey="n" rel="next">Pitfalls and common mistakes</a>, Up: <a href="#Hazards" accesskey="u" rel="up">Hazards</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Differences-with_002e_002e_002e-1"></span><h3 class="section">4.1 Differences with...</h3>
- <p>If you come to <code>newra</code> from another array language or library, you may want to be aware of some of these differences. See also the <a href="#Cheatsheet">Cheatsheet</a>.
- </p>
- <p>Differences with built-in Guile arrays
- </p><ul>
- <li> <code>newra</code> map operations are rank-extending but require exact agreement of bounds, unlike operations on built-in arrays, which require exact rank agreement but admit overlapping bounds.
- </li></ul>
- <p>Differences with array SRFIs
- </p>
- <p>For the most part these differences stem from <code>newra</code> following the conventions of Guile’s built in array API.
- </p>
- <ul>
- <li> SRFI-25 uses <code>[)</code> array bounds, while <code>newra</code> uses <code>[]</code> array bounds like Guile’s built arrays.
- </li><li> SRFI-25 uses arrays as shape arguments, while <code>newra</code> uses lists like in Guile’s built in array functions.
- </li><li> SRFI-163 uses <code>#</code><var>RANK</var><code>a</code> for literal arrays of Scheme values, while <code>newra</code> uses <code>#%</code><var>RANK</var> instead (<code>#%</code><var>RANK</var><code>a</code> is used for literal arrays of characters, following Guile’s built in <code>#</code><var>RANK</var><code>a</code>).
- </li><li> SRFI-163 uses <code>#0 x</code> for a literal rank-0 array, while <code>newra</code> uses <code>#0(x)</code> (this is configurable with <a href="#x_002dstar_002dra_002dparenthesized_002drank_002dzero_002dstar"><code>*ra-parenthesized-rank-zero*</code></a>).
- </li></ul>
- <span id="index-APL-1"></span>
- <p>Differences with APL
- </p><ul>
- <li> The default lower bound (base index) in <code>newra</code> is 0, as in <code>⎕io←0</code>. The lower bound isn’t global, but it may be different per axis.
- </li><li> <code>newra</code> arrays of size 1 are not equivalent to scalars and always retain their rank. For example, <code>(make-ra 99)</code>, <code>(make-ra 99 1)</code> and <code>(make-ra 99 1 1)</code> are all different from each other and from the scalar <code>99</code>, while in APL <code>99</code>, <code>(1 ⍴ 99)</code>, and <code>(1 1 ⍴ 99)</code> are all the same thing.
- </li><li> When a function takes multiple arguments, the meaning with multiple arguments is an extension of the meaning with a single argument. This contrasts with APL where the monadic and dyadic versions of a verb usually have a related but independent definition. For example <code>(ra-transpose a)</code>≡<code>(ra-transpose a 0)</code>≡<code>(ra-transpose a 0 1)</code>, but (assuming <code>a</code> is of rank 2) <code>⍉a</code>≡<code>1 0⍉a</code>. Please check the documentation for each function.
- </li></ul>
- <span id="index-Fortran"></span>
- <p>Differences with Fortran
- </p><ul>
- <li> The default lower bound (base index) in <code>newra</code> is 0, not 1. Like in Fortran, the lower bound may be different for each axis of each array.
- </li><li> Unlike Fortran, the default element order in arrays is row-major, or ‘last index changes fastest’. It’s possible to define and manipulate arrays in any other order, including Fortran’s default. However, some functions (such as <code>ra-ravel</code>) only support row-major order.
- </li><li> <code>newra</code> uses prefix matching for rank extension on arguments on any rank, while Fortran only performs rank extension on scalar arguments.
- </li></ul>
- <span id="index-Python"></span>
- <span id="index-NumPy-2"></span>
- <p>Differences with NumPy
- </p><ul>
- <li> <code>newra</code> uses prefix matching for rank extension, while NumPy uses suffix matching (<a href="#x_002dnumpy_002dexample_002d0">example</a>).
- </li><li> <code>newra</code> doesn’t support singleton broadcasting. Axes of length 1 only match either axes of length 1, or <a href="#x_002ddead_002daxes">dead axes</a>. For example, <code>(ra-map #f + (make-ra 90 1) (make-ra 7 2))</code> is an error because the shapes (2), (1), (2) don’t agree.
- </li></ul>
- <span id="index-Octave"></span>
- <span id="index-Matlab"></span>
- <p>Differences with Octave
- </p><ul>
- <li> The default lower bound (base index) in <code>newra</code> is 0, not 1. Lower bounds may be 1 on a particular array (or particular axes of an array), but not globally.
- </li><li> In Octave, the lowest rank an array can be is 2. This isn’t true in <code>newra</code>, so, for example, an array of rank 1 isn’t equivalent to an array of rank 2 with a single row (a ‘row vector’).
- </li><li> Unlike Octave, the default element order in arrays is row-major, or ‘last index changes fastest’. It’s possible to define and manipulate arrays in any other order, including Octave’s default. However, some functions (such as <code>ra-ravel</code>) only support row-major order.
- </li><li> <code>newra</code> uses prefix matching for rank extension on arguments on any rank, while Octave only performs rank extension on scalar arguments.
- </li></ul>
- <hr>
- </div>
- <div class="section" id="Pitfalls-and-common-mistakes">
- <div class="header">
- <p>
- Previous: <a href="#Differences-with_002e_002e_002e" accesskey="p" rel="prev">Differences with...</a>, Up: <a href="#Hazards" accesskey="u" rel="up">Hazards</a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Pitfalls-and-common-mistakes-1"></span><h3 class="section">4.2 Pitfalls and common mistakes</h3>
- <ul class="section-toc">
- <li><a href="#Using-rank-extension-or-dead-axes-for-reduction" accesskey="1">Using rank extension or dead axes for reduction</a></li>
- <li><a href="#Holding-onto-the-arguments-of-x_002dra_002dslice_002dfor_002deach_0027s-op" accesskey="2">Holding onto the arguments of <a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>’s <var>op</var></a></li>
- <li><a href="#Partial-application-in-outer-products" accesskey="3">Partial application in outer products</a></li>
- </ul>
- <div class="subsection" id="Using-rank-extension-or-dead-axes-for-reduction">
- <h4 class="subsection">4.2.1 Using rank extension or dead axes for reduction</h4>
- <p>The use of rank extension for reduction inhibits parallelization and may be dependent on the order in which the array arguments are traversed, which is generally unspecified. In principle, it’s possible for <code>newra</code> to look at the strides of the destination arguments and figure out whether some array positions are referenced more than once, so that the meaning of <code>ra-for-each</code> or <code>ra-map!</code> can be preserved even if (when?) those operations are actually implemented in parallel. However, that still leaves the order of traversal unspecified.
- </p>
- <p>In that light, the following reduction should be alright when <var>op</var> is <code>+</code>, but it’s better avoided it if <var>op</var> is <code>-</code>, even if it happens to do what you expect on the current version of <code>newra</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(let ((sum (make-ra 0)))
- (ra-map! sum op sum (list->ra 1 '(1 2 3 4 5)))
- (sum))
- </pre><pre class="example">⇒ <code>15</code>
- </pre></div>
- <p>For cases where it matters, it’s better to use a function which specifies the order of evaluation, such as <code>ra-fold</code>.
- </p>
- <span id="index-ra_002dslice_002dfor_002deach"></span>
- </div>
- <div class="subsection" id="Holding-onto-the-arguments-of-x_002dra_002dslice_002dfor_002deach_0027s-op">
- <h4 class="subsection">4.2.2 Holding onto the arguments of <a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>’s <var>op</var></h4>
- <p><a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a> may reuse the same array object for different calls to <var>op</var>. For example
- </p>
- <div class="example">
- <pre class="verbatim">; `keep the last row that begins with 3' (wrong)
- (let ((a #f))
- (ra-slice-for-each 1
- (lambda (row) (when (= 3 (row 0)) (set! a row)))
- (list->ra 2 '((2 3) (3 5) (3 a) (1 2))))
- a)
- </pre><pre class="example">⇒ <code>#%1:2(2 3)</code> ; ?? could be anything
- </pre></div>
- <p>For this to work reliably, you need to copy the array descriptor, which can be done with <a href="#x_002dra_002dslice"><code>ra-slice</code></a>.
- </p>
- <div class="example">
- <pre class="verbatim">; `keep the last row that begins with 3' (fixed)
- (let ((a #f))
- (ra-slice-for-each 1
- (lambda (row) (when (= 3 (row 0)) (set! a (ra-slice row))))
- (list->ra 2 '((2 3) (3 5) (3 a) (1 2))))
- a)
- </pre><pre class="example">⇒ <code>#%1:2(3 a)</code>
- </pre></div>
- <p>Of course, if it suits your purpose, you can also copy <var>row</var> into a new array, with its own storage, using <a href="#x_002dra_002dcopy"><code>ra-copy</code></a>.
- </p>
- </div>
- <div class="subsection" id="Partial-application-in-outer-products">
- <h4 class="subsection">4.2.3 Partial application in outer products</h4>
- <p>TODO
- </p>
- <hr>
- </div>
- </div>
- </div>
- <div class="chapter" id="Reference">
- <div class="header">
- <p>
- Next: <a href="#Cheatsheet" accesskey="n" rel="next">Cheatsheet</a>, Previous: <a href="#Hazards" accesskey="p" rel="prev">Hazards</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Reference-1"></span><h2 class="chapter">5 Reference</h2>
- <span id="index-array_002d_003era"></span>
- <span id="x_002darray_002d_003era"></span><dl class="def">
- <dt id="index-array_002d_003era-1"><span class="category">Function<!-- /@w -->: </span><span><strong>array->ra</strong> <em>a</em><a href='#index-array_002d_003era-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Convert built-in Guile array <var>a</var> (anything that satisfies <code>array?</code>) to a (<code>newra)</code> array.
- </p>
- <p>This function doesn’t create a copy of the array, but reuses the root (<code>shared-array-root</code>) of <var>a</var>, that is, <code>(eq? (ra-root (array->ra a)) (shared-array-root a))</code> is <code>#t</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (make-array 'x 2 2))
- (define b (array->ra v))
- b
- </pre><pre class="example">⇒ <code>#%2:2:2((x x) (x x))</code>
- </pre><pre class="verbatim">(ra-fill! b 'y)
- a
- </pre><pre class="example">⇒ <code>#2((y y) (y y))</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002d_003earray"><code>ra->array</code></a>.
- </p>
- </dd></dl>
- <span id="index-c_002ddims"></span>
- <span id="x_002dc_002ddims"></span><dl class="def">
- <dt id="index-c_002ddims-1"><span class="category">Function<!-- /@w -->: </span><span><strong>c-dims</strong> <em>bounds ...</em><a href='#index-c_002ddims-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <span id="index-packed-array"></span>
- <p>Create dims (dim vector) for row-major order array (packed elements, last dimension changing fastest).
- </p>
- <p>Each of the <var>bounds</var> may be an integer (a length) or a pair of integers (lower and upper bounds).
- </p><div class="example">
- <pre class="verbatim">(c-dims 2 3)
- </pre><pre class="example">⇒ <code>#(#<<dim> len: 2 lo: 0 step: 3> #<<dim> len: 3 lo: 0 step: 1>)</code>
- </pre></div>
- <p>The functions <a href="#x_002dmake_002dra_002dnew"><code>make-ra-new</code></a> and <a href="#x_002dmake_002dra_002droot"><code>make-ra-root</code></a> take a dim vector as one of their arguments.
- </p>
- </dd></dl>
- <span id="index-dots-1"></span>
- <span id="x_002ddots"></span><dl class="def">
- <dt id="index-dots-2"><span class="category">Function<!-- /@w -->: </span><span><strong>dots</strong> <em>[n] ...</em><a href='#index-dots-2' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Placeholder for <var>n</var> full axes, used as argument to <code>ra-from</code> or <code>ra-amend!</code>. Without <var>n</var>, expand to fill the rank of the argument <var>a</var> of <a href="#x_002dra_002dfrom"><code>ra-from</code></a> or <a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a>.
- </p></dd></dl>
- <span id="index-make_002dra"></span>
- <span id="x_002dmake_002dra"></span><dl class="def">
- <dt id="index-make_002dra-1"><span class="category">Function<!-- /@w -->: </span><span><strong>make-ra</strong> <em>val bounds ... ⇒ a</em><a href='#index-make_002dra-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Create an array of type <code>#t</code> with the given <var>bounds</var>, filled with <var>val</var>. Each of the bounds may be an integer (a length) or a pair of integers (lower and upper bounds).
- </p>
- <div class="example">
- <pre class="verbatim">(make-ra 0 '(2 3) 4)
- </pre><pre class="example">⇒ <code>#%2@2:2:4((0 0 0 0) (0 0 0 0))</code>
- </pre></div>
- <p>See also: <a href="#x_002dmake_002dtyped_002dra"><code>make-typed-ra</code></a>, <a href="#x_002dmake_002dra_002dnew"><code>ra-make-ra-new</code></a>, <a href="#x_002dra_002dshape"><code>ra-shape</code></a>.
- </p>
- </dd></dl>
- <span id="index-make_002dra_002dnew"></span>
- <span id="x_002dmake_002dra_002dnew"></span><dl class="def">
- <dt id="index-make_002dra_002dnew-1"><span class="category">Function<!-- /@w -->: </span><span><strong>make-ra-new</strong> <em>type value dims</em><a href='#index-make_002dra_002dnew-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Create an array over a new root of the given <var>type</var> and size (according to <var>dims</var>), and fill it with <var>value</var>.
- </p><div class="example">
- <pre class="verbatim">(make-ra-new 'u8 0 (c-dims 3 2))
- </pre><pre class="example">⇒ #%2u8:3:2((0 0) (0 0) (0 0))
- </pre></div>
- </dd></dl>
- <span id="index-make_002dra_002droot"></span>
- <span id="x_002dmake_002dra_002droot"></span><dl class="def">
- <dt id="index-make_002dra_002droot-1"><span class="category">Function<!-- /@w -->: </span><span><strong>make-ra-root</strong> <em>root [dims [zero]]</em><a href='#index-make_002dra_002droot-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Create an array over the given <var>root</var>.
- </p><div class="example">
- <pre class="verbatim">(make-ra-root (vector 1 2 3))
- </pre><pre class="example">⇒ #%1d:3(1 2 3)
- </pre></div>
- <div class="example">
- <pre class="verbatim">(make-ra-root (vector 1 2 3) (vector (make-dim 2)))
- </pre><pre class="example">⇒ #%1d:2(1 2)
- </pre></div>
- <div class="example">
- <pre class="verbatim">(make-ra-root (vector 1 2 3) (vector (make-dim 2)) 1)
- </pre><pre class="example">⇒ #%1d:2(2 3)
- </pre></div>
- </dd></dl>
- <span id="index-make_002dtyped_002dra"></span>
- <span id="x_002dmake_002dtyped_002dra"></span><dl class="def">
- <dt id="index-make_002dtyped_002dra-1"><span class="category">Function<!-- /@w -->: </span><span><strong>make-typed-ra</strong> <em>type val bounds ... ⇒ a</em><a href='#index-make_002dtyped_002dra-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Same as <a href="#x_002dmake_002dra"><code>make-ra</code></a>, except that the result has the specified <var>type</var>.
- </p>
- <p>See also: <a href="#x_002dmake_002dra"><code>make-ra</code></a>, <a href="#x_002dmake_002dra_002droot"><code>ra-make-ra-root</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002d_003earray"></span>
- <span id="x_002dra_002d_003earray"></span><dl class="def">
- <dt id="index-ra_002d_003earray-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra->array</strong> <em>a</em><a href='#index-ra_002d_003earray-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Convert (<code>newra</code>) array <var>a</var> to built-in Guile array.
- </p>
- <p>This function does not create a copy of the array, but reuses the root (<code>ra-root</code>) of <var>a</var>, that is, <code>(eq? (ra-root a) (shared-array-root (ra->array a)))</code> is <code>#t</code>.
- </p>
- <p>Not all arrays can be converted to built-in Guile arrays. For example, type <code>d</code> arrays, or arrays with unbounded axes, are not convertible.
- </p>
- <div class="example">
- <pre class="verbatim">(ra->array (ra-i 3)) ; error, type d not convertible
- (ra->array (ra-copy (ra-i 3))) ; ok, (ra-copy (ra-i 3)) has type #t
- (ra->array (ra-transpose (ra-i 2 3) 1)) ; error, not convertible
- (ra->array (ra-singletonize (ra-transpose (ra-i 2 3) 1))) ; ok
- </pre></div>
- <p>See also: <a href="#x_002darray_002d_003era"><code>array->ra</code></a>, <a href="#x_002dra_002dsingletonize"><code>ra-singletonize</code></a>, <a href="#x_002dra_002dcopy_0021"><code>ra-copy!</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002damend_0021"></span>
- <span id="x_002dra_002damend_0021"></span><dl class="def">
- <dt id="index-ra_002damend_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-amend!</strong> <em>a c i ... → a</em><a href='#index-ra_002damend_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Copy <var>c</var> to the outer product slice of <var>a</var> by indices <var>i</var> ...
- </p>
- <div class="example">
- <pre class="verbatim">a(i₀(j₀₀ j₀₁ ...) i₁(j₁₀ j₁₁ ...) ...) ← c(j₀₀ j₀₁ ... j₁₀ j₁₁ ...)
- </pre></div>
- <p>where <var>i</var> : <var>i₀</var> <var>i₁</var> ...
- </p>
- <p>This is equivalent to <code>(ra-copy! (ra-from a i ...) c)</code> if <code>(ra-from a i ...)</code> would
- return a shared ra of <var>a</var>, but it also works in other cases, as long as <var>a</var> is
- writable. <var>i</var> may take any of the special values accepted by <code>ra-from</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (list->ra 1 '(1 2 3)))
- (define x 1)
- (define y (array->ra #(1)))
- (ra-amend! a 9 x) ; modifies a
- (ra-amend! a (array->ra #0(9)) x) ; same thing
- (ra-copy! (ra-from a x) (array->ra #0(9))) ; modifies a
- (ra-amend! a 9 y) ; modifies a
- (ra-copy! (ra-from a y) (array->ra #0(9))) ; (ra-from a y) is a new array, so a is NOT modified
- (ra-amend! (array->ra #(2 3 4)) 9 1) ; error, (array->ra #(2 3 4)) is not mutable
- </pre></div>
- <p>If <var>i</var> contains repeated indices or the steps of <var>a</var> make it so that the same elements of <var>a</var>
- are referenced more than once, then the value that ends up in <var>a</var> may correspond to any of the
- indices that match those elements. <code>newra</code> will <em>not</em> check that each element of <var>a</var> is represented uniquely in its root.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-amend! a (array->ra #(6 7 8)) (ra-tile (array->ra #0(1)) 0 3))
- </pre><pre class="example">⇒ #%1:3(1 8 3) ; do not rely on 8 ending up there
- </pre></div>
- <p>This function returns the modified array <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002dfrom"><code>ra-from</code></a>, <a href="#x_002dra_002dcopy_0021"><code>ra-copy!</code></a> <a href="#x_002dra_002dcell"><code>ra-cell</code></a> <a href="#x_002dra_002dref"><code>ra-ref</code></a> <a href="#x_002dra_002dslice"><code>ra-slice</code></a> <a href="#x_002dra_002dset_0021"><code>ra-set!</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dany"></span>
- <span id="x_002dra_002dany"></span><dl class="def">
- <dt id="index-ra_002dany-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-any</strong> <em>pred? a ...</em><a href='#index-ra_002dany-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>See also: <a href="#x_002dra_002dfold"><code>ra-fold</code></a>, <a href="#x_002dra_002devery"><code>ra-every</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dcell"></span>
- <span id="x_002dra_002dcell"></span><dl class="def">
- <dt id="index-ra_002dcell-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-cell</strong> <em>a i ...</em><a href='#index-ra_002dcell-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Look up array cell.
- </p>
- <p>Let <var>k</var> be the rank of <var>a</var> minus the number of <var>i ...</var> If <var>k</var> is zero, return the array element at <var>i ...</var>, like <a href="#x_002dra_002dref"><code>ra-ref</code></a>; else return a <var>k</var>-view of <var>a</var>, like <a href="#x_002dra_002dslice"><code>ra-slice</code></a>.
- </p>
- <p>It is an error if the number of <var>i ...</var> exceeds the rank of <var>a</var>.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (ra-copy (ra-i 3 2)))
- (ra-cell a 0)
- (ra-slice a 0) ; same thing
- </pre><pre class="example">⇒ <code>#%1(0 1 2)</code>
- </pre><pre class="verbatim">(ra-slice a 0 1)
- </pre><pre class="example">⇒ <code>#%0(4)</code>
- </pre><pre class="verbatim">(ra-cell a 0 1)
- (ra-ref a 0 1) ; same thing
- </pre><pre class="example">⇒ <code>4</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002dslice"><code>ra-slice</code></a>, <a href="#x_002dra_002dref"><code>ra-ref</code></a>, <a href="#x_002dra_002dfrom"><code>ra-from</code></a>, <a href="#Slicing">Slicing</a>.
- </p>
- </dd></dl>
- <span id="index-intersection"></span>
- <span id="index-ra_002dclip"></span>
- <span id="x_002dra_002dclip"></span><dl class="def">
- <dt id="index-ra_002dclip-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-clip</strong> <em>a b ⇒ c</em><a href='#index-ra_002dclip-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Slice <var>a</var> to the intersection of the bounds of <var>a</var> and <var>b</var>. If <var>a</var> and <var>b</var> have different ranks, only the common prefix of <var>a</var> is sliced.
- </p>
- <div class="example">
- <pre class="verbatim">(define f (make-ra " " '(-4 4) '(-5 3)))
- (define a (make-ra " A " '(-3 0) '(-4 1)))
- (define b (make-ra " B " '(-1 3) '(-1 2)))
- (ra-fill! (ra-clip a b) " x ")
- (ra-copy! (ra-clip f b) (ra-clip b f))
- (ra-copy! (ra-clip f a) (ra-clip a f))
- (ra-format f)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2@-4:9@-5:9───┬───┬───┬───┬───┬───┐
- │ │ │ │ │ │ │ │ │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ A │ A │ A │ │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ A │ A │ A │ │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ x │ x │ x │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ x │ x │ x │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ B │ B │ B │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ B │ B │ B │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ B │ B │ B │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ │ │ │ │ │
- └───┴───┴───┴───┴───┴───┴───┴───┴───┘
- </pre><pre class="verbatim">(ra-fill! (ra-clip f (ra-clip a b)) " o ")
- (ra-format f)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2@-4:9@-5:9───┬───┬───┬───┬───┬───┐
- │ │ │ │ │ │ │ │ │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ A │ A │ A │ │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ A │ A │ A │ │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ o │ o │ o │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ A │ A │ A │ o │ o │ o │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ B │ B │ B │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ B │ B │ B │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ B │ B │ B │ B │ │
- ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
- │ │ │ │ │ │ │ │ │ │
- └───┴───┴───┴───┴───┴───┴───┴───┴───┘
- </pre></div>
- <p>The result of <code>ra-clip</code> always shares the root of its first argument <var>a</var>.
- </p>
- <p>See also: <a href="#Slicing">Slicing</a>, <a href="#Compatibility-with-old-Guile-arrays">Compatibility with old Guile arrays</a>.
- </p></dd></dl>
- <span id="index-ra_002ddimensions"></span>
- <span id="x_002dra_002ddimensions"></span><dl class="def">
- <dt id="index-ra_002ddimensions-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-dimensions</strong> <em>a</em><a href='#index-ra_002ddimensions-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Return the dimensions of <var>a</var> as a list, like <a href="#x_002dra_002dshape"><code>ra-shape</code></a>, but the dimensions that have lower bound zero are represented by their length alone, instead of a two-element list <code>(lo hi)</code>. This is a convenience for the common case when lower bounds are zero.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-dimensions (make-ra 0 '(2 3) 4))
- </pre><pre class="example">⇒ <code>((2 3) 4)</code>
- </pre><pre class="verbatim">(ra-shape (make-ra 0 '(2 3) 4))
- </pre><pre class="example">⇒ <code>((2 3) (0 3))</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002dshape"><code>ra-shape</code></a>, <a href="#x_002dmake_002dra"><code>make-ra</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dformat"></span>
- <span id="x_002dra_002dformat"></span><dl class="def">
- <dt id="index-ra_002dformat-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-format</strong> <em>ra port #:fmt #:prefix? #:compact</em><a href='#index-ra_002dformat-1' class='copiable-anchor'> ¶</a></span></dt>
- <dt id="index-ra_002dformat-2"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-format</strong> <em>ra #f #:fmt #:prefix? #:compact ⇒ sc</em><a href='#index-ra_002dformat-2' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Pretty print array <var>ra</var>.
- </p>
- <p>Each element <var>x</var> of <var>ra</var> is converted to a string using <code>(fmt x)</code>, or <code>(format #f fmt x)</code><a id="DOCF11" href="#FOOT11"><sup>11</sup></a> if <var>fmt</var> is a string. <var>fmt</var> defauts to <code>"~a"</code>. Elements that are arrays are formatted using <code>ra-format</code> recursively.
- </p>
- <p>If <var>port</var> is <code>#f</code>, nothing is printed and the function returns a rank-2 character array <var>sc</var> with the result of the printing. Otherwise the array is printed to <var>port</var> and the function returns unspecified values. The default for <var>port</var> is <code>#t</code>, which works as <code>(current-output-port)</code>.
- </p>
- <p>If <var>prefix?</var> is true, the array print prefix <a href="#x_002dra_002dprint_002dprefix"><code>ra-print-prefix</code></a> is printed over the first line of the printout if the rank of <var>ra</var> is 2 or greater, else it is printed on a separate line above the printout.
- </p>
- <p>If <var>compact</var> is 0 (the default) separators are printed around every cell. If <var>compact</var> is 1, the separators for the rank-0 cells are replaced by spaces and the separators for the rank-1 cells are omitted. This results in a more compact output at the cost of some clarity. If <var>compact</var> is 2, the separators for the rank-0 cells are also omitted.
- </p>
- <p>This function handles arrays of rank up to 14, or up to 16 if <var>compact</var> > 0. The even dimensions (counting from the last one) are arranged horizontally, while the odd dimensions are arranged vertically. The dimensions are separated visually using <a href="https://unicode.org/charts/nameslist/n_2500.html">box-drawing characters</a>. This might look better or worse depending on the font.
- </p>
- <p>A 0-array:
- </p><div class="example">
- <pre class="verbatim">(ra-format (make-ra 'element))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%0
- element
- </pre></div>
- <p>A 1-array:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-i 4))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%1d:4
- │0│1│2│3│
- </pre></div>
- <p>Compare with the 2-array
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-i 1 4))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:1:4┐
- │0│1│2│3│
- └─┴─┴─┴─┘
- </pre></div>
- <p>Another 2-array:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-i 3 4) #:prefix? #f)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">┌─┬─┬──┬──┐
- │0│1│ 2│ 3│
- ├─┼─┼──┼──┤
- │4│5│ 6│ 7│
- ├─┼─┼──┼──┤
- │8│9│10│11│
- └─┴─┴──┴──┘
- </pre></div>
- <p>A 5-array:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-i 2 2 3 2 4) #:prefix? #f)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">┃═══════════╦═══════════╦═══════════┃═══════════╦═══════════╦═══════════┃
- ┃ 0│ 1│ 2│ 3║ 8│ 9│10│11║16│17│18│19┃48│49│50│51║56│57│58│59║64│65│66│67┃
- ┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃
- ┃ 4│ 5│ 6│ 7║12│13│14│15║20│21│22│23┃52│53│54│55║60│61│62│63║68│69│70│71┃
- ┃═══════════╬═══════════╬═══════════┃═══════════╬═══════════╬═══════════┃
- ┃24│25│26│27║32│33│34│35║40│41│42│43┃72│73│74│75║80│81│82│83║88│89│90│91┃
- ┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃
- ┃28│29│30│31║36│37│38│39║44│45│46│47┃76│77│78│79║84│85│86│87║92│93│94│95┃
- ┃═══════════╩═══════════╩═══════════┃═══════════╩═══════════╩═══════════┃
- </pre></div>
- <p>The same 5-array in compact mode:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-i 2 2 3 2 4) #:prefix? #f #:compact 1)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">║───────────┬───────────┬───────────║───────────┬───────────┬───────────║
- ║ 0 1 2 3│ 8 9 10 11│16 17 18 19║48 49 50 51│56 57 58 59│64 65 66 67║
- ║ 4 5 6 7│12 13 14 15│20 21 22 23║52 53 54 55│60 61 62 63│68 69 70 71║
- ║───────────┼───────────┼───────────║───────────┼───────────┼───────────║
- ║24 25 26 27│32 33 34 35│40 41 42 43║72 73 74 75│80 81 82 83│88 89 90 91║
- ║28 29 30 31│36 37 38 39│44 45 46 47║76 77 78 79│84 85 86 87│92 93 94 95║
- ║───────────┴───────────┴───────────║───────────┴───────────┴───────────║
- </pre></div>
- <span id="index-SRFI_002d163-1"></span>
- <p>A nested array (example from [<a href="#Sources">SRFI-163</a>]
- ):
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (call-with-input-string "#%2@1:2@1:3((#%2((1 2) (3 4)) 9 #%2((3 4) (5 6)))
- (#%(42 43) #%2((8 7 6)) #%2((90 91) (100 101))))))"
- read))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2@1:2@1:3─────┬─────────┐
- │#%2:2:2│ 9│ #%2:2:2│
- ││1│2│ │ │ │3│4│ │
- │├─┼─┤ │ │ ├─┼─┤ │
- ││3│4│ │ │ │5│6│ │
- │└─┴─┘ │ │ └─┴─┘ │
- ├───────┼───────┼─────────┤
- │#%1:2 │#%2:1:3│#%2:2:2─┐│
- ││42│43│││8│7│6│││ 90│ 91││
- │ │└─┴─┴─┘│├───┼───┤│
- │ │ ││100│101││
- │ │ │└───┴───┘│
- └───────┴───────┴─────────┘
- </pre></div>
- <p>Looking at the return value when <var>port</var> is <code>#f</code>:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-format (ra-i 2 3) #f #:prefix? #f) #:prefix? #f)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">┌─┬─┬─┬─┬─┬─┬─┐
- │┌│─│┬│─│┬│─│┐│
- ├─┼─┼─┼─┼─┼─┼─┤
- │││0│││1│││2│││
- ├─┼─┼─┼─┼─┼─┼─┤
- │├│─│┼│─│┼│─│┤│
- ├─┼─┼─┼─┼─┼─┼─┤
- │││3│││4│││5│││
- ├─┼─┼─┼─┼─┼─┼─┤
- │└│─│┴│─│┴│─│┘│
- └─┴─┴─┴─┴─┴─┴─┘
- </pre></div>
- <p>The same array with <code>#:compact 2</code>:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-format (ra-i 2 3) #f #:prefix? #f) #:prefix? #f #:compact 2)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">┌╌╌╌╌╌╌╌┐
- ┆┌─┬─┬─┐┆
- ┆│0│1│2│┆
- ┆├─┼─┼─┤┆
- ┆│3│4│5│┆
- ┆└─┴─┴─┘┆
- └╌╌╌╌╌╌╌┘
- </pre></div>
- <p>Using a custom element formatter:
- </p><div class="example">
- <pre class="verbatim">(ra-format (ra-map! (make-ra #f 4 4) sqrt (ra-reshape (ra-iota 20 -10) 0 4 4))
- #:fmt (λ (x) (format #f (cond ((real? x) "~4,2f")
- ((complex? x) "~4,2i")
- (else "~a"))
- x)))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2:4:4────┬──────────┬──────────┬──────────┐
- │0.00+3.16i│0.00+3.00i│0.00+2.83i│0.00+2.65i│
- ├──────────┼──────────┼──────────┼──────────┤
- │0.00+2.45i│0.00+2.24i│0.00+2.00i│0.00+1.73i│
- ├──────────┼──────────┼──────────┼──────────┤
- │0.00+1.41i│0.00+1.00i│ 0.00│ 1.00│
- ├──────────┼──────────┼──────────┼──────────┤
- │ 1.41│ 1.73│ 2.00│ 2.24│
- └──────────┴──────────┴──────────┴──────────┘
- </pre></div>
- <p>If any of the lengths of <var>ra</var> is 0, only the prefix is printed.
- </p>
- <p>This function doesn’t handle large arrays in any particular way. User beware!
- </p>
- <p>See also: <a href="#x_002dra_002dprint"><code>ra-print</code></a>, <a href="#x_002dstar_002dra_002dprint_002dstar"><code>*ra-print*</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002di"></span>
- <span id="x_002dra_002di"></span><dl class="def">
- <dt id="index-ra_002di-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-i</strong> <em>bounds ...</em><a href='#index-ra_002di-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Create a multidimensional index array with the given <var>bounds</var>. Each of the bounds may be an integer (a length) or a pair of integers (lower and upper bounds).
- </p>
- <p>The root is of type <code>d</code>. The first upper bound that isn’t <code>#f</code> may be <code>#t</code>; this creates an unbounded axis.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-i 2 3 4)
- </pre><pre class="example">⇒ #%3d:2:3:4(((0 1 2 3) (4 5 6 7) (8 9 10 11)) ((12 13 14 15) (16 17 18 19) (20 21 22 23)))
- </pre></div>
- <p>See also: <a href="#x_002dra_002diota"><code>ra-iota</code></a>, <a href="#x_002dra_002dindex_002dmap_0021"><code>ra-index-map!</code></a>. <a id="DOCF12" href="#FOOT12"><sup>12</sup></a>
- </p>
- </dd></dl>
- <span id="index-ra_002dindex_002dmap_0021"></span>
- <span id="x_002dra_002dindex_002dmap_0021"></span><dl class="def">
- <dt id="index-ra_002dindex_002dmap_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-index-map!</strong> <em>a op ⇒ a</em><a href='#index-ra_002dindex_002dmap_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Iterate over array <var>a</var> in unspecified order, assigning to each element the result of <code>(op i₀ ...)</code>, where <code>i₀ ...</code> are the indices of that element.
- </p>
- <p>For example:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-index-map! (make-ra #t 3 4) -)
- (ra-map! (make-ra #t 3 4) - (ra-iota) (ra-transpose (ra-iota) 1)) ; same thing
- </pre><pre class="example">⇒ <code>#%2:3:4((0 -1 -2 -3) (1 0 -1 -2) (2 1 0 -1))</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>, <a href="#Iteration">Iteration</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002diota"></span>
- <span id="x_002dra_002diota"></span><dl class="def">
- <dt id="index-ra_002diota-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-iota</strong> <em>len [lo [step]]</em><a href='#index-ra_002diota-1' class='copiable-anchor'> ¶</a></span></dt>
- <dt id="index-ra_002diota-2"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-iota</strong><a href='#index-ra_002diota-2' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Create rank-1 index array. The root is of type <code>d</code>. <var>lo</var> defaults to 0 and <var>step</var> to 1.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-iota 4 3 -1)
- </pre><pre class="example">⇒ #%1d:4(3 2 1 0)
- </pre></div>
- <p><code>(ra-iota)</code> is unbounded both ways, e.g.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-shape (ra-iota))
- </pre><pre class="example">⇒ <code>((#f #f))</code>
- </pre><pre class="verbatim">((ra-iota) -100000000000)
- </pre><pre class="example">⇒ -100000000000
- </pre></div>
- <p>See also: <a href="#x_002dra_002di"><code>ra-i</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dcat"></span>
- <span id="x_002dra_002dcat"></span><dl class="def">
- <dt id="index-ra_002dcat-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-cat</strong> <em>type i a ... ⇒ b</em><a href='#index-ra_002dcat-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Concatenate arrays <var>a</var> ... along axis <var>i</var>. The arguments are prefix-matched and rank extended before concatenation. All axes must match, other than the concatenation axis.
- </p>
- <p>This function always produces a new array, of the type given. If <var>type</var> is <code>#f</code> then the type of the first <var>a</var> is used, unless that is <code>d</code>, in which case the result is of type <code>#t</code>. The lower bound in the concatenation axis of the result is 0; the lower bounds of the arguments in the concatenation axis are ignored.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cat #f 1 #%1(a b) #%2((0 1) (2 3)))
- </pre><pre class="example">⇒ #%2((a 0 1) (b 2 3))
- </pre></div>
- <p>See also: <a href="#x_002dra_002dcats"><code>ra-cats</code></a>, <a href="#x_002dra_002dtile"><code>ra-tile</code></a>, <a href="#Concatenation">Concatenation</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dcats"></span>
- <span id="x_002dra_002dcats"></span><dl class="def">
- <dt id="index-ra_002dcats-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-cats</strong> <em>type i a ... ⇒ b</em><a href='#index-ra_002dcats-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Concatenate <var>i</var>-items of arrays <var>a</var> ... . The arguments are suffix-matched and rank extended before concatenation. All axes must match, other than the concatenation axis.
- </p>
- <p>This function always produces a new array, of the type given. If <var>type</var> is <code>#f</code> then the type of the first <var>a</var> is used, unless that is <code>d</code>, in which case the result is of type <code>#t</code>. The lower bound in the concatenation axis of the result is 0; the lower bounds of the arguments in the concatenation axis are ignored.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-cats #t 1 #%2((0 1) (2 3)) #%(a b))
- </pre><pre class="example">⇒ #%2((0 1) (2 3) (a b))
- </pre></div>
- <p>See also: <a href="#x_002dra_002dcat"><code>ra-cat</code></a>, <a href="#x_002dra_002dtile"><code>ra-tile</code></a>, <a href="#Concatenation">Concatenation</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dcopy"></span>
- <span id="x_002dra_002dcopy"></span><dl class="def">
- <dt id="index-ra_002dcopy-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-copy</strong> <em>src ⇒ dst</em><a href='#index-ra_002dcopy-1' class='copiable-anchor'> ¶</a></span></dt>
- <dt id="index-ra_002dcopy-2"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-copy</strong> <em>type src ⇒ dst</em><a href='#index-ra_002dcopy-2' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Create a new array of type <var>type</var> and copy <var>src</var> into it. If <var>type</var> is <code>#f</code> or isn’t given, use the type of <var>src</var>, unless that type is <code>d</code>, in which case the result is of type <code>#t</code>.
- </p>
- <p>See also <a href="#x_002dra_002dcopy_0021"><code>ra-copy!</code></a> <a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a> <a href="#x_002dra_002dset_0021"><code>ra-set!</code></a>.
- </p></dd></dl>
- <span id="index-ra_002dcopy_0021"></span>
- <span id="x_002dra_002dcopy_0021"></span><dl class="def">
- <dt id="index-ra_002dcopy_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-copy!</strong> <em>dst src ⇒ dst</em><a href='#index-ra_002dcopy_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Copy <var>src</var> to <var>dst</var>. The arguments must have matching shapes and be of compatible types.
- </p>
- <p>For valid arguments, this is equivalent to any one of
- </p><pre class="verbatim">(ra-map! dst values src)
- (ra-amend! dst src)
- </pre>
- <p>See also <a href="#x_002dra_002dcopy"><code>ra-copy</code></a> <a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a> <a href="#x_002dra_002dset_0021"><code>ra-set!</code></a> <a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dequal_003f"></span>
- <span id="x_002dra_002dequal_003f"></span><dl class="def">
- <dt id="index-ra_002dequal_003f-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-equal?</strong> <em>a ... → boolean</em><a href='#index-ra_002dequal_003f-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Return <code>#t</code> if the arrays <var>a</var> ... have the same shapes and types and their
- corresponding elements are all <code>equal?</code> to each other, or <code>#f</code> otherwise.
- </p>
- <p>Note that this function isn’t rank extending; the shapes of the arguments must be the same, not just match. Here’s a rank-extending version:
- </p>
- <div class="example">
- <pre class="verbatim">(import (ice-9 control))
- (define (ra-equal? . a) (let/ec exit (apply ra-for-each (λ a (unless (apply equal? a) (exit #f))) a) #t))
- </pre></div>
- <p>See also: <a href="#x_002dra_002dfor_002deach"><code>ra-for-each</code></a>, <a href="#x_002dra_002dfold"><code>ra-fold</code></a>, <a href="#x_002dra_002devery"><code>ra-every</code></a>, <a href="#x_002dra_002dany"><code>ra-any</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002devery"></span>
- <span id="x_002dra_002devery"></span><dl class="def">
- <dt id="index-ra_002devery-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-every</strong> <em>pred? a ...</em><a href='#index-ra_002devery-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>See also: <a href="#x_002dra_002dfold"><code>ra-fold</code></a>, <a href="#x_002dra_002dany"><code>ra-any</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dfill_0021"></span>
- <span id="x_002dra_002dfill_0021"></span><dl class="def">
- <dt id="index-ra_002dfill_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-fill!</strong> <em>dst value ⇒ dst</em><a href='#index-ra_002dfill_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Assign <var>value</var> to each element of <var>dst</var>. The arguments must be of compatible types.
- </p>
- <p>This is equivalent to any one of
- </p><div class="example">
- <pre class="verbatim">(ra-map! dst (const value))
- (ra-copy! dst (make-ra value))
- (ra-amend! dst (make-ra value))
- (ra-amend! dst value) ; when value isn't an array
- </pre></div>
- <p>Compare
- </p>
- <div class="example">
- <pre class="verbatim">(ra-fill! (make-ra #f 2 2) (make-ra 'x))
- </pre><pre class="example">⇒ #%2:2:2((#%0(x) #%0(x)) (#%0(x) #%0(x)))
- </pre><pre class="verbatim">(ra-amend! (make-ra #f 2 2) 'x)
- </pre><pre class="example">⇒ #%2:2:2((x x) (x x))
- </pre><pre class="verbatim">(ra-amend! (make-ra #f 2 2) (make-ra 'x))
- </pre><pre class="example">⇒ #%2:2:2((x x) (x x))
- </pre><pre class="verbatim">(ra-amend! (make-ra #f 2 2) (make-ra (make-ra 'x)))
- </pre><pre class="example">⇒ #%2:2:2((#%0(x) #%0(x)) (#%0(x) #%0(x)))
- </pre></div>
- <p>See also: <a href="#x_002dra_002dset_0021"><code>ra-set!</code></a>, <a href="#x_002dra_002dcopy_0021"><code>ra-copy!</code></a>, <a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dfold"></span>
- <span id="x_002dra_002dfold"></span><dl class="def">
- <dt id="index-ra_002dfold-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-fold</strong> <em>op knil a ...</em><a href='#index-ra_002dfold-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Returns <code>(... (op (op knil a₀ ...) a₁ ...) ...)</code>, where <var>a</var>₀ <var>a</var>₁ ... is the row-major ravel of <var>a</var> (after rank extension). The shapes of <var>a</var> ... must match. Example:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-fold list 99 (ra-i 2) (ra-i 2 3))
- </pre><pre class="example">⇒ <code>((((((99 0 0) 0 1) 0 2) 1 3) 1 4) 1 5)</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002devery"><code>ra-every</code></a>, <a href="#x_002dra_002dany"><code>ra-any</code></a>, <a href="#Iteration">Iteration</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dfor_002deach"></span>
- <span id="x_002dra_002dfor_002deach"></span><dl class="def">
- <dt id="index-ra_002dfor_002deach-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-for-each</strong> <em>op a ...</em><a href='#index-ra_002dfor_002deach-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Apply <var>op</var> to each tuple of elements from arrays <var>a</var> ... The shapes of <var>a</var> must match.
- </p>
- <p>See also: <a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>, <a href="#x_002dra_002dmap_0021"><code>ra-map</code></a>, <a href="#Iteration">Iteration</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dfrom"></span>
- <span id="x_002dra_002dfrom"></span><dl class="def">
- <dt id="index-ra_002dfrom-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-from</strong> <em>a i ... → b</em><a href='#index-ra_002dfrom-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Outer product slice of <var>a</var> by indices <var>i</var> ...
- </p>
- <p>The shape of <var>b</var> is the concatenation of the shapes of <var>i</var>... and the
- contents are obtained by looking up in each dimension of <var>a</var> by the indices <var>i</var>,
- that is
- </p>
- <div class="example">
- <pre class="verbatim">b(j₀₀ j₀₁ ... j₁₀ j₁₁ ...) = a(i₀(j₀₀ j₀₁ ...) i₁(j₁₀ j₁₁ ...) ...)
- </pre></div>
- <p>where <var>i</var> : <var>i₀</var> <var>i₁</var> ... The special value <code>#t</code> is understood as the full range of <var>a</var> on that axis.
- </p>
- <p>Additionally, if each of the <var>i</var> ... is one of
- </p><ul>
- <li> <code>#t</code>
- </li><li> an array of type <code>d</code>
- </li><li> an array of rank 0
- </li><li> an integer
- </li></ul>
- <p>then the result <var>b</var> shares the root of <var>a</var>. In all other cases a new root is allocated for the result. For example
- </p>
- <div class="example">
- <pre class="verbatim">(define a (list->ra 2 '((1 2 3) (a b c))))
- (define b (ra-from a #t (ra-iota 3 2 -1))) ; same as (ra-reverse a 1)
- b
- </pre><pre class="example">⇒ <code>#%2:2:3((3 2 1) (c b a))</code>
- </pre><pre class="verbatim">(eq? (ra-root a) (ra-root b))
- </pre><pre class="example">⇒ <code>#t</code>
- </pre><pre class="verbatim">(define c (ra-from a #t (list->ra 1 '(2 1 0))))
- b
- </pre><pre class="example">⇒ <code>#%2:2:3((3 2 1) (c b a))</code>
- </pre><pre class="verbatim">(eq? (ra-root a) (ra-root c))
- </pre><pre class="example">⇒ <code>#f</code>
- </pre></div>
- <p>Unbounded indices aren’t treated especially, so they are only valid if the relevant axis of <var>ra</var> is itself unbounded.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-i #t 4)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:f:4──┐
- │0│1│ 2│ 3│
- ├─┼─┼──┼──┤
- │4│5│ 6│ 7│
- ├─┼─┼──┼──┤
- │8│9│10│11│
- ...........
- </pre><pre class="verbatim">(ra-from (ra-i #t 4) (ra-iota #f 0 2))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:f:4─┬──┐
- │ 0│ 1│ 2│ 3│
- ├──┼──┼──┼──┤
- │ 8│ 9│10│11│
- ├──┼──┼──┼──┤
- │16│17│18│19│
- .............
- </pre></div>
- <p>The type of <var>b</var> is the same as that of <var>a</var>, with the only exception that if the type of <var>a</var> is <code>d</code> and the root of <var>b</var> cannot be shared with the root of <var>a</var>, then the type of <var>b</var> is <code>#t</code>.
- </p>
- <p><code>ra-from</code> always returns an array, even if the result has rank 0. This is in contrast to array application (see <a href="#Slicing">Slicing</a>).
- </p>
- <div class="example">
- <pre class="verbatim">(define A (list->ra 2 '((1 a) (2 b) (3 c))))
- (ra-from A 2 1)
- </pre><pre class="example">⇒ #%0(b)
- </pre><pre class="verbatim">(A 2 1)
- </pre><pre class="example">⇒ b
- </pre></div>
- <p>See also: <a href="#x_002dra_002dcell"><code>ra-cell</code></a>, <a href="#x_002dra_002dref"><code>ra-ref</code></a>, <a href="#x_002dra_002dslice"><code>ra-slice</code></a>, <a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a>, <a href="#Slicing">Slicing</a>.<a id="DOCF13" href="#FOOT13"><sup>13</sup></a>
- </p>
- </dd></dl>
- <span id="index-ra_002dfrom_002dcopy"></span>
- <span id="x_002dra_002dfrom_002dcopy"></span><dl class="def">
- <dt id="index-ra_002dfrom_002dcopy-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-from-copy</strong> <em>a i ... ⇒ b</em><a href='#index-ra_002dfrom_002dcopy-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Like <code>ra-from</code>, but always return a newly allocated array. This is equivalent to <code>(ra-copy (ra-from a i ...))</code>, but it doesn’t incur a second copy in case <code>ra-from</code> already allocates a new array.
- </p>
- <p>See also: <a href="#x_002dra_002dfrom"><code>ra-from</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dmap"></span>
- <span id="x_002dra_002dmap"></span><dl class="def">
- <dt id="index-ra_002dmap-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-map</strong> <em>type op a0 a ... ⇒ dst</em><a href='#index-ra_002dmap-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Same as <a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>, but create the result array from the arguments. Unlike <code>ra-map!</code>, this function requires at least one source argument.
- </p>
- <p>The type of the result <var>dst</var> is <var>type</var> unless that is <code>#f</code>, in which case the type of <var>a0</var> is used, unless that is <code>'d</code>, in which case the result is of type <code>#t</code>. For the shape of <var>dst</var> see <a href="#Automatic-result-arrays">Automatic result arrays</a>.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-map 'f64 + (ra-iota 3 1) (ra-i 3 4)))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2f64:3:4┬────┬────┐
- │ 1.0│ 2.0│ 3.0│ 4.0│
- ├────┼────┼────┼────┤
- │ 6.0│ 7.0│ 8.0│ 9.0│
- ├────┼────┼────┼────┤
- │11.0│12.0│13.0│14.0│
- └────┴────┴────┴────┘
- </pre></div>
- <p>See also: <a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>, <a href="#x_002dra_002dcopy"><code>ra-copy</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dmap_0021"></span>
- <span id="x_002dra_002dmap_0021"></span><dl class="def">
- <dt id="index-ra_002dmap_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-map!</strong> <em>dst op a ... ⇒ dst</em><a href='#index-ra_002dmap_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Iterate over arrays <var>dst</var> <var>a</var> ... applying <var>op</var> to the respective elements in <var>a</var>, and storing the result in the respective element of <var>dst</var>. The arguments must have matching shapes and the type of <var>dst</var> must be compatible with the results of <var>op</var>.
- </p>
- <p>This is equivalent to
- </p><pre class="verbatim">(apply ra-slice-for-each
- (rank dst)
- (λ (dst . a)
- (ra-set! dst (apply op (map ra-ref a))))
- dst a)
- </pre>
- <p>See also: <a href="#x_002dra_002dmap"><code>ra-map</code></a>, <a href="#x_002dra_002dfor_002deach"><code>ra-for-each</code></a>, <a href="#x_002dra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>, <a href="#Iteration">Iteration</a>.
- </p>
- </dd></dl>
- <span id="index-packed-array-1"></span>
- <span id="index-ra_002dorder_002dc_003f"></span>
- <span id="x_002dra_002dorder_002dc_003f"></span><dl class="def">
- <dt id="index-ra_002dorder_002dc_003f-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-order-c?</strong> <em>a [n [org]]</em><a href='#index-ra_002dorder_002dc_003f-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Check whether axes [<var>org</var> ... <var>org</var>+<var>n</var>) of <var>a</var> are in row-major order. <var>org</var> defaults to 0.
- </p>
- <p>If <var>n</var> isn’t given, check that the whole array is in row-major order, and additionally that the step on the last axis is 1 (i.e. the array is ‘packed’).
- </p>
- <p><code>(ra-order-c? a n org)</code> implies <code>(eq? (ra-root a) (ra-root (<a href="#x_002dra_002dravel"><code>ra-ravel</code></a> a n org)))</code>. Note that the stronger condition <code>(ra-order-c? a)</code> is not necessary for <code>(eq? (ra-root a) (ra-root (ra-ravel a)))</code> to hold.
- </p>
- </dd></dl>
- <span id="index-ra_002dprint"></span>
- <span id="x_002dra_002dprint"></span><dl class="def">
- <dt id="index-ra_002dprint-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-print</strong> <em>ra [port]</em><a href='#index-ra_002dprint-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Print an array to <var>port</var>. <var>port</var> defaults to <code>(current-output-port)</code>.
- </p>
- <p>This is the default array printer. The result is meant to be back-readable, although some special arrays are not supported yet.
- </p>
- <p>See also: <a href="#x_002dra_002dformat"><code>ra-format</code></a>, <a href="#x_002dstar_002dra_002dprint_002dstar"><code>*ra-print*</code></a>, <a href="#x_002dstar_002dra_002dparenthesized_002drank_002dzero_002dstar"><code>*ra-parenthesized-rank-zero*</code></a>.
- </p></dd></dl>
- <span id="index-print-prefix"></span>
- <span id="index-ra_002dprint_002dprefix"></span>
- <span id="x_002dra_002dprint_002dprefix"></span><dl class="def">
- <dt id="index-ra_002dprint_002dprefix-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-print-prefix</strong> <em>ra port #:dims?</em><a href='#index-ra_002dprint_002dprefix-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Return the print prefix for array <var>ra</var>. This is a string that details the type, rank, and (optionally) the dimensions of <var>ra</var>, and is part of the default read syntax for arrays. This is the same syntax as that of the <a href="https://www.gnu.org/software/guile/manual/html_node/Array-Syntax.html">the built in Guile arrays</a>, except that <var>dims?</var> defaults to true and <code>#%</code> is used instead of <code>#</code>.
- </p>
- <p>This function is provided by the module <code>(newra print)</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(call-with-output-string (cut ra-print-prefix (make-ra 4 '(3 4) '(2 3)) <>))
- </pre><pre class="example">⇒ <code>"#%2@3:2@2:2"</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(call-with-output-string (cut ra-print-prefix (make-ra 4 '(3 4) '(2 3)) <> #:dims? #t))
- </pre><pre class="example">⇒ <code>"#%2@3@2"</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002dformat"><code>ra-format</code></a>, <a href="#Writing-and-reading">Writing and reading</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dravel"></span>
- <span id="x_002dra_002dravel"></span><dl class="def">
- <dt id="index-ra_002dravel-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-ravel</strong> <em>a [n [org]] ⇒ b</em><a href='#index-ra_002dravel-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Ravel axes [<var>org</var> ... <var>org</var>+<var>n</var>) of array <var>a</var> in row-major order. <var>n</var> defaults to the rank of <var>a</var> and <var>org</var> defaults to 0.
- </p>
- <p>For example:
- </p><div class="example">
- <pre class="verbatim">(ra-ravel (ra-i 2 3))
- </pre><pre class="example">⇒ #%1d:6(0 1 2 3 4 5)
- </pre></div>
- <p>Consider this 3-array:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-i 2 3 4))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%3d:2:3:4║──┬──┬──┬──║
- ║0│1│ 2│ 3║12│13│14│15║
- ║─┼─┼──┼──║──┼──┼──┼──║
- ║4│5│ 6│ 7║16│17│18│19║
- ║─┼─┼──┼──║──┼──┼──┼──║
- ║8│9│10│11║20│21│22│23║
- ║─┴─┴──┴──║──┴──┴──┴──║
- </pre></div>
- <p>Ravel axes 0..1:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-ravel (ra-i 2 3 4) 2)) ; or (ra-ravel ... 2 0)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:6:4─┬──┐
- │ 0│ 1│ 2│ 3│
- ├──┼──┼──┼──┤
- │ 4│ 5│ 6│ 7│
- ├──┼──┼──┼──┤
- │ 8│ 9│10│11│
- ├──┼──┼──┼──┤
- │12│13│14│15│
- ├──┼──┼──┼──┤
- │16│17│18│19│
- ├──┼──┼──┼──┤
- │20│21│22│23│
- └──┴──┴──┴──┘
- </pre></div>
- <p>Ravel axes 1..2:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-ravel (ra-i 2 3 4) 2 1))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim"></pre><pre class="example">#%2d:2:12┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
- │ 0│ 1│ 2│ 3│ 4│ 5│ 6│ 7│ 8│ 9│10│11│
- ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
- │12│13│14│15│16│17│18│19│20│21│22│23│
- └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
- </pre></div>
- <p>To ravel other combinations of axes, use <a href="#Transposition">Transposition</a>.
- </p>
- <span id="index-packed-array-2"></span>
- <p>The full ravel of an array doesn’t necessarily result in a rank-1 ‘packed’ array, that is, one where the step is 1. If that is required, one can use <code>(ra-ravel (ra-copy ra))</code>. <a id="DOCF14" href="#FOOT14"><sup>14</sup></a>.
- </p>
- <p>See also: <a href="#x_002dra_002dreshape"><code>ra-reshape</code></a>, <a href="#x_002dra_002dtile"><code>ra-tile</code></a>, <a href="#Reshaping">Reshaping</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dref"></span>
- <span id="x_002dra_002dref"></span><dl class="def">
- <dt id="index-ra_002dref-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-ref</strong> <em>a i ...</em><a href='#index-ra_002dref-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Look up element of array <var>a</var>. The indices <var>i ...</var> must be integers within the bounds of <var>a</var>. It is an error if the number of <var>i ...</var> doesn’t match the rank of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002dcell"><code>ra-cell</code></a>, <a href="#x_002dra_002dslice"><code>ra-slice</code></a>, <a href="#x_002dra_002dfrom"><code>ra-from</code></a>, <a href="#x_002dra_002dset_0021"><code>ra-set!</code></a>, <a href="#Slicing">Slicing</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dreshape"></span>
- <span id="x_002dra_002dreshape"></span><dl class="def">
- <dt id="index-ra_002dreshape-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-reshape</strong> <em>a k bounds ... ⇒ b</em><a href='#index-ra_002dreshape-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Reshape axis <var>k</var> of array <var>a</var> to <var>bounds</var>.
- </p>
- <p>Each of <var>bounds</var> may be an integer (a length) or a pair of integers (lower and upper bounds), or <code>#f</code>. No more than one of <var>bounds</var> may be <code>#f</code>.
- </p>
- <div class="example">
- <pre class="verbatim">(define a (ra-i 4 3))
- (ra-format a)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:4:3┐
- │0│ 1│ 2│
- ├─┼──┼──┤
- │3│ 4│ 5│
- ├─┼──┼──┤
- │6│ 7│ 8│
- ├─┼──┼──┤
- │9│10│11│
- └─┴──┴──┘
- </pre><pre class="verbatim">(ra-format (ra-reshape a 0 2 2))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%3d:2:2:3─┬──║
- ║0│1│2║6│ 7│ 8║
- ║─┼─┼─║─┼──┼──║
- ║3│4│5║9│10│11║
- ║─┴─┴─║─┴──┴──║
- </pre></div>
- <p>If one of <var>bounds</var> is <code>#f</code>, the missing length is computed as <code>(/ (ra-len ra k) n)</code> where <var>n</var> is the total size of the <var>bounds</var> that are not <code>#f</code>. It is an error if this isn’t a non-negative integer.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-reshape (ra-iota 12) 0 2 2 #f) ; #f will be 3 = 12/(2*2)
- </pre><pre class="example">⇒ <code>#%3d:2:2:3(((0 1 2) (3 4 5)) ((6 7 8) (9 10 11)))</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-reshape (ra-iota 7) 0 3 #f)
- </pre><pre class="example">⇒ <code>error ; bad-placeholder 7/3</code>
- </pre></div>
- <p>It is an error if the product of the lengths in <var>bounds</var> exceeds the length of axis <var>k</var> of <var>a</var>. For example
- </p>
- <div class="example">
- <pre class="verbatim">(ra-reshape (ra-i 8 2) 0 2 3)
- </pre><pre class="example">⇒ <code>#%3d:2:3:2(((0 1) (2 3) (4 5)) ((6 7) (8 9) (10 11))</code> ; ok, 8 can be reshaped into 2·3
- </pre><pre class="verbatim">(ra-reshape (ra-i 8 2) 0 4 3)
- </pre><pre class="example">⇒ error ; 8 cannot be reshaped into 4·3
- </pre></div>
- <span id="index-bounds-1"></span>
- <p><code>ra-reshape</code> may be used to change either of the bounds of an axis, not only its length. For example
- </p>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-i 2 3))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:2:3
- │0│1│2│
- ├─┼─┼─┤
- │3│4│5│
- └─┴─┴─┘
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-reshape (ra-i 2 3) 0 '(1 2)))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d@1:2:3
- │0│1│2│
- ├─┼─┼─┤
- │3│4│5│
- └─┴─┴─┘
- </pre></div>
- <p>The result of <code>ra-reshape</code> always shares the root of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002dravel"><code>ra-ravel</code></a>, <a href="#x_002dra_002dtile"><code>ra-tile</code></a>, <a href="#Reshaping">Reshaping</a>.
- </p>
- </dd></dl>
- <span id="index-_005b_003f_005d_002c-reverse"></span>
- <span id="index-ra_002dreverse"></span>
- <span id="x_002dra_002dreverse"></span><dl class="def">
- <dt id="index-ra_002dreverse-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-reverse</strong> <em>a axes ... ⇒ b</em><a href='#index-ra_002dreverse-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Reverse the given <var>axes</var> of <var>a</var>, that is, the order of the elements along those axes. The bounds do not change.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-reverse (ra-i 2 3) 0 1)
- </pre><pre class="example">⇒ #%1d:2:3((5 4 3) (2 1 0))
- </pre></div>
- <p>The reversed array shares the root of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002drotate"><code>ra-rotate</code></a>, <a href="#x_002dra_002drotate"><code>ra-rotate!</code></a>.
- </p>
- </dd></dl>
- <span id="index-_005b_003f_005d_002c-rotate"></span>
- <span id="index-_005b_003f_005d_002c-rowel"></span>
- <span id="index-ra_002drotate"></span>
- <span id="x_002dra_002drotate"></span><dl class="def">
- <dt id="index-ra_002drotate-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-rotate</strong> <em>n a ⇒ b</em><a href='#index-ra_002drotate-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Rotate the first axis of <var>a</var> toward the lower indices (‘to the left’) <var>n</var> times. <var>n</var> may be any integer. The result has the type of <var>a</var>, unless that type is <code>d</code>, in which case the result is of type <code>#t</code>.
- </p>
- <p>This function always returns a new array.
- </p>
- <p>Example:
- </p><div class="example">
- <pre class="verbatim">(ra-rotate 1 (ra-i 3 2))
- </pre><pre class="example">⇒ #%1:3:2((2 3) (4 5) (0 1))
- </pre></div>
- <p>See also: <a href="#x_002dra_002drotate_0021"><code>ra-rotate!</code></a>, <a href="#x_002dra_002dreverse"><code>ra-reverse</code></a>.
- </p>
- </dd></dl>
- <span id="index-rotate_0021"></span>
- <span id="index-ra_002drotate_0021"></span>
- <span id="x_002dra_002drotate_0021"></span><dl class="def">
- <dt id="index-ra_002drotate_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-rotate!</strong> <em>n a ⇒ a</em><a href='#index-ra_002drotate_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Rotate in place the first axis of <var>a</var> to the left <var>n</var> times. <var>n</var> may be any integer. <var>a</var> must be writable. This function returns <var>a</var>.
- </p>
- <p>Example:
- </p><div class="example">
- <pre class="verbatim">(define a (ra-copy #t (ra-i 3 2)))
- (ra-rotate! 1 a)
- a
- </pre><pre class="example">⇒ #%1:3:2((2 3) (4 5) (0 1))
- </pre></div>
- <p>See also: <a href="#x_002dra_002drotate"><code>ra-rotate</code></a>, <a href="#x_002dra_002dreverse"><code>ra-reverse</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dslice_002dfor_002deach-1"></span>
- <span id="x_002dra_002dslice_002dfor_002deach"></span><dl class="def">
- <dt id="index-ra_002dslice_002dfor_002deach-2"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-slice-for-each</strong> <em>k op a ...</em><a href='#index-ra_002dslice_002dfor_002deach-2' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Iterate over the <var>k</var>-frames of arrays <var>a</var> ..., applying <var>op</var> to the respective slices. The arguments <var>a</var> ... must have matching <var>k</var>-frames.
- </p>
- <p>Note that it isn’t necessary for arguments <var>a</var> to have rank ≥ <var>k</var>. Arguments with rank < <var>k</var> are rank-extended and the corresponding arguments are 0-cells. For example:
- </p>
- <div class="example">
- <pre class="verbatim">(ra-slice-for-each 1
- (λ (a b) (display (list (a) (b))))
- (make-ra-root #(a b))
- (ra-i 2 3))
- </pre><pre class="example">⇒ <code>(a #%1d:3(0 1 2))(b #%1d:3(3 4 5))</code>
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-slice-for-each 2
- (λ (a b) (display (list (a) (b))))
- (make-ra-root #(a b))
- (ra-i 2 3))
- </pre><pre class="example">⇒ <code>(a 0)(a 1)(a 2)(b 3)(b 4)(b 5)</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002dmap_0021"><code>ra-map!</code></a>, <a href="#x_002dra_002dfor_002deach"><code>ra-for-each</code></a>, <a href="#Iteration">Iteration</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dset_0021"></span>
- <span id="x_002dra_002dset_0021"></span><dl class="def">
- <dt id="index-ra_002dset_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-set!</strong> <em>a value i ...</em><a href='#index-ra_002dset_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Assign <var>value</var> to array <var>a</var> at indices <var>i ...</var> It is an error if the number of <var>i ...</var> doesn’t match the rank of <var>a</var>.
- </p>
- <p>This function returns the modified array <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002damend_0021"><code>ra-amend!</code></a>, <a href="#x_002dra_002dref"><code>ra-ref</code></a>, <a href="#Slicing">Slicing</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dslice"></span>
- <span id="x_002dra_002dslice"></span><dl class="def">
- <dt id="index-ra_002dslice-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-slice</strong> <em>a i ...</em><a href='#index-ra_002dslice-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Look up cell of array <var>a</var>. The indices <var>i ...</var> must be integers within the bounds of <var>a</var>.
- </p>
- <p>This function returns a view of <var>a</var> with rank <var>k</var> equal to the rank of <var>a</var> minus the number of <var>i ...</var>, even if that is 0. It is an error if the number of <var>i ...</var> exceeds the rank of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002dcell"><code>ra-cell</code></a>, <a href="#x_002dra_002dref"><code>ra-ref</code></a>, <a href="#x_002dra_002dfrom"><code>ra-from</code></a>, <a href="#Slicing">Slicing</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dshape"></span>
- <span id="x_002dra_002dshape"></span><dl class="def">
- <dt id="index-ra_002dshape-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-shape</strong> <em>a ⇒ s</em><a href='#index-ra_002dshape-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Return the shape (a list of two-element lists, each containing the lower and upper bound of each axis) of array <var>a</var>.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-shape (make-ra 0 '(2 3) 4))
- </pre><pre class="example">⇒ <code>((2 3) (0 3))</code>
- </pre></div>
- <p>See also: <a href="#x_002dra_002ddimensions"><code>ra-dimensions</code></a>, <a href="#x_002dmake_002dra"><code>make-ra</code></a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dsingletonize"></span>
- <span id="x_002dra_002dsingletonize"></span><dl class="def">
- <dt id="index-ra_002dsingletonize-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-singletonize</strong> <em>a</em><a href='#index-ra_002dsingletonize-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd>
- <p>Return an array with the same root and dimensions as <var>a</var>, except that dead axes (axes with step 0 and undefined length) have their length set to 1.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-dimensions (ra-transpose (ra-i 2 3) 1))
- </pre><pre class="example">⇒ (#f 2 3)
- </pre><pre class="verbatim">(ra-dimensions (ra-singletonize (ra-transpose (ra-i 2 3) 1)))
- </pre><pre class="example">⇒ (1 2 3)
- </pre><pre class="verbatim">(ra-dimensions (ra-singletonize (ra-tile (ra-i 2 3) 0 4)))
- </pre><pre class="example">⇒ (4 2 3) ; no change
- </pre></div>
- </dd></dl>
- <span id="index-ra_002dswap_0021"></span>
- <span id="x_002dra_002dswap_0021"></span><dl class="def">
- <dt id="index-ra_002dswap_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-swap!</strong> <em>a b ⇒ a</em><a href='#index-ra_002dswap_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Swap the contents of <var>a</var> and <var>b</var>. The swap is executed in unspecified order, so the effect on <var>a</var> and <var>b</var> is undefined if <var>a</var> and <var>b</var> share storage.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-swap! (make-ra 2 3) (make-typed-ra 'f64 -1 3))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%1:3(-1.0 -1.0 -1.0)
- </pre></div>
- <p>See also <a href="#x_002dra_002dswap_002din_002dorder_0021"><code>ra-swap-in-order!</code></a> <a href="#x_002dra_002dcopy_0021"><code>ra-copy!</code></a>.
- </p></dd></dl>
- <span id="index-ra_002dswap_002din_002dorder_0021"></span>
- <span id="x_002dra_002dswap_002din_002dorder_0021"></span><dl class="def">
- <dt id="index-ra_002dswap_002din_002dorder_0021-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-swap-in-order!</strong> <em>a b ⇒ a</em><a href='#index-ra_002dswap_002din_002dorder_0021-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Swap the contents of <var>a</var> and <var>b</var>. The swap is executed in row-major order.
- </p></dd></dl>
- <span id="index-ra_002dtile"></span>
- <span id="x_002dra_002dtile"></span><dl class="def">
- <dt id="index-ra_002dtile-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-tile</strong> <em>a k bounds ... ⇒ b</em><a href='#index-ra_002dtile-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Replicate array <var>a</var> by inserting axes of <var>bounds ...</var> before axis <var>k</var>. If <var>t</var> is the shape of <var>a</var>, the shape of the result will be
- </p>
- <div class="example">
- <pre class="verbatim">[t₀ ... tₖ₋₁ s₀ ... tₖ ...]
- </pre></div>
- <p>Each of the bounds may be an integer (a length) or a pair of integers (lower and upper bounds).
- </p>
- <div class="example">
- <pre class="verbatim">(define a (ra-i 3 4))
- (ra-format a)
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%2d:3:4──┐
- │0│1│ 2│ 3│
- ├─┼─┼──┼──┤
- │4│5│ 6│ 7│
- ├─┼─┼──┼──┤
- │8│9│10│11│
- └─┴─┴──┴──┘
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-tile a 0 2))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%3d:2:3:4║─┬─┬──┬──║
- ║0│1│ 2│ 3║0│1│ 2│ 3║
- ║─┼─┼──┼──║─┼─┼──┼──║
- ║4│5│ 6│ 7║4│5│ 6│ 7║
- ║─┼─┼──┼──║─┼─┼──┼──║
- ║8│9│10│11║8│9│10│11║
- ║─┴─┴──┴──║─┴─┴──┴──║
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-tile a 1 2))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%3d:3:2:4┬─┬─┬─║─┬─┬──┬──║
- ║0│1│2│3║4│5│6│7║8│9│10│11║
- ║─┼─┼─┼─║─┼─┼─┼─║─┼─┼──┼──║
- ║0│1│2│3║4│5│6│7║8│9│10│11║
- ║─┴─┴─┴─║─┴─┴─┴─║─┴─┴──┴──║
- </pre></div>
- <div class="example">
- <pre class="verbatim">(ra-format (ra-tile a 2 2))
- </pre><pre class="example">⇒
- </pre><pre class="verbatim">#%3d:3:4:2─┬──║
- ║0│0║4│4║ 8│ 8║
- ║─┼─║─┼─║──┼──║
- ║1│1║5│5║ 9│ 9║
- ║─┼─║─┼─║──┼──║
- ║2│2║6│6║10│10║
- ║─┼─║─┼─║──┼──║
- ║3│3║7│7║11│11║
- ║─┴─║─┴─║──┴──║
- </pre></div>
- <p>Either <var>len</var> or <var>hi</var> being <code>#f</code> creates <a href="#x_002ddead_002daxes">dead axes</a>.
- </p><div class="example">
- <pre class="verbatim">(define a (ra-tile (ra-i 2 2) 0 #f #f))
- (define b (ra-transpose (ra-i 2 2) 2)) ; same thing
- </pre><pre class="example">⇒ <code>#%4d:d:d:2:2((((0 1) (2 3))))</code>
- </pre></div>
- <p>The tiled array shares the root of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002dravel"><code>ra-ravel</code></a>, <a href="#x_002dra_002dreshape"><code>ra-reshape</code></a>, <a href="#Reshaping">Reshaping</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002dtranspose"></span>
- <span id="x_002dra_002dtranspose"></span><dl class="def">
- <dt id="index-ra_002dtranspose-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-transpose</strong> <em>a axes ... ⇒ b</em><a href='#index-ra_002dtranspose-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Transpose axes 0, 1, ... of <var>a</var> to matching destination <var>axes</var>.
- </p>
- <div class="example">
- <pre class="verbatim">(ra-transpose (ra-i 2 3) 1 0)
- </pre><pre class="example">⇒ #%1d:3:2((0 3) (1 4) (2 5))
- </pre></div>
- <p>The transposed array shares the root of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002duntranspose"><code>ra-untranspose</code></a>, <a href="#Transposition">Transposition</a>.
- </p>
- </dd></dl>
- <span id="index-ra_002duntranspose"></span>
- <span id="x_002dra_002duntranspose"></span><dl class="def">
- <dt id="index-ra_002duntranspose-1"><span class="category">Function<!-- /@w -->: </span><span><strong>ra-untranspose</strong> <em>a axes ... ⇒ b</em><a href='#index-ra_002duntranspose-1' class='copiable-anchor'> ¶</a></span></dt>
- <dd><p>Transpose <var>axes</var> of <var>a</var> to matching destination axes 0, 1, ...
- </p>
- <div class="example">
- <pre class="verbatim">(ra-untranspose (ra-transpose (ra-i 2 3 4) 2 1 0) 2 1 0)
- </pre><pre class="example">⇒ <code>#%3d:2:3:4(((0 1 2 3) (4 5 6 7) (8 9 10 11)) ((12 13 14 15) (16 17 18 19) (20 21 22 23)))</code>
- </pre></div>
- <p>but
- </p>
- <div class="example">
- <pre class="verbatim">(ra-transpose (ra-transpose (ra-i 2 3 4) 2 1 0) 2 1 0)
- </pre><pre class="example">⇒ <code>#%3d:4:2:3(((0 4 8) (12 16 20)) ((1 5 9) (13 17 21)) ((2 6 10) (14 18 22)) ((3 7 11) (15 19 23)))</code>
- </pre></div>
- <p>The transposed array shares the root of <var>a</var>.
- </p>
- <p>See also: <a href="#x_002dra_002dtranspose"><code>ra-transpose</code></a>, <a href="#Transposition">Transposition</a>.
- </p>
- </dd></dl>
- <hr>
- </div>
- <div class="chapter" id="Cheatsheet">
- <div class="header">
- <p>
- Next: <a href="#Sources" accesskey="n" rel="next">Sources</a>, Previous: <a href="#Reference" accesskey="p" rel="prev">Reference</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Cheatsheet-1"></span><h2 class="chapter">6 Cheatsheet</h2>
- <p>Lines marked ∗ don’t work at the moment because of lack of support by the compiler; there should be a alternative listed, but the intent is that they work (eventually). For these and other examples that look poor, part of the purpose of this table is to encourage improvement...
- </p>
- <p>The APL examples assume <code>⎕io←0</code>. The <code>newra</code> examples use <code>(define ⍉ ra-transpose)</code>, which <code>newra</code> itself doesn’t provide.
- </p>
- <table>
- <tr><td width="20%"></td><td width="20%"><code>newra</code></td><td width="20%">APL</td><td width="20%"><span id="index-NumPy-3"></span>
- NumPy</td><td width="20%">Octave</td></tr>
- <tr><td width="20%">1×n array</td><td width="20%"><pre class="verbatim">∗ #%2((1 2 3))
- ────
- (list->ra 2 '((1 2 3)))
- ────
- (ra-reshape (list->ra 1 '(1 2 3)) 0 1 3)
- </pre></td><td width="20%"><pre class="verbatim">1 3 ⍴ 1 2 3
- </pre></td><td width="20%"><pre class="verbatim">np.array([1, 2, 3]).reshape(1, 3)
- </pre></td><td width="20%"><pre class="verbatim">[1 2 3]
- </pre></td></tr>
- <tr><td width="20%">n×1 array</td><td width="20%"><pre class="verbatim">∗ #%2((1) (2) (3))
- ────
- (list->ra 2 '((1) (2) (3)))
- ────
- (ra-reshape (list->ra 1 '(1 2 3)) 0 3 1)
- </pre></td><td width="20%"><pre class="verbatim">3 1 ⍴ 1 2 3
- </pre></td><td width="20%"><pre class="verbatim">np.array([1, 2, 3]).reshape(3, 1)
- </pre></td><td width="20%"><pre class="verbatim">[1 2 3].'
- </pre></td></tr>
- <tr><td width="20%">rank 1 array</td><td width="20%"><pre class="verbatim">∗ #%(1 2 3)
- ────
- (list->ra 1 '(1 2 3))
- </pre></td><td width="20%"><pre class="verbatim">1 2 3
- </pre></td><td width="20%"><pre class="verbatim">np.array([1, 2, 3])
- </pre></td><td width="20%">n/a</td></tr>
- <tr><td width="20%">integers from <var>a</var> to <var>b</var> with step size <var>k</var></td><td width="20%"><pre class="verbatim">(ra-iota (euclidean/ (- b a (- k)) k) a k)
- </pre></td><td width="20%"><pre class="verbatim">a + k × ι ⌊ (b-a) ÷ k
- </pre></td><td width="20%"><pre class="verbatim">np.arange(a, b+1, k)
- </pre></td><td width="20%"><pre class="verbatim">j:k:n
- </pre></td></tr>
- <tr><td width="20%">equispaced sequence [a .. b] with <var>n</var> points</td><td width="20%"><pre class="verbatim">(ra-iota n a (/ (- b a) (- n 1)))
- </pre></td><td width="20%"><pre class="verbatim">a + ((b-a) ÷ (n-1)) × ι n
- </pre></td><td width="20%"><pre class="verbatim">np.linspace(a, b, n)
- </pre></td><td width="20%"><pre class="verbatim">linspace(a, b, n)
- </pre></td></tr>
- <tr><td width="20%">integer sequence :p</td><td width="20%"><pre class="verbatim">(ra-iota n a k)
- </pre></td><td width="20%"><pre class="verbatim">a + k × ι n
- </pre></td><td width="20%"><pre class="verbatim">np.arange(a, a+k*n, k)
- </pre></td><td width="20%"><pre class="verbatim">a:(a+k*(n-1)):k
- </pre></td></tr>
- <tr><td width="20%">2x2 array</td><td width="20%"><pre class="verbatim">∗ #%2((1 2) (3 4))
- (list->ra 2 '((1 2) (3 4)))
- </pre></td><td width="20%"><pre class="verbatim">2 2 ⍴ 1 2 3 4
- </pre></td><td width="20%"><pre class="verbatim">p.array([[1, 2], [3, 4]])
- </pre></td><td width="20%"><pre class="verbatim">[1, 2; 3, 4]
- </pre></td></tr>
- <tr><td width="20%">array of zeros</td><td width="20%"><pre class="verbatim">(make-ra 0 2 2)
- </pre></td><td width="20%"><pre class="verbatim">2 2 ⍴ 0
- </pre></td><td width="20%"><pre class="verbatim">np.zeros((2, 2))
- </pre></td><td width="20%"><pre class="verbatim">zeros(2, 2)
- </pre></td></tr>
- <tr><td width="20%">array of ones</td><td width="20%"><pre class="verbatim">(make-ra 1 2 2)
- </pre></td><td width="20%"><pre class="verbatim">2 2 ⍴ 1
- </pre></td><td width="20%"><pre class="verbatim">np.ones((2, 2))
- </pre></td><td width="20%"><pre class="verbatim">ones(2, 2)
- </pre></td></tr>
- <tr><td width="20%">identity matrix</td><td width="20%"><pre class="verbatim">(let ((a (make-ra 0 2 2)))
- (ra-fill! (⍉ a 0 0) 1)
- a)
- </pre></td><td width="20%"><pre class="verbatim">2 2 ⍴ 1 , 2 ⍴ 0
- </pre></td><td width="20%"><pre class="verbatim">np.eye(2)
- </pre></td><td width="20%"><pre class="verbatim">eye(2, 2)
- </pre></td></tr>
- <tr><td width="20%">create diagonal matrix</td><td width="20%"><pre class="verbatim">(let* ((v #%(1 2 3))
- (a (make-ra 0 (ra-len v) (ra-len v))))
- (ra-copy! (⍉ a 0 0) v)
- a)
- </pre></td><td width="20%"><pre class="verbatim">v ← 1 2 3
- a ← ((⍴ v), ⍴ v) ⍴ 0
- (0 0 ⍉ a) ← v
- a
- </pre></td><td width="20%"><pre class="verbatim">np.diag([1, 2, 3])
- </pre></td><td width="20%"><pre class="verbatim">diag([1 2 3])
- </pre></td></tr>
- <tr><td width="20%">transpose</td><td width="20%"><pre class="verbatim">(⍉ A 1 0)
- </pre></td><td width="20%"><span id="index-_005b_003f_005d_002c-transpose-1"></span>
- <pre class="verbatim">1 0 ⍉ A
- </pre></td><td width="20%"><pre class="verbatim">A.T
- </pre></td><td width="20%"><pre class="verbatim">A.'
- </pre></td></tr>
- <tr><td width="20%">cat horizontally</td><td width="20%"><pre class="verbatim">∗ (define a #%(1 2))
- (ra-cat #f 0 a a)
- </pre></td><td width="20%"><pre class="verbatim">a ← 1 2
- a , a
- </pre></td><td width="20%"><pre class="verbatim">a = np.array([1, 2])
- np.hstack((a, a))
- </pre></td><td width="20%"><pre class="verbatim">a = [1 2]
- [a a]
- </pre></td></tr>
- <tr><td width="20%">cat vertically</td><td width="20%"><pre class="verbatim">∗ (define a #%(1 2))
- (ra-cats #f 1 a a)
- </pre></td><td width="20%"><pre class="verbatim">a ← 1 2
- a ⍪ a
- </pre></td><td width="20%"><pre class="verbatim">a = np.array([1, 2])
- np.vstack((a, a))
- </pre></td><td width="20%"><pre class="verbatim">a = [1 2]
- [a; a]
- </pre></td></tr>
- <tr><td width="20%">convert matrix to vector</td><td width="20%"><pre class="verbatim">(ra-ravel a)
- </pre></td><td width="20%"><pre class="verbatim">, a
- </pre></td><td width="20%"><pre class="verbatim">a.flatten()
- </pre></td><td width="20%"><pre class="verbatim">a(:)
- </pre></td></tr>
- <tr><td width="20%">flip matrix left/right</td><td width="20%"><pre class="verbatim">(ra-reverse a 1)
- </pre></td><td width="20%"><span id="index-_005b_003f_005d_002c-reverse-1"></span>
- <pre class="verbatim">⌽ a
- </pre></td><td width="20%"><pre class="verbatim">np.fliplr(a)
- </pre></td><td width="20%"><pre class="verbatim">fliplr(a)
- </pre></td></tr>
- <tr><td width="20%">flip matrix up/down</td><td width="20%"><pre class="verbatim">(ra-reverse a 0)
- </pre></td><td width="20%"><span id="index-_005b_003f_005d_002c-rowel-1"></span>
- <pre class="verbatim">⊖ a
- </pre></td><td width="20%"><pre class="verbatim">np.flipud(a)
- </pre></td><td width="20%"><pre class="verbatim">flipud(a)
- </pre></td></tr>
- <tr><td width="20%">broadcast a function over arrays</td><td width="20%"><pre class="verbatim">(define (f x) (* x x))
- (define (g x y) (+ 2 x (* y y)))
- (define x (ra-iota 10 1))
- (define y (ra-iota 10 2))
- (ra-map #f f x)
- (ra-map #f g x y)
- </pre></td><td width="20%">tbf</td><td width="20%"><pre class="verbatim">def f(x): return x**2
- def g(x, y): return x + 2 + y**2
- x = np.arange(1, 11)
- y = np.arange(2, 12)
- f(x)
- g(x, y)
- </pre></td><td width="20%"><pre class="verbatim">f = @(x) x.^2
- g = @(x, y) x + 2 + y.^2
- x = 1:10
- y = 2:11
- f(x)
- g(x, y)
- </pre></td></tr>
- <tr><td width="20%">for matrix <code>a</code>, access one element</td><td width="20%"><pre class="verbatim">(a 2 2)
- ────
- (ra-from a 2 2)
- </pre></td><td width="20%"><pre class="verbatim">a[2; 2]
- </pre></td><td width="20%"><pre class="verbatim">a[2, 2]
- </pre></td><td width="20%"><pre class="verbatim">a(2, 2)
- </pre></td></tr>
- <tr><td width="20%">for matrix <code>a</code>, access row block</td><td width="20%"><pre class="verbatim">(ra-from a (ra-iota 4 1))
- </pre></td><td width="20%"><pre class="verbatim">a[1 + ι 4; ]
- </pre></td><td width="20%"><pre class="verbatim">a[1:5, :]
- </pre></td><td width="20%"><pre class="verbatim">a(1:4, :)
- </pre></td></tr>
- <tr><td width="20%">for matrix <code>a</code>, access column block</td><td width="20%"><pre class="verbatim">(ra-from a #t (ra-iota 4 1))
- </pre></td><td width="20%"><pre class="verbatim">a[; 1 + ι 4]
- </pre></td><td width="20%"><pre class="verbatim">a[:, 1:5]
- </pre></td><td width="20%"><pre class="verbatim">a(:, 1:4)
- </pre></td></tr>
- <tr><td width="20%">copy of matrix with row removed</td><td width="20%"><pre class="verbatim">(ra-from a (list->ra 1 '(1 2 4)))
- </pre></td><td width="20%"><pre class="verbatim">a[1 2 4; ]
- </pre></td><td width="20%"><pre class="verbatim">a[[1 2 4], :]
- </pre></td><td width="20%"><pre class="verbatim">a([1 2 4], :)
- </pre></td></tr>
- <tr><td width="20%">diagonal of matrix</td><td width="20%"><pre class="verbatim">(⍉ a 0 0)
- </pre></td><td width="20%"><pre class="verbatim">0 0 ⍉ a
- </pre></td><td width="20%"><pre class="verbatim">np.diag(a)
- </pre></td><td width="20%"><pre class="verbatim">diag(a)
- </pre></td></tr>
- <tr><td width="20%">dimensions of matrix</td><td width="20%"><pre class="verbatim">(match (ra-dimensions a)
- ((nrow ncol) ...))
- </pre></td><td width="20%"><pre class="verbatim">nrow ← (ρ a)[0]
- ncol ← (ρ a)[1]
- </pre></td><td width="20%"><pre class="verbatim">nrow, ncol = np.shape(A)
- </pre></td><td width="20%"><pre class="verbatim">[nrow ncol] = size(A)
- </pre></td></tr>
- <tr><td width="20%">sum/max/min each column of matrix</td><td width="20%"><pre class="verbatim">(define id 0/-inf.0/+inf.0)
- (define op +/max/min)
- (let ((b (make-ra id (ra-len a 1))))
- (ra-map! b op b (⍉ 1 0)))
- </pre></td><td width="20%"><pre class="verbatim">+ / ⍉ a
- ⌈ / ⍉ a
- ⌊ / ⍉ a
- </pre></td><td width="20%"><pre class="verbatim">np.sum(a, 0)
- np.max(a, 0)
- np.min(a, 0)
- </pre></td><td width="20%"><pre class="verbatim">sum(a, 1)
- max(a, 1)
- min(a, 1)
- </pre></td></tr>
- <tr><td width="20%">sum/max/min each row of matrix</td><td width="20%"><pre class="verbatim">(define id 0/-inf.0/+inf.0)
- (define op +/max/min)
- (let ((b (make-ra id (ra-len a 0))))
- (ra-map! b op b a))
- </pre></td><td width="20%"><pre class="verbatim">+ / a
- ⌈ / a
- ⌊ / a
- </pre></td><td width="20%"><pre class="verbatim">np.sum(a, 1)
- np.max(a, 1)
- np.min(a, 1)
- </pre></td><td width="20%"><pre class="verbatim">sum(a, 2)
- max(a, 2)
- min(a, 2)
- </pre></td></tr>
- <tr><td width="20%">sum/max/min the whole matrix</td><td width="20%"><pre class="verbatim">(define id 0/-inf.0/+inf.0)
- (define op +/max/min)
- (ra-fold op id a)
- </pre></td><td width="20%"><pre class="verbatim">+ / , a
- ⌈ / , a
- ⌊ / , a
- </pre></td><td width="20%"><pre class="verbatim">np.sum(a)
- np.max(a)
- np.min(a)
- </pre></td><td width="20%"><pre class="verbatim">sum(a)
- max(a)
- min(a)
- </pre></td></tr>
- <tr><td width="20%">dot product of vectors</td><td width="20%"><pre class="verbatim">(ra-fold
- (λ (c a b) (+ c (* a b)))
- a b)
- </pre></td><td width="20%"><pre class="verbatim">a + . × b
- </pre></td><td width="20%"><pre class="verbatim">a @ b
- </pre></td><td width="20%"><pre class="verbatim">dot(a, b)
- </pre></td></tr>
- <tr><td width="20%">matrix product</td><td width="20%"><pre class="verbatim">(let* ((c (make-ra 0 (ra-len a 0) (ra-len b 1)))
- (cc (⍉ c 0 2)))
- (ra-map! cc (λ (c a b) (+ c (* a b)))
- cc a (⍉ b 1))
- c)
- </pre></td><td width="20%"><pre class="verbatim">a + . × b
- </pre></td><td width="20%"><pre class="verbatim">a @ b
- </pre></td><td width="20%"><pre class="verbatim">a * b
- </pre></td></tr>
- <tr><td width="20%">elementwise product of matrices</td><td width="20%"><pre class="verbatim">(ra-map #f * a b)
- </pre></td><td width="20%"><pre class="verbatim">a × b
- </pre></td><td width="20%"><pre class="verbatim">a * b
- </pre></td><td width="20%"><pre class="verbatim">a .* b
- </pre>
- <span id="x_002dnumpy_002dexample_002d0"></span></td></tr>
- <tr><td width="20%">multiply each element of vector by each row of matrix</td><td width="20%"><pre class="verbatim">(ra-map #f * m v)
- </pre></td><td width="20%"><pre class="verbatim">m ×⍤1 0 v
- </pre></td><td width="20%"><pre class="verbatim">m * v[:, np.newaxis]
- ────
- np.diag(v) * m
- </pre></td><td width="20%"><pre class="verbatim">diag(v) * m
- </pre></td></tr>
- <tr><td width="20%">multiply each element of vector by each column of matrix</td><td width="20%"><pre class="verbatim">(ra-map #f * m (⍉ v 1))
- </pre></td><td width="20%"><pre class="verbatim">m ×⍤1 1 v
- </pre></td><td width="20%"><pre class="verbatim">m * v
- ────
- m * v[np.newaxis, :]
- ────
- m * np.diag(v)
- </pre></td><td width="20%"><pre class="verbatim">m * diag(v)
- </pre></td></tr>
- <tr><td width="20%">...</td><td width="20%">...</td><td width="20%">...</td><td width="20%">...</td><td width="20%">...</td></tr>
- </table>
- <hr>
- </div>
- <div class="chapter" id="Sources">
- <div class="header">
- <p>
- Next: <a href="#Indices" accesskey="n" rel="next">Indices</a>, Previous: <a href="#Cheatsheet" accesskey="p" rel="prev">Cheatsheet</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Sources-1"></span><h2 class="chapter">7 Sources</h2>
- <table>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Abr70"></span>[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>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Ber87"></span>[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>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="bli17"></span>[bli17]</td><td width="90%">The Blitz++ meta-template library. <a href="http://blitz.sourceforge.net">http://blitz.sourceforge.net</a>, November 2017.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Cha86"></span>[Cha86]</td><td width="90%">Gregory J. Chaitin. Physics in APL2, June 1986.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="FI68"></span>[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>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="FI73"></span>[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>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="FI78"></span>[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>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="J-S"></span>[J S]</td><td width="90%">J Primer. J Software, <a href="https://www.jsoftware.com/help/primer/contents.htm">https://www.jsoftware.com/help/primer/contents.htm</a>, November 2017.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Mat"></span>[Mat]</td><td width="90%">MathWorks. MATLAB documentation, <a href="https://www.mathworks.com/help/matlab/">https://www.mathworks.com/help/matlab/</a>, November 2017.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Octave"></span>[Octave]</td><td width="90%">GNU Octave documentation (version 6.3.0), <a href="https://octave.org/doc/v6.3.0">https://octave.org/doc/v6.3.0</a>, 2020.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="num17"></span>[num17]</td><td width="90%">NumPy. <a href="http://www.numpy.org">http://www.numpy.org</a>, November 2017.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Ric08"></span>[Ric08]</td><td width="90%">Henry Rich. J for C programmers, February 2008.</td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SSM14"></span>[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>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="Wad90"></span>[Wad90]</td><td width="90%">Philip Wadler. Deforestation: transforming programs to eliminate trees. Theoretical Computer Science, 73(2): 231–248, June 1990. <a href="https://doi.org/10.1016/0304-3975%2890%2990147-A">https://doi.org/10.1016/0304-3975%2890%2990147-A</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d4"></span>[SRFI-4]</td><td width="90%">Marc Feeley. SRFI-4: Homogeneous numeric vector datatypes, May 1999. <a href="https://srfi.schemers.org/srfi-4/srfi-4.html">https://srfi.schemers.org/srfi-4/srfi-4.html</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d25"></span>[SRFI-25]</td><td width="90%">Jussi Piitulainen. SRFI-25: Multi-dimensional array primitives, May 2002. <a href="https://srfi.schemers.org/srfi-25/srfi-25.html">https://srfi.schemers.org/srfi-25/srfi-25.html</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d122"></span>[SRFI-122]</td><td width="90%">Bradley J. Lucier. SRFI-122: Nonempty intervals and generalized arrays, December 2016. <a href="https://srfi.schemers.org/srfi-122/srfi-122.html">https://srfi.schemers.org/srfi-122/srfi-122.html</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d160"></span>[SRFI-160]</td><td width="90%">John Cowan and Shiro Kawai. SRFI-160: Homogeneous numeric vector libraries, November 2020. <a href="https://srfi.schemers.org/srfi-160/srfi-160.html">https://srfi.schemers.org/srfi-160/srfi-160.html</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="S7"></span>[S7]</td><td width="90%">S7 Scheme: Multidimensional vectors. Accessed June 2022. <a href="https://ccrma.stanford.edu/software/snd/snd/s7.html#multidimensionalvectors">https://ccrma.stanford.edu/software/snd/snd/s7.html#multidimensionalvectors</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d163"></span>[SRFI-163]</td><td width="90%">Per Bothner. SRFI-163: Enhanced array literals, January 2019. <a href="https://srfi.schemers.org/srfi-163/srfi-163.html">https://srfi.schemers.org/srfi-163/srfi-163.html</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d164"></span>[SRFI-164]</td><td width="90%">Per Bothner. SRFI-164: Enhanced multi-dimensional arrays, August 2019. <a href="https://srfi.schemers.org/srfi-164/srfi-164.html">https://srfi.schemers.org/srfi-164/srfi-164.html</a></td></tr>
- <tr><td width="10%"></td></tr>
- <tr><td width="10%"><span id="SRFI_002d231"></span>[SRFI-231]</td><td width="90%">Bradley J. Lucier. SRFI-231: Intervals and generalized arrays, September 2022. <a href="https://srfi.schemers.org/srfi-164/srfi-164.html">https://srfi.schemers.org/srfi-164/srfi-164.html</a></td></tr>
- </table>
- <hr>
- </div>
- <div class="unnumbered" id="Indices">
- <div class="header">
- <p>
- Previous: <a href="#Sources" accesskey="p" rel="prev">Sources</a>, Up: <a href="#Top" accesskey="u" rel="up"><code>newra</code></a> [<a href="#Indices" title="Index" rel="index">Index</a>]</p>
- </div>
- <span id="Indices-1"></span><h2 class="unnumbered">Indices</h2>
- <table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="#Indices_cp_symbol-1"><b>*</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-2"><b>,</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-3"><b>{</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-4"><b>⊖</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-5"><b>⌽</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-6"><b>⍉</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-7"><b>⍋</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-8"><b>⍴</b></a>
-
- <br>
- <a class="summary-letter" href="#Indices_cp_letter-A"><b>A</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-B"><b>B</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-C"><b>C</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-D"><b>D</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-F"><b>F</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-G"><b>G</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-I"><b>I</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-L"><b>L</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-M"><b>M</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-N"><b>N</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-O"><b>O</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-P"><b>P</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-R"><b>R</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-S"><b>S</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-T"><b>T</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-U"><b>U</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-V"><b>V</b></a>
-
- </td></tr></table>
- <table class="index-cp" border="0">
- <tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-1">*</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_002ara_002dparenthesized_002drank_002dzero_002a"><code>*ra-parenthesized-rank-zero*</code></a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_002ara_002dprint_002a"><code>*ra-print*</code></a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-2">,</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_002c_002c-ravel"><code>,</code>, ravel</a>:</td><td> </td><td valign="top"><a href="#Reshaping">Reshaping</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-3">{</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_007b_002c-from"><code>{</code>, from</a>:</td><td> </td><td valign="top"><a href="#Slicing">Slicing</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-4">⊖</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-rowel"><code>⊖</code>, rowel</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-rowel-1"><code>⊖</code>, rowel</a>:</td><td> </td><td valign="top"><a href="#Cheatsheet">Cheatsheet</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-5">⌽</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-reverse"><code>⌽</code>, reverse</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-reverse-1"><code>⌽</code>, reverse</a>:</td><td> </td><td valign="top"><a href="#Cheatsheet">Cheatsheet</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-rotate"><code>⌽</code>, rotate</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-6">⍉</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-transpose"><code>⍉</code>, transpose</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-transpose-1"><code>⍉</code>, transpose</a>:</td><td> </td><td valign="top"><a href="#Cheatsheet">Cheatsheet</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-7">⍋</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-grade">⍋, grade</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_symbol-8">⍴</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-_005b_003f_005d_002c-reshape"><code>⍴</code>, reshape</a>:</td><td> </td><td valign="top"><a href="#Reshaping">Reshaping</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-A">A</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-APL">APL</a>:</td><td> </td><td valign="top"><a href="#Reshaping">Reshaping</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-APL-1">APL</a>:</td><td> </td><td valign="top"><a href="#Differences-with_002e_002e_002e">Differences with...</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-applicative">applicative</a>:</td><td> </td><td valign="top"><a href="#Creating-and-accessing-arrays">Creating and accessing arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-array_002d_003era"><code>array->ra</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-B">B</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-bounds">bounds</a>:</td><td> </td><td valign="top"><a href="#Introduction">Introduction</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-bounds-1">bounds</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-box"><code>box</code></a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-box1"><code>box1</code></a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-box2"><code>box2</code></a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-broadcasting_002c-singleton_002c-newaxis">broadcasting, singleton, newaxis</a>:</td><td> </td><td valign="top"><a href="#Rank-extension">Rank extension</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-C">C</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-c_002ddims"><code>c-dims</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-cell">cell</a>:</td><td> </td><td valign="top"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-concatenation">concatenation</a>:</td><td> </td><td valign="top"><a href="#Concatenation">Concatenation</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-D">D</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-d"><code>d</code></a>:</td><td> </td><td valign="top"><a href="#Special-arrays">Special arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-dead-axes">dead axes</a>:</td><td> </td><td valign="top"><a href="#Special-arrays">Special arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-default"><code>default</code></a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-diagonal">diagonal</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-dim-vector">dim vector</a>:</td><td> </td><td valign="top"><a href="#The-pieces-of-an-array">The pieces of an array</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-dots"><code>dots</code></a>:</td><td> </td><td valign="top"><a href="#Slicing">Slicing</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-dots-1"><code>dots</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-F">F</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-Fortran">Fortran</a>:</td><td> </td><td valign="top"><a href="#Differences-with_002e_002e_002e">Differences with...</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-frame">frame</a>:</td><td> </td><td valign="top"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-G">G</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-grade">grade</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-I">I</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-index-placeholder">index placeholder</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-infinite-axes">infinite axes</a>:</td><td> </td><td valign="top"><a href="#Special-arrays">Special arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-intersection">intersection</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-L">L</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-libguile">libguile</a>:</td><td> </td><td valign="top"><a href="#Built_002din-Guile-arrays">Built-in Guile arrays</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-M">M</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-make_002daseq"><code>make-aseq</code></a>:</td><td> </td><td valign="top"><a href="#Special-arrays">Special arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-make_002dra"><code>make-ra</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-make_002dra_002dnew"><code>make-ra-new</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-make_002dra_002droot"><code>make-ra-root</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-make_002dtyped_002dra"><code>make-typed-ra</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-Matlab">Matlab</a>:</td><td> </td><td valign="top"><a href="#Differences-with_002e_002e_002e">Differences with...</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-N">N</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-new-array">new array</a>:</td><td> </td><td valign="top"><a href="#The-pieces-of-an-array">The pieces of an array</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-NumPy">NumPy</a>:</td><td> </td><td valign="top"><a href="#Rank-extension">Rank extension</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-NumPy-1">NumPy</a>:</td><td> </td><td valign="top"><a href="#Rank-extension">Rank extension</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-NumPy-2">NumPy</a>:</td><td> </td><td valign="top"><a href="#Differences-with_002e_002e_002e">Differences with...</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-NumPy-3">NumPy</a>:</td><td> </td><td valign="top"><a href="#Cheatsheet">Cheatsheet</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-O">O</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-Octave">Octave</a>:</td><td> </td><td valign="top"><a href="#Differences-with_002e_002e_002e">Differences with...</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-order_002c-C">order, C</a>:</td><td> </td><td valign="top"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-order_002c-row_002dmajor">order, row-major</a>:</td><td> </td><td valign="top"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-outer-product">outer product</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-P">P</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-packed-array">packed array</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-packed-array-1">packed array</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-packed-array-2">packed array</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-prefix-matching">prefix matching</a>:</td><td> </td><td valign="top"><a href="#Iteration">Iteration</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-prefix-matching-1">prefix matching</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-prefix-slice">prefix slice</a>:</td><td> </td><td valign="top"><a href="#Creating-and-accessing-arrays">Creating and accessing arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-prefix-slice-1">prefix slice</a>:</td><td> </td><td valign="top"><a href="#Slicing">Slicing</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-print-prefix"><code>print prefix</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-Python">Python</a>:</td><td> </td><td valign="top"><a href="#Differences-with_002e_002e_002e">Differences with...</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-R">R</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002d_003earray"><code>ra->array</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002damend_0021"><code>ra-amend!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dany"><code>ra-any</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dcat"><code>ra-cat</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dcats"><code>ra-cats</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dcell"><code>ra-cell</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dclip"><code>ra-clip</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dcopy"><code>ra-copy</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dcopy_0021"><code>ra-copy!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002ddimensions"><code>ra-dimensions</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dequal_003f"><code>ra-equal?</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002devery"><code>ra-every</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dfill_0021"><code>ra-fill!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dfold"><code>ra-fold</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dfor_002deach"><code>ra-for-each</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dformat"><code>ra-format</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dfrom"><code>ra-from</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dfrom_002dcopy"><code>ra-from-copy</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002di"><code>ra-i</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dindex_002dmap_0021"><code>ra-index-map!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002diota"><code>ra-iota</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dmap"><code>ra-map</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dmap_0021"><code>ra-map!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dorder_002dc_003f"><code>ra-order-c?</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dprint"><code>ra-print</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dprint_002dprefix"><code>ra-print-prefix</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dravel"><code>ra-ravel</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dref"><code>ra-ref</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dreshape"><code>ra-reshape</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dreverse"><code>ra-reverse</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002drotate"><code>ra-rotate</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002drotate_0021"><code>ra-rotate!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dset_0021"><code>ra-set!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dshape"><code>ra-shape</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dsingletonize"><code>ra-singletonize</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dslice"><code>ra-slice</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dslice_002dfor_002deach"><code>ra-slice-for-each</code></a>:</td><td> </td><td valign="top"><a href="#Pitfalls-and-common-mistakes">Pitfalls and common mistakes</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dslice_002dfor_002deach-1"><code>ra-slice-for-each</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dswap_0021"><code>ra-swap!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dswap_002din_002dorder_0021"><code>ra-swap-in-order!</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dtile"><code>ra-tile</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002dtranspose"><code>ra-transpose</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-ra_002duntranspose"><code>ra-untranspose</code></a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-rank">rank</a>:</td><td> </td><td valign="top"><a href="#The-pieces-of-an-array">The pieces of an array</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-rank-polymorphism">rank polymorphism</a>:</td><td> </td><td valign="top"><a href="#Rank-polymorphism">Rank polymorphism</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-root-vector">root vector</a>:</td><td> </td><td valign="top"><a href="#The-pieces-of-an-array">The pieces of an array</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-rotate_0021">rotate!</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-S">S</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-shape-agreement_002c-prefix">shape agreement, prefix</a>:</td><td> </td><td valign="top"><a href="#Rank-extension">Rank extension</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-shape-agreement_002c-suffix">shape agreement, suffix</a>:</td><td> </td><td valign="top"><a href="#Rank-extension">Rank extension</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-shared-root">shared root</a>:</td><td> </td><td valign="top"><a href="#The-pieces-of-an-array">The pieces of an array</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-singleton-axis">singleton axis</a>:</td><td> </td><td valign="top"><a href="#Special-arrays">Special arrays</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-SRFI_002d163">SRFI-163</a>:</td><td> </td><td valign="top"><a href="#Writing-and-reading">Writing and reading</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-SRFI_002d163-1">SRFI-163</a>:</td><td> </td><td valign="top"><a href="#Reference">Reference</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-T">T</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-transpose">transpose</a>:</td><td> </td><td valign="top"><a href="#Transposition">Transposition</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-U">U</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-unbounded-axes">unbounded axes</a>:</td><td> </td><td valign="top"><a href="#Special-arrays">Special arrays</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th id="Indices_cp_letter-V">V</th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-view">view</a>:</td><td> </td><td valign="top"><a href="#Introduction">Introduction</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-view-1">view</a>:</td><td> </td><td valign="top"><a href="#The-pieces-of-an-array">The pieces of an array</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- </table>
- <table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="#Indices_cp_symbol-1"><b>*</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-2"><b>,</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-3"><b>{</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-4"><b>⊖</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-5"><b>⌽</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-6"><b>⍉</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-7"><b>⍋</b></a>
-
- <a class="summary-letter" href="#Indices_cp_symbol-8"><b>⍴</b></a>
-
- <br>
- <a class="summary-letter" href="#Indices_cp_letter-A"><b>A</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-B"><b>B</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-C"><b>C</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-D"><b>D</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-F"><b>F</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-G"><b>G</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-I"><b>I</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-L"><b>L</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-M"><b>M</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-N"><b>N</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-O"><b>O</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-P"><b>P</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-R"><b>R</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-S"><b>S</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-T"><b>T</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-U"><b>U</b></a>
-
- <a class="summary-letter" href="#Indices_cp_letter-V"><b>V</b></a>
-
- </td></tr></table>
- </div>
- </div>
- <div class="footnote">
- <hr>
- <h4 class="footnotes-heading">Footnotes</h4>
- <h5><a id="FOOT1" href="#DOCF1">(1)</a></h5>
- <p>(c) lloda 2017–2023. Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.3 or
- any later version published by the Free Software Foundation; with no
- Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
- </p>
- <h5><a id="FOOT2" href="#DOCF2">(2)</a></h5>
- <pre class="verbatim">(import (newra))
- (define element (λ i (format #f "A(~{~a~^, ~})" i)))
- (define (ti k) (ra-transpose (ra-iota) k))
- (ra-format (ra-map! (make-ra #f 3 3) element (ti 0) (ti 1)) #:prefix? #f)
- (ra-format (ra-map! (make-ra #f 2 '(2 5) '(-2 0)) element (ti 0) (ti 1) (ti 2)) #:prefix? #f)
- </pre>
- <h5><a id="FOOT3" href="#DOCF3">(3)</a></h5>
- <p>Cf. <a href="https://en.wikipedia.org/wiki/Dope_vector"><em>dope vector</em></a></p>
- <h5><a id="FOOT4" href="#DOCF4">(4)</a></h5>
- <p>Old Guile (before v1.8) offered dedicated operations to sum arrays, etc. but obviously that isn’t any kind of solution.</p>
- <h5><a id="FOOT5" href="#DOCF5">(5)</a></h5>
- <p>This is equivalent to <a href="#x_002darray_002d_003era"><code>array->ra</code></a> when the argument is a root type.</p>
- <h5><a id="FOOT6" href="#DOCF6">(6)</a></h5>
- <p>An exception is <a href="#x_002dra_002dindex_002dmap_0021"><code>ra-index-map!</code></a>, where passing the indices is the purpose.</p>
- <h5><a id="FOOT7" href="#DOCF7">(7)</a></h5>
- <p>Note that this is not the same as <code>(let ((d (vector-ref (ra-dims a) k))) (ra-iota (dim-len d) (dim-lo d)))</code>, because the lower bound of <code>(ra-iota ...)</code> (<em>not</em> its content) is 0, not <code>(dim-lo d)</code>, so the corresponding lower bound on the result array would also be 0, while <code>#t</code> preserves the lower bound of <code>a</code>.</p>
- <h5><a id="FOOT8" href="#DOCF8">(8)</a></h5>
- <p>It’s still possible for array application to return a rank-0 array if that element is itself a rank-0 array, e.g.
- </p><div class="example">
- <pre class="example">((make-ra (make-ra 'x)))
- ⇒ #%0(x)
- </pre></div>
- <h5><a id="FOOT9" href="#DOCF9">(9)</a></h5>
- <p>An example of how using lower bounds other than 0 is not worth the trouble, not least for the library author.</p>
- <h5><a id="FOOT10" href="#DOCF10">(10)</a></h5>
- <p>I decided against this approach for <code>newra</code> because in my experience it results in errors going undetected more often than it saves any work.</p>
- <h5><a id="FOOT11" href="#DOCF11">(11)</a></h5>
- <p><a href="https://www.gnu.org/software/guile/manual/html_node/Formatted-Output.html"><code>(ice-9 format)</code></a></p>
- <h5><a id="FOOT12" href="#DOCF12">(12)</a></h5>
- <p>Cf. <code>array-index</code> from [<a href="#Sources">SRFI-164</a>]
- .</p>
- <h5><a id="FOOT13" href="#DOCF13">(13)</a></h5>
- <p>Cf. <code>array-index-ref</code> from [<a href="#Sources">SRFI-164</a>]
- .</p>
- <h5><a id="FOOT14" href="#DOCF14">(14)</a></h5>
- <p><a href="#x_002dra_002dorder_002dc_003f"><code>ra-order-c?</code></a> is always true for the result of <code>ra-copy</code>, so the ravel operation in <code>(ra-ravel (ra-copy ra))</code> is free, but it might not be in <code>(ra-copy (ra-ravel ra))</code>. So in principle, it is preferable to copy first.</p>
- </div>
- <a href='js_licenses.html' rel='jslicense'><small>JavaScript license information</small></a>
- </body>
- </html>
|