newra.texi 125 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932
  1. @c -*-texinfo-*-
  2. @c %**start of header
  3. @setfilename newra.info
  4. @documentencoding UTF-8
  5. @settitle newra — An alternative array library for Guile 3
  6. @c %**end of header
  7. @c last [ma112]
  8. @set VERSION 1
  9. @set UPDATED 2023 January 5
  10. @copying
  11. Version @value{VERSION}, updated @value{UPDATED}
  12. @footnote{
  13. (c) lloda 2017--2023. Permission is granted to copy, distribute and/or modify this document
  14. under the terms of the GNU Free Documentation License, Version 1.3 or
  15. any later version published by the Free Software Foundation; with no
  16. Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
  17. }
  18. @end copying
  19. @dircategory Guile libraries
  20. @direntry
  21. * newra: (newra.info). Array library for Guile meant to replace the built-in array facility.
  22. @end direntry
  23. @include my-bib-macros.texi
  24. @mybibuselist{Sources}
  25. @titlepage
  26. @title newra
  27. @subtitle version @value{VERSION}, updated @value{UPDATED}
  28. @author lloda
  29. @page
  30. @vskip 0pt plus 1filll
  31. @insertcopying
  32. @end titlepage
  33. @ifnottex
  34. @node Top
  35. @top @code{newra}
  36. @insertcopying
  37. @code{newra} is a pure Scheme replacement for the built-in C-based array facility in Guile 3.0.
  38. This document uses ‘array’ to refer both to the old built-in array type and to the new type introduced in @code{newra}. The distinction is made as necessary.
  39. @end ifnottex
  40. @iftex
  41. @shortcontents
  42. @end iftex
  43. @c ------------------------------------------------
  44. @node Introduction
  45. @chapter Introduction
  46. @c ------------------------------------------------
  47. @cindex bounds
  48. @cindex view
  49. A multidimensional array is a container (or rather a container @emph{view}) 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 @dfn{rank} of the array, and the list ([l₀ h₀] [l₁ h₁] ... [lᵣ₋₁ hᵣ₋₁]) is the @dfn{shape} of the array. We speak of a rank-@math{r} array or of an @math{r}-array.
  50. This is a 2-array with bounds [0, 2] on both axes:
  51. @verbatim
  52. ┌───────┬───────┬───────┐
  53. │A(0, 0)│A(0, 1)│A(0, 2)│
  54. ├───────┼───────┼───────┤
  55. │A(1, 0)│A(1, 1)│A(1, 2)│
  56. ├───────┼───────┼───────┤
  57. │A(2, 0)│A(2, 1)│A(2, 2)│
  58. └───────┴───────┴───────┘
  59. @end verbatim
  60. This is a 3-array with bounds [0, 1] on axis 0, [2, 5] on axis 1, bounds [-2, 0] on axis 2:@footnote{
  61. @verbatim
  62. (import (newra))
  63. (define element (λ i (format #f "A(~{~a~^, ~})" i)))
  64. (define (ti k) (ra-transpose (ra-iota) k))
  65. (ra-format (ra-map! (make-ra #f 3 3) element (ti 0) (ti 1)) #:prefix? #f)
  66. (ra-format (ra-map! (make-ra #f 2 '(2 5) '(-2 0)) element (ti 0) (ti 1) (ti 2)) #:prefix? #f)
  67. @end verbatim
  68. }
  69. @verbatim
  70. ║───────────┬───────────┬──────────║───────────┬───────────┬──────────║
  71. ║A(0, 2, -2)│A(0, 2, -1)│A(0, 2, 0)║A(1, 2, -2)│A(1, 2, -1)│A(1, 2, 0)║
  72. ║───────────┼───────────┼──────────║───────────┼───────────┼──────────║
  73. ║A(0, 3, -2)│A(0, 3, -1)│A(0, 3, 0)║A(1, 3, -2)│A(1, 3, -1)│A(1, 3, 0)║
  74. ║───────────┼───────────┼──────────║───────────┼───────────┼──────────║
  75. ║A(0, 4, -2)│A(0, 4, -1)│A(0, 4, 0)║A(1, 4, -2)│A(1, 4, -1)│A(1, 4, 0)║
  76. ║───────────┼───────────┼──────────║───────────┼───────────┼──────────║
  77. ║A(0, 5, -2)│A(0, 5, -1)│A(0, 5, 0)║A(1, 5, -2)│A(1, 5, -1)│A(1, 5, 0)║
  78. ║───────────┴───────────┴──────────║───────────┴───────────┴──────────║
  79. @end verbatim
  80. Sometimes we deal with multidimensional @emph{expressions} 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.
  81. Arrays (in the form of @dfn{vectors}, @dfn{matrices}, or @dfn{tensors}) 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}.
  82. The rest of this section discusses the motivation for @code{newra} in more detail. To start using the library, please jump ahead to @ref{The array library}.
  83. @c ------------------------------------------------
  84. @node Rank polymorphism
  85. @section Rank polymorphism
  86. @c ------------------------------------------------
  87. @cindex rank polymorphism
  88. @dfn{Rank polymorphism} is the ability to treat an array of rank @math{r} as an array of lower rank where the elements are themselves arrays.
  89. @cindex cell
  90. @cindex frame
  91. 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-@dfn{cells} of A, and the numbers A(i₀, i₁) are 0-cells of A. For an array of arbitrary rank @math{r} the (@math{r}-1)-cells of A are called its @dfn{items}. The prefix of the shape (l₀, l₁, ... lₙ₋₁₋ₖ) that is not taken up by the k-cell is called the (r-k)-@dfn{frame}.
  92. @multitable @columnfractions .4 .1 .4
  93. @item
  94. @verbatim
  95. ┌───────┬───────┬───────┐
  96. │A(0, 0)│A(0, 1)│A(0, 2)│
  97. ├───────┼───────┼───────┤
  98. │A(1, 0)│A(1, 1)│A(1, 2)│
  99. ├───────┼───────┼───────┤
  100. │A(2, 0)│A(2, 1)│A(2, 2)│
  101. └───────┴───────┴───────┘
  102. @end verbatim
  103. @tab
  104. @tab
  105. @verbatim
  106. ────
  107. A(0)
  108. ────
  109. A(1)
  110. ────
  111. A(2)
  112. ────
  113. @end verbatim
  114. @end multitable
  115. 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
  116. @quotation
  117. A: [A(0), A(1), ...]
  118. @end quotation
  119. and the items of A(i₀), etc. are in turn stored in the same way, so
  120. @quotation
  121. A: [A(0): [A(0, 0), A(0, 1) ...], ...]
  122. @end quotation
  123. and the same for the items of A(i₀, i₁), etc.
  124. @quotation
  125. A: [[A(0, 0): [A(0, 0, 0), A(0, 0, 1) ...], A(0, 1): [A(0, 1, 0), A(0, 1, 1) ...]], ...]
  126. @end quotation
  127. @cindex order, row-major
  128. @cindex order, C
  129. This way to lay out an array in memory is called @dfn{row-major order} or @dfn{C-order}, 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:
  130. @anchor{x-steps}
  131. @quotation
  132. A(i₀, i₁, ...) = (storage-of-A) [(((i₀l₁ + i₁)l₂ + i₂)l₃ + ...)+iᵣ₋₁] = (storage-of-A) [o + s₀·i₀ + s₁·i₁ + ...]
  133. @end quotation
  134. where the numbers (s₀, s₁, ...) are called the @dfn{steps}@footnote{Cf. @url{https://en.wikipedia.org/wiki/Dope_vector, @dfn{dope vector}}}. 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
  135. @quotation
  136. A ≡ ((storage-of-A), o, (s₀, s₁, ...))
  137. @end quotation
  138. 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: @ref{x-ra-transpose,transposing} axes, @ref{x-ra-reverse,reversing} the order along an axis, most cases of @ref{Slicing,slicing}, and sometimes even reshaping or tiling the array.
  139. A basic example is obtaining the i₀-th item of A:
  140. @quotation
  141. A(i₀) ≡ ((storage-of-A), o+s₀·i₀, (s₁, ...))
  142. @end quotation
  143. 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 (@ref{x-ra-slice-for-each,@code{ra-slice-for-each}}). 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.
  144. @c ------------------------------------------------
  145. @node Rank extension
  146. @section Rank extension
  147. @c ------------------------------------------------
  148. Rank extension is the mechanism that allows @code{R+S} to be defined even when @code{R}, @code{S} may have different ranks. The idea is an interpolation of the following basic cases.
  149. Suppose first that @code{R} and @code{S} have the same rank. We require that the shapes be the same. Then the shape of @code{R+S} will be the same as the shape of either @code{R} or @code{S} and the elements of @code{R+S} will be
  150. @quotation
  151. @code{(R+S)(i₀ i₁ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ᵣ₋₁₎) + S(i₀ i₁ ... i₍ᵣ₋₁₎)}
  152. @end quotation
  153. where @code{r} is the rank of @code{R}.
  154. Now suppose that @code{S} has rank 0. The shape of @code{R+S} is the same as the shape of @code{R} and the elements of @code{R+S} will be
  155. @quotation
  156. @code{(R+S)(i₀ i₁ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ᵣ₋₁₎) + S()}.
  157. @end quotation
  158. The two rules above are supported by all primitive array languages. But suppose that @code{S} has rank @code{s}, where @code{0<s<r}. Looking at the expressions above, it seems natural to define @code{R+S} by
  159. @quotation
  160. @code{(R+S)(i₀ i₁ ... i₍ₛ₋₁₎ ... i₍ᵣ₋₁₎) = R(i₀ i₁ ... i₍ₛ₋₁₎ ... i₍ᵣ₋₁₎) + S(i₀ i₁ ... i₍ₛ₋₁₎)}.
  161. @end quotation
  162. That is, after we run out of indices in @code{S}, we simply repeat the elements. We have aligned the shapes so:
  163. @quotation
  164. @verbatim
  165. [n₀ n₁ ... n₍ₛ₋₁₎ ... n₍ᵣ₋₁₎]
  166. [n₀ n₁ ... n₍ₛ₋₁₎]
  167. @end verbatim
  168. @end quotation
  169. @cindex shape agreement, prefix
  170. @cindex shape agreement, suffix
  171. @c @cindex J
  172. @cindex NumPy
  173. This rank extension rule is used by the J language @mybibcite{J S} and is known as @dfn{prefix agreement}. The opposite rule of @dfn{suffix agreement} is used, for example, in NumPy @mybibcite{num17}.
  174. 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}, even in assignments. For example,
  175. @example
  176. @verbatim
  177. (define a (make-ra-root #(3 5 9)))
  178. (define b (make-ra #f 3 2))
  179. (ra-copy! b a) ; copy each aᵢ on each bᵢ
  180. @end verbatim
  181. @result{} @code{#%2:3:2((3 3) (5 5) (9 9))}
  182. @end example
  183. @example
  184. @verbatim
  185. (define a (make-ra 0 3))
  186. (define b (ra-reshape (ra-iota 6 1) 0 3 2))
  187. (ra-map! a + a b) ; sum the rows of b
  188. @end verbatim
  189. @result{} @code{#%1:3(3 7 11)}
  190. @end example
  191. @cindex NumPy
  192. @cindex broadcasting, singleton, newaxis
  193. A weakness of prefix agreement is that the axes you want to match aren't always the prefix axes. Other array systems (e.g. @mybibcite{num17}) 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.
  194. 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}'s support for explicit broadcasting is based on @ref{x-dead-axes,dead axes}.
  195. @example
  196. @verbatim
  197. (define a (ra-i 5 3))
  198. (define b (make-ra 0 3))
  199. (let ((b1 (ra-transpose b 1))) ; align axis 0 of b with axis 1 of a
  200. (ra-map! b1 + b1 a) ; sum the columns of a
  201. b)
  202. @end verbatim
  203. @result{} b = @code{#%1:5(30 35 40)}
  204. @end example
  205. @c ------------------------------------------------
  206. @node The pieces of an array
  207. @section The pieces of an array
  208. @c ------------------------------------------------
  209. A @code{newra} array is an aggregate of the following pieces:
  210. @cindex rank
  211. @cindex dim vector
  212. @cindex root vector
  213. @itemize
  214. @item A @dfn{root vector}, or root for short.
  215. This can be a Scheme vector, as well as one of several other vector-like types.
  216. @item A @dfn{zero}.
  217. An arbitary integer.
  218. @item A @dfn{dim vector}.
  219. Each dim consists of a length (@dfn{len}), a lower bound (@dfn{lo}), and a @dfn{step}. The length of the dim vector is the @dfn{rank} of the array.
  220. @end itemize
  221. @cindex view
  222. Together, the dim vector and the zero define an affine function of array indices @code{i₀, i₁, ...} that produces an index into the root. Thus, the array is a multidimensional view of the root.
  223. For example, the following pieces
  224. @itemize
  225. @item root: v = @code{#(1 2 3 4 5 6 7)}
  226. @item zero: 1
  227. @item dims: @code{#(#<<dim> len: 2 lo: 0 step: 2> #<<dim> len: 2 lo: 0 step: 1>)}
  228. @end itemize
  229. 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]].
  230. In @code{newra} code,
  231. @example
  232. @verbatim
  233. (make-ra-root (vector 1 2 3 4 5 6 7) 1 (vector (make-dim 2 0 2) (make-dim 2 0 1)))
  234. @end verbatim
  235. @result{} @code{#%2:2:2((2 3) (4 5))}
  236. @end example
  237. The default print style means @code{#%RANK:LEN₀:LEN₁(...)} (@ref{Writing and reading}).
  238. It's unusual to need to specify the dims directly. More commonly, one creates an array of whatever size
  239. @example
  240. @verbatim
  241. > (define a (make-ra #f 3 4))
  242. > a
  243. @end verbatim
  244. @result{} @code{#%2:3:4((#f #f #f #f) (#f #f #f #f) (#f #f #f #f))}
  245. @end example
  246. 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,
  247. @example
  248. @verbatim
  249. > (ra-set! a 99 2 2)
  250. @end verbatim
  251. @result{} @code{#%2:3:4((#f #f #f #f) (#f #f 99 #f) (#f #f #f #f))}
  252. @end example
  253. Still, since the array is just a view of the root, any changes on the array are reflected there as well
  254. @example
  255. @verbatim
  256. > (ra-root a)
  257. @end verbatim
  258. @result{} @code{#(#f #f #f #f #f #f #f #f #f #f 99 #f)}
  259. @end example
  260. and the other way around,
  261. @example
  262. @verbatim
  263. > (define b (make-ra-root (vector 'x) 0 (vector (make-dim 3 0 0) (make-dim 2 0 0))))
  264. > b
  265. @end verbatim
  266. @result{} @code{#%2:3:2((x x) (x x) (x x))}
  267. @verbatim
  268. > (vector-set! (ra-root b) 0 'Z)
  269. > b
  270. @end verbatim
  271. @result{} @code{#%2:3:2((Z Z) (Z Z) (Z Z))}
  272. @end example
  273. @cindex shared root
  274. @cindex new array
  275. 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.
  276. Generally a given function will always do one or the other, e.g. the result of @ref{x-ra-tile, @code{ra-tile}} always shares the root of its argument, while @ref{x-ra-copy, @code{ra-copy}} always creates a new array. Some functions, like @ref{x-ra-ravel, @code{ra-ravel}} or @ref{x-ra-from, @code{ra-from}}, may do either, depending on their arguments. For example, the result of
  277. @example
  278. @verbatim
  279. (ra-ravel (ra-iota 3 4))
  280. @end verbatim
  281. @result{} @code{#%1d:12(0 1 2 3 4 5 6 7 8 9 10 11)}
  282. @end example
  283. shares the root of @code{(ra-iota 3 4)}, but
  284. @example
  285. @verbatim
  286. (ra-ravel (ra-transpose (ra-iota 3 4) 1 0))
  287. @end verbatim
  288. @result{} @code{#%1:12(0 4 8 1 5 9 2 6 10 3 7 11)}
  289. @end example
  290. doesn't.
  291. @c ------------------------------------------------
  292. @node Built-in Guile arrays
  293. @section Built-in Guile arrays
  294. @c ------------------------------------------------
  295. 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}), a zero (computable from @code{shared-array-offset} and @code{array-shape}), and a dim vector (@code{array-shape}, @code{shared-array-increments}). Functionally, they are entirely equivalent to the objects offered by @code{newra}. Why replace them?
  296. @cindex libguile
  297. 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} or @code{array-rank}. Obtaining any of the components of the array requires calling into C. There are several problems with this.
  298. First, the built-in library offers a single function to manipulate array dims, @code{make-shared-array}. 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}.
  299. 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)} 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{+}. Since the Scheme compiler doesn't have any special support for @code{array-map!}, it doesn't know what the types of the arguments are, etc. and those checks and dispatches are repeated over and over. @footnote{Old Guile (before v1.8) offered dedicated operations to sum arrays, etc. but obviously that isn't any kind of solution.}
  300. Third, some of the the larger functions of the array interface, such as @code{array-map!}, etc. are not interruptible. This is especially inconvenient when operating on large arrays.
  301. These problems are solved if the built-in type is replaced with a new type defined in Scheme.
  302. @c ------------------------------------------------
  303. @node The array library
  304. @chapter The array library
  305. @c ------------------------------------------------
  306. @c ------------------------------------------------
  307. @node Creating and accessing arrays
  308. @section Creating and accessing arrays
  309. @c ------------------------------------------------
  310. An array can be created anew (@ref{x-make-ra-new, @code{make-ra-new}}, @ref{x-make-ra, @code{make-ra}}, @ref{x-make-typed-ra, @code{make-typed-ra}}), or over an existing root (@ref{x-make-ra-root, @code{make-ra-root}}).
  311. @ref{x-make-ra, @code{make-ra}} or @ref{x-make-typed-ra, @code{make-typed-ra}} take a fill element and array lengths and use row-major order by default. The fill element may be @code{*unspecified*}.
  312. @example
  313. @verbatim
  314. (make-ra 99 2 3)
  315. @end verbatim
  316. @result{} #%2:3:2((9 9) (9 9) (9 9))
  317. @end example
  318. @example
  319. @verbatim
  320. (make-typed-ra 's16 *unspecified* 2 3)
  321. @end verbatim
  322. @result{} #%2s16:2:3((26414 26997 25964) (24878 26994 26996)) ; likely different values
  323. @end example
  324. The functions @code{make-ra-new} and @code{make-ra-root} are lower level. @ref{x-make-ra-new, @code{make-ra-new}} takes an array type, a fill value, and a dim vector. @ref{x-c-dims, @code{c-dims}} can be used to create a row-major dim vector.
  325. @example
  326. @verbatim
  327. (make-ra-new #t 'x (vector (make-dim 3 0 2) (make-dim 2 0 1)))
  328. (make-ra-new #t 'x (c-dims 3 2)) ; more simply
  329. @end verbatim
  330. @result{} #%2:3:2((x x) (x x) (x x))
  331. @end example
  332. @example
  333. @verbatim
  334. (make-ra-new 'f32 0.0 (c-dims 3 2))
  335. @end verbatim
  336. @result{} #%2f32:3:2((0.0 0.0) (0.0 0.0) (0.0 0.0))
  337. @end example
  338. @ref{x-make-ra-root, @code{make-ra-root}} takes the type from the root.
  339. @example
  340. @verbatim
  341. (make-ra-root (vector 1 2 3 4 5 6) (c-dims 3 2))
  342. @end verbatim
  343. @result{} #%2:3:2((1 2) (3 4) (5 6))
  344. @end example
  345. The default dims produce a view of the root as is (rank 1, zero offset, same length)@footnote{This is equivalent to @ref{x-array->ra, @code{array->ra}} when the argument is a root type.}.
  346. @example
  347. @verbatim
  348. (make-ra-root (vector 1 2 3 4 5 6))
  349. @end verbatim
  350. @result{} #%1:6(1 2 3 4 5 6)
  351. @end example
  352. @cindex applicative
  353. @code{newra} arrays are applicative; to look up or assign an element of an array, use it as a function of the indices.
  354. @example
  355. @verbatim
  356. (define a (make-ra #f 3 2))
  357. (set! (a 0 0) 9)
  358. (set! (a 1 1) 3)
  359. @end verbatim
  360. @result{} #%2:3:4((9 #f) (#f 3) (#f #f))
  361. @verbatim
  362. (a 0 0)
  363. @end verbatim
  364. @result{} 9
  365. @end example
  366. @cindex prefix slice
  367. If you give fewer indices than the rank, you get a prefix slice. This slice shares the root of the original array.
  368. @example
  369. @verbatim
  370. (a 1)
  371. @end verbatim
  372. @result{} #%1:2(#f 3)
  373. @verbatim
  374. (set! ((a 1) 0) 'b)
  375. @end verbatim
  376. @result{} #%1:2(b 3)
  377. @verbatim
  378. a
  379. @end verbatim
  380. @result{} #%2:3:4((9 #f) (b 3) (#f #f))
  381. @end example
  382. Generalized indices are handled as in @ref{x-ra-from, @code{ra-from}}:
  383. @example
  384. @verbatim
  385. ((ra-i 3 4) #t 1) ; second column
  386. @end verbatim
  387. @result{} #%1d:3(1 5 9)
  388. @end example
  389. You can also access arrays in the more usual way with the functions @ref{x-ra-ref, @code{ra-ref}} and @ref{x-ra-set!, @code{ra-set!}}. See @ref{Slicing} for all the options.
  390. @c ------------------------------------------------
  391. @node Special arrays
  392. @section Special arrays
  393. @c ------------------------------------------------
  394. Any type that is usable as the root of an old built-in Guile array is also usable as root of a @code{newra} array. These include
  395. @itemize
  396. @item vectors, like @code{(vector 3)}
  397. @item SRFI-4 typed vectors, like @code{(c64vector 1 2+0i)}
  398. @item strings, like @code{"hello"}
  399. @item bitvectors, like @code{(bitvector #f #t #f #t)}
  400. @end itemize
  401. @code{newra} supports an additional root type, @code{<aseq>}, representing an unbounded arithmetic sequence.
  402. @cindex @code{make-aseq}
  403. @anchor{x-none}
  404. @deffn @w{Function} make-aseq [org [inc]]
  405. Create an arithmetic sequence [@code{org, org+inc, org+2·inc, ...}]. The default values of @code{org} and @code{inc} are respectively 0 and 1. For example:
  406. @example
  407. @verbatim
  408. (make-ra-root (make-aseq 0 3) (vector (make-dim 10)) 0)
  409. @end verbatim
  410. @result{} #%1d:10(0 3 6 9 12 15 18 21 24 27)
  411. @end example
  412. This can be written more succinctly as @code{(@ref{x-ra-iota, ra-iota} 10 0 3)}.
  413. @end deffn
  414. @cindex @code{d}
  415. @code{aseq} roots are immutable. The type tag of @code{aseq} roots is @code{d}. Arrays with integer-valued @code{aseq} roots have some special uses; one of them is as arguments in @ref{Slicing, slicing}.
  416. @cindex infinite axes
  417. @cindex unbounded axes
  418. To make @code{<aseq>} even more useful, @code{newra} supports unbounded axes.
  419. @example
  420. @verbatim
  421. (ra-ref (make-ra-root (make-aseq) (vector (make-dim #f)) 0) #e1e12) ; or more simply
  422. (ra-ref (ra-iota) #e1e12)
  423. @end verbatim
  424. @result{} 1000000000000
  425. @end example
  426. These are treated especially when used in iteration (@ref{x-ra-map!, @code{ra-map!}}), in that they match axes of any finite length. Effectively this lets one use @code{(@ref{x-ra-transpose, @code{ra-transpose}} (ra-iota) k)} as a placeholder for the index over axis @code{k}.
  427. @example
  428. @verbatim
  429. (ra-map! (make-ra 0 3) + (ra-iota 3) (ra-iota))
  430. @end verbatim
  431. @result{} #1%3(0 2 4)
  432. @end example
  433. @cindex dead axes
  434. @anchor{x-dead-axes}
  435. @code{newra} 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}, because effectively only one position (the lower bound) is ever accessed.
  436. @cindex singleton axis
  437. 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).
  438. Some functions work by creating axes with step 0, usually with defined lengths.
  439. @example
  440. @verbatim
  441. (define A (make-ra-root #(1 2 3) (c-dims 3)))
  442. (ra-tile A 0 2 2)
  443. @end verbatim
  444. @result{} #%3d:2:2:3(((0 1 2) (0 1 2)) ((0 1 2) (0 1 2)))
  445. @verbatim
  446. (ra-dims (ra-tile A 0 2 2))
  447. @end verbatim
  448. @result{} #(#<<dim> len: 2 lo: 0 step: 0> #<<dim> len: 2 lo: 0 step: 0> #<<dim> len: 3 lo: 0 step: 1>)
  449. @end example
  450. @c ------------------------------------------------
  451. @node Writing and reading
  452. @section Writing and reading
  453. @c ------------------------------------------------
  454. The read syntax for arrays is @url{https://www.gnu.org/software/guile/manual/html_node/Array-Syntax.html,the same} as for built-in Guile arrays, except that @code{#%} is used instead of @code{#}. Full dimensions are printed by default, even when they are not required to read an array.
  455. @example
  456. @verbatim
  457. (call-with-input-string "#%1(2 2 2)" read)
  458. @end verbatim
  459. @result{} @code{#%1:3(2 2 2)}
  460. @end example
  461. @example
  462. @verbatim
  463. (call-with-input-string "#%1:3(2 2 2)" read)
  464. @end verbatim
  465. @result{} @code{#%1:3(2 2 2)}
  466. @end example
  467. Dead axes print as @code{d}, and unbounded (not dead) axes print as @code{f}. These cannot be read back.
  468. @example
  469. @verbatim
  470. (display (ra-transpose (ra-copy (ra-iota 3)) 1))
  471. @end verbatim
  472. @result{} @code{#%2:d:3((0 1 2))}
  473. @end example
  474. Arrays with root of type @code{d} cannot be read back either.
  475. @example
  476. @verbatim
  477. (define s (format #f "~a" (ra-i 2 3)))
  478. s
  479. @end verbatim
  480. @result{} @code{"#%2d:2:3((0 1 2) (3 4 5))"}
  481. @end example
  482. @example
  483. @verbatim
  484. (call-with-input-string s read)
  485. @end verbatim
  486. @result{} error: cannot make array of type d
  487. @end example
  488. Truncated output is not supported yet.
  489. @example
  490. @verbatim
  491. (format #f "~@y" (ra-i 2 3))
  492. @end verbatim
  493. @result{} @code{"#%2d:2:3((0 1 2) (3 4 5))"} ; ok, but we didn't need to truncate
  494. @end example
  495. @example
  496. @verbatim
  497. (format #f "~@y" (ra-i 99 99))
  498. @end verbatim
  499. @result{} @code{"#" ; ouch}
  500. @end example
  501. The function @ref{x-ra-format, @code{ra-format}} can be used to pretty print arrays. This type of output cannot be read back, either.
  502. @example
  503. @verbatim
  504. (ra-format (list->ra 2 '((1 hello) ("try" 2) (never 3.14))) #:fmt "~s")
  505. @end verbatim
  506. @result{}
  507. @verbatim
  508. #%2:3:2─────┐
  509. │ 1│hello│
  510. ├─────┼─────┤
  511. │"try"│ 2│
  512. ├─────┼─────┤
  513. │never│ 3.14│
  514. └─────┴─────┘
  515. @end verbatim
  516. @end example
  517. The writing mode can be configured with the following parameter.
  518. @cindex @code{*ra-print*}
  519. @anchor{x-star-ra-print-star}
  520. @deffn @w{Parameter} *ra-print* (λ (array port) ...)
  521. Set the default printer for arrays. This parameter is available from @code{(newra print)}.
  522. @cindex @code{box}
  523. @cindex @code{box1}
  524. @cindex @code{box2}
  525. @cindex @code{default}
  526. The parameter can be set to a function @code{(λ (array port) ...)} or to one of the values @code{#f}, @code{'default}, @code{'box}, @code{'box1}, or @code{'box2}.
  527. For example
  528. @example
  529. @verbatim
  530. (import (newra print))
  531. (*ra-print* (λ (ra o) (ra-print ra o #:dims? #f)))
  532. (ra-i 2 3)
  533. @end verbatim
  534. @result {}
  535. @verbatim
  536. $1 = #%2d((0 1 2) (3 4 5))
  537. @end verbatim
  538. @end example
  539. or
  540. @example
  541. @verbatim
  542. (*ra-print* (λ (ra o) (newline o) (ra-format ra o)))
  543. ; (*ra-print* 'box) ; same thing
  544. (ra-i 2 3)
  545. @end verbatim
  546. @result {}
  547. @verbatim
  548. $1 =
  549. #%2d:2:3
  550. │0│1│2│
  551. ├─┼─┼─┤
  552. │3│4│5│
  553. └─┴─┴─┘
  554. @end verbatim
  555. @end example
  556. The options @code{'box1} and @code{'box2} use @ref{x-ra-format,@code{ra-format}} like @code{'box} but pass 1 or 2 to the @code{#:compact} argument.
  557. The default printer can be reset with @code{(*ra-print* #f)} or @code{(*ra-print* 'default)}.
  558. @end deffn
  559. @cindex SRFI-163
  560. 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 @mybibcite{SRFI-163}, those parentheses are not used. The following parameter allows one to choose either behavior for both the printer and the reader.
  561. @cindex @code{*ra-parenthesized-rank-zero*}
  562. @anchor{x-star-ra-parenthesized-rank-zero-star}
  563. @deffn @w{Parameter} *ra-parenthesized-rank-zero* boolean
  564. Control read syntax of rank-0 arrays. This parameter is available from @code{(newra print)} or @code{(newra read)}.
  565. If @code{(*ra-parenthesized-rank-zero*)} is true, the read syntax for rank-0 arrays is
  566. @display
  567. @code{#%0TYPE(item)}
  568. @end display
  569. If it is @code{#f}, it is
  570. @display
  571. @code{#%0TYPE item}
  572. @end display
  573. with @code{TYPE} being optional in either case. Note that these are not compatible:
  574. @example
  575. @verbatim
  576. (ra-ref (parameterize ((*ra-parenthesized-rank-zero* #t))
  577. (call-with-input-string "#%0(a)" read)))
  578. @end verbatim
  579. @result{} @code{a}
  580. @verbatim
  581. (ra-ref (parameterize ((*ra-parenthesized-rank-zero* #f))
  582. (call-with-input-string "#%0(a)" read)))
  583. @end verbatim
  584. @result{} @code{(a)}
  585. @verbatim
  586. (ra-ref (parameterize ((*ra-parenthesized-rank-zero* #f))
  587. (call-with-input-string "#%0 a" read)))
  588. @end verbatim
  589. @result{} @code{a}
  590. @end example
  591. In the last example, the space is necessary (unlike in @mybibcite{SRFI-163}) since the array type tag is optional in Guile.
  592. @example
  593. @verbatim
  594. (parameterize ((*ra-parenthesized-rank-zero* #f))
  595. (call-with-input-string "#%0a" read))
  596. @end verbatim
  597. @result{} Wrong type (expecting character): #<eof>
  598. @end example
  599. The printer always uses a space in this mode:
  600. @example
  601. @verbatim
  602. (parameterize ((*ra-parenthesized-rank-zero* #f))
  603. (display (make-ra '(a))))
  604. @end verbatim
  605. @result{} @code{#%0 (a)}
  606. @end example
  607. Note that setting this parameter to @code{#f} still doesn't make the array read syntax fully compatible with that of @mybibcite{SRFI-163}, since the type tag @code{a} is reserved (in Guile) for character arrays.
  608. The default value of this parameter is @code{#t}.
  609. @end deffn
  610. @c ------------------------------------------------
  611. @node Iteration
  612. @section Iteration
  613. @c ------------------------------------------------
  614. The basic array iteration operations in @code{newra} 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 @ref{x-ra-map!, @code{ra-map!}}, then that is the result of the whole iteration. For example:
  615. @example
  616. @verbatim
  617. (ra-map! (make-ra #f 3) - (ra-iota 3 1))
  618. @end verbatim
  619. @result{} #%1:3(-1 -2 -3)
  620. @end example
  621. It is common to need the indices of the elements during array iteration. @code{newra} iteration operations do not keep track of those indices@footnote{An exception is @ref{x-ra-index-map!, @code{ra-index-map!}}, where passing the indices is the purpose.} 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 @ref{x-ra-transpose, @code{ra-transpose}}.
  622. @example
  623. @verbatim
  624. (define i0 (ra-iota))
  625. (define i1 (ra-transpose (ra-iota) 1))
  626. (ra-map! (make-ra #f 2 2) list (list->ra 2 '((A B) (C D))) i0 i1)
  627. @end verbatim
  628. @result{} #%2:2:2(((A 0 0) (B 0 1)) ((C 1 0) (D 1 1)))
  629. @end example
  630. One can iterate not only over the whole array, but also over any @code{n}-frame (the first @code{n} axes of an array), using @ref{x-ra-slice-for-each, @code{ra-slice-for-each}}. 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.
  631. In the following example, @code{xys} is of rank 2, @code{angle} is of rank 1, and their first axes have the same length.
  632. @example
  633. @verbatim
  634. (ra-slice-for-each 1
  635. (λ (xy angle)
  636. ; inside the op, xy is rank 1, angle is rank 0
  637. (ra-set! angle (atan (ra-ref xy 1) (ra-ref xy 0))))
  638. xys angles)
  639. @end verbatim
  640. @end example
  641. @cindex prefix matching
  642. The iteration procedures in @code{newra} all perform rank extension of their arguments through prefix matching (see @ref{Rank extension}). In the following example, the shapes of the arguments are (5 5), (5) and (@code{#f} 5), and the common prefixes all match.
  643. @example
  644. @verbatim
  645. (ra-map! (make-ra 5 5) * (ra-iota 5 1) (ra-transpose (ra-iota 5 1) 1))
  646. @end verbatim
  647. @result{} @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))}
  648. @end example
  649. Another example using @ref{x-ra-copy!, @code{ra-copy!}},
  650. @example
  651. @verbatim
  652. (ra-copy! (list->ra 2 '((a b) (p q) (x y)))
  653. (list->ra 1 '(1 2 3)))
  654. @end verbatim
  655. @result{} @code{#%2:3:2((1 1) (2 2) (3 3))}
  656. @end example
  657. @c ------------------------------------------------
  658. @node Slicing
  659. @section Slicing
  660. @c ------------------------------------------------
  661. 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 @ref{x-ra-ravel, @code{ra-ravel}}, @ref{x-ra-reshape, @code{ra-reshape}} and @ref{x-ra-transpose, @code{ra-transpose}}, and of course by direct modification of the dim vector, but the facilities described in this section are usually a lot clearer.
  662. @cindex prefix slice
  663. The simplest form of slicing uses @ref{x-ra-slice, ra-slice} to produce ‘prefix slices’.
  664. @example
  665. @verbatim
  666. (define a (list->ra 3 '(((a b) (x y)) ((A B) (X Y)))))
  667. @end verbatim
  668. @result{} @code{#%3:2:2:2(((a b) (x y)) ((A B) (X Y)))}
  669. @verbatim
  670. (ra-slice a 0 1 0)
  671. @end verbatim
  672. @result{} @code{#%0(x)}
  673. @verbatim
  674. (ra-slice a 0 1)
  675. @end verbatim
  676. @result{} @code{#%1:2(x y)}
  677. @verbatim
  678. (ra-slice a 0)
  679. @end verbatim
  680. @result{} @code{#%2:2:2((a b) (x y))}
  681. @verbatim
  682. (ra-slice a)
  683. @end verbatim
  684. @result{} @code{#%3:2:2:2(((a b) (x y)) ((A B) (X Y)))}
  685. @end example
  686. The prefix slice always shares the root of the source array, so it can be used to modify the source array.
  687. @example
  688. @verbatim
  689. (ra-fill! (ra-slice a 1 0) '99)
  690. @end verbatim
  691. @result{} @code{#%1:2(99 99)}
  692. @verbatim
  693. a
  694. @end verbatim
  695. @result{} @code{#%3:2:2:2(((a b) (x y)) ((99 99) (X Y)))}
  696. @end example
  697. The variant @ref{x-ra-cell, @code{ra-cell}} is identical to @code{ra-slice} except that it returns an element (and not a rank 0 array) when the full set of indices is given.
  698. @example
  699. @verbatim
  700. (ra-slice a 0 1 0)
  701. @end verbatim
  702. @result{} @code{x}
  703. @end example
  704. @code{ra-cell} is a @ref{Rank polymorphism, rank-polymorphic} generalization of the basic element lookup function @ref{x-ra-ref, @code{ra-ref}}, which requires the full set of indices.
  705. @example
  706. @verbatim
  707. (ra-ref a 0 1 0) ; same as ra-cell
  708. @end verbatim
  709. @result{} @code{x}
  710. @verbatim
  711. (ra-ref a 0 1)
  712. @end verbatim
  713. @result{} @code{"<unnamed port>":...: Throw to key `bad-number-of-indices' with args `(3 2)'.}
  714. @end example
  715. Both @code{ra-cell} and @code{ra-slice} (and @code{ra-ref}) take scalar indices as arguments. The more powerful function @ref{x-ra-from, @code{ra-from}} is able to handle arrays of indices.
  716. @cindex @code{@{}, from
  717. @quotation
  718. @verbatim
  719. (ra-from a i₀ ...) ⇒ b
  720. @end verbatim
  721. @end quotation
  722. Each of the @code{i₀...} is either 1. an integer; 2. an array of integers; 3. the special value @code{#t}. Integer arguments contain indices into the respective axis of @code{a}. @code{#t} for @code{iₖ} is a shortcut for ‘the whole of axis @code{k}’@footnote{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)))}, because the lower bound of @code{(ra-iota ...)} (@emph{not} its content) is 0, not @code{(dim-lo d)}, so the corresponding lower bound on the result array would also be 0, while @code{#t} preserves the lower bound of @code{a}.}. The result @code{b} has rank equal to the sum of all the ranks of the @code{i₀...}, and is defined as
  723. @quotation
  724. @verbatim
  725. (ra-ref b j₀ ...) = (ra-ref a (ra-ref i₀ j₀ ...) ...)
  726. @end verbatim
  727. @end quotation
  728. In other words, @code{ra-from} produces the outer product of the indices @code{i₀...} with operator @code{a} (if one thinks of @code{(a i₀ ...)} as @code{(ra-ref a i₀ ...)}). The rank of this outer product is @math{\mathrm{rank}\,A + \sum_i (\mathrm{rank}\,i - 1)}.
  729. If all of the @code{i...} are integers or arrays of type @code{d} (such as those produced by @code{ra-iota} or @code{ra-i}) then the result of @code{ra-from} shares the root of @code{a}. Otherwise @code{newra} cannot tell whether the indices are an arithmetic sequence, so the result has to be copied to a new root. For example:
  730. @example
  731. @verbatim
  732. (define a (list->ra 2 '((a b c) (d e f))))
  733. @end verbatim
  734. @result{} @code{#%2:2:3((a b c) (d e f))}
  735. @verbatim
  736. (ra-from a 0 #t) ; row 0, will share root
  737. @end verbatim
  738. @result{} @code{#%1:3(a b c)}
  739. @verbatim
  740. (ra-from a #t 1) ; column 1, will share root
  741. @end verbatim
  742. @result{} @code{#%1:2(b e)}
  743. @verbatim
  744. (ra-from a #t (make-ra-root #(2 0))) ; cols 2 & 0, won't share root
  745. @end verbatim
  746. @result{} @code{#%2:2:2((c a) (f d))}
  747. @verbatim
  748. (ra-from a #t (ra-iota 2 2 -2)) ; cols 2 & 0, will share root
  749. @end verbatim
  750. @result{} @code{#%2:2:2((c a) (f d))}
  751. @end example
  752. One may give fewer @code{i} than the rank of @code{a}. The missing arguments are taken as @code{#t} (see @ref{Rank polymorphism}).
  753. @example
  754. @verbatim
  755. (ra-from a 0) ; row 0, same as (ra-from a 0 #t)
  756. @end verbatim
  757. @result{} @code{#%1d:3(0 1 2)}
  758. @end example
  759. @cindex @code{dots}
  760. When used as an argument to @code{ra-from} (or @code{ra-amend!}), the special object @code{(@ref{x-dots, dots} n)} stands for @code{n} times @code{#t}. @code{(dots)} alone will expand to fill the rank of the array argument, so the indices that come after are pushed to the last axes.
  761. @example
  762. @verbatim
  763. (ra-from A 0 (dots 1) 1) ; same as (ra-from A 0 #t 1)
  764. (ra-from B 0 (dots 2) 1) ; same as (ra-from B 0 #t #t 1)
  765. (ra-from C 0 (dots) 1) ; same as (ra-from C 1 (dots (- (ra-rank C) 2)) 1)
  766. @end verbatim
  767. @end example
  768. For instance:
  769. @example
  770. @verbatim
  771. (ra-i 4 3 2)
  772. @end verbatim
  773. @result{} #%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)))
  774. @verbatim
  775. (ra-from (ra-i 4 3 2) (dots) 1) ; select second element on last axis
  776. @end verbatim
  777. @result{} #%2d:4:3((1 3 5) (7 9 11) (13 15 17) (19 21 23))
  778. @end example
  779. Array application @code{(A i₀ ...)} is equivalent to @code{(ra-from A i₀ ...)}, except that whenever the result of @code{(ra-from A i₀ ...)} has rank-0, @code{(A i₀ ...)} returns the element of that result instead.@footnote{It's still possible for array application to return a rank-0 array if that element is itself a rank-0 array, e.g.
  780. @example
  781. ((make-ra (make-ra 'x)))
  782. @result{} #%0(x)
  783. @end example
  784. }
  785. @example
  786. @verbatim
  787. (ra-from (ra-i 2 3) 1 1)
  788. @end verbatim
  789. @result{} @code{#%0(4)}
  790. @verbatim
  791. ((ra-i 2 3) 0 0)
  792. @end verbatim
  793. @result{} 4
  794. @end example
  795. When it is known that the result of @code{ra-from} will share the root with its argument, that can be used to modify the original array. For example:
  796. @example
  797. @verbatim
  798. (define a (list->ra 2 '((a b c) (d e f))))
  799. (ra-fill! (ra-from a 1) x)
  800. @end verbatim
  801. @result{} @code{#%2:3((a b c) (x x x)}
  802. @verbatim
  803. a
  804. @end verbatim
  805. @result{} @code{#%2:3((a b c) (x x x))}
  806. @end example
  807. @ref{x-ra-amend!, @code{ra-amend!}} handles the general case:
  808. @example
  809. @verbatim
  810. (define a (list->ra 2 '((a b c) (d e f))))
  811. (ra-amend! a 'Y #t (make-ra-root #(2 0)))
  812. @end verbatim
  813. @result{} @code{#%2:3((Y b Y) (Y e Y))}
  814. @verbatim
  815. a
  816. @end verbatim
  817. @result{} @code{#%2:3((Y b Y) (Y e Y))}
  818. @end example
  819. while on the other hand
  820. @example
  821. @verbatim
  822. (define a (list->ra 2 '((a b c) (d e f))))
  823. (ra-fill! (ra-from a #t (make-ra-root #(2 0))) 'Y)
  824. @end verbatim
  825. @result{} @code{#%2:3((Y Y) (Y Y))}
  826. @verbatim
  827. a
  828. @end verbatim
  829. @result{} @code{#%2:3((a b c) (d e f))}
  830. @end example
  831. @c ------------------------------------------------
  832. @node Reshaping
  833. @section Reshaping
  834. @c ------------------------------------------------
  835. @cindex APL
  836. @cindex @code{,}, ravel
  837. @cindex @code{⍴}, reshape
  838. To match APL ρ, @code{newra} offers three separate functions.
  839. @ref{x-ra-reshape, @code{ra-reshape}} and @ref{x-ra-ravel, @code{ra-ravel}} are in a way the inverse of each other. @code{ra-reshape} folds an axis into (potentially) many, while @code{ra-ravel} makes a block of axes into a single axis. Neither is able to increase the size of the array (although @code{ra-reshape} can @emph{reduce} it). For that purpose @ref{x-ra-tile, @code{ra-tile}} is provided.
  840. @example
  841. @verbatim
  842. (ra-dimensions (ra-i 2 3 4))
  843. @end verbatim
  844. @result{} (2 3 4)
  845. @verbatim
  846. ; insert new axis of size 5 before axis 0
  847. (ra-dimensions (ra-tile (ra-i 2 3 4) 0 5))
  848. @end verbatim
  849. @result{} (5 2 3 4)
  850. @verbatim
  851. ; collapse axes 0 and 1
  852. (ra-dimensions (ra-ravel (ra-tile (ra-i 2 3 4) 0 5) 2))
  853. @end verbatim
  854. @result{} (10 3 4)
  855. @verbatim
  856. ; reshape axis 0 into two axes with shape [3 3]
  857. (ra-dimensions (ra-reshape (ra-ravel (ra-tile (ra-i 2 3 4) 0 5) 2) 0 3 3))
  858. @end verbatim
  859. @result{} (3 3 3 4)
  860. @end example
  861. @code{ra-reshape} and @code{ra-tile} always reuse the root of the argument. On the other hand @code{ra-ravel} 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} will reuse the root with the function @ref{x-ra-order-c?, @code{ra-order-c?}}.
  862. @c ------------------------------------------------
  863. @node Concatenation
  864. @section Concatenation
  865. @c ------------------------------------------------
  866. @cindex concatenation
  867. @code{newra} offers two concatenation operations: @ref{x-ra-cat, @code{ra-cat}} (prefix cat) and @ref{x-ra-cats, @code{ra-cats}} (cat suffix).
  868. For @code{ra-cat}, the arguments are prefix-matched, and the concatenation axis is counted from the left. E.g. for three arrays @var{r}, @var{s}, @var{t} with shapes
  869. @example
  870. @verbatim
  871. (r₀ r₁ r₂ r₃)
  872. (s₀ s₁ s₂ s₃ s₄ s₅)
  873. (t₀ t₁)
  874. @end verbatim
  875. @end example
  876. Then @code{(define val (ra-cat #t 1 r s t))} will prefix-match these to (it is an error if any of @code{r₀=s₀=t₀}, @code{r₂=s₂}, or @code{r₃=s₃} don't hold)
  877. @example
  878. @verbatim
  879. (s₀ |r₁| s₂ s₃ s₄ s₅)
  880. (s₀ |s₁| s₂ s₃ s₄ s₅)
  881. (s₀ |t₁| s₂ s₃ s₄ s₅)
  882. @end verbatim
  883. @end example
  884. and then concatenate them along axis 1 into an array of shape @code{(s₀ (r₁+s₁+t₁) s₂ s₃ s₄ s₅)}.
  885. For @code{ra-cats}, the arguments are suffix-matched, and the concatenation axis is counted from the right. For example
  886. @example
  887. @verbatim
  888. (define r (ra-i 2 3 2))
  889. (define s (list->ra 1 '(a b)))
  890. (ra-cats #t 1 r s)
  891. @end verbatim
  892. @end example
  893. the axes are aligned as
  894. @example
  895. @verbatim
  896. (r₀ r₁ r₂)
  897. (s₀)
  898. @end verbatim
  899. @end example
  900. and suffix-matched (s₀ and r₂ must match)
  901. @example
  902. @verbatim
  903. (r₀ |r₁| r₂)
  904. (r₀ | 1| s₀)
  905. @end verbatim
  906. @end example
  907. for a result
  908. @example
  909. @verbatim
  910. (ra-cats #t 1 r s)
  911. @end verbatim
  912. @result{} @code{#%3(((0 1) (2 3) (4 5) (a b)) ((6 7) (8 9) (10 11) (a b)))}
  913. @end example
  914. Note that the rank extension of @code{s} on the concatenation axis yields a length of 1 (and not @code{r₁}). It can be useful to think of the axis argument of @code{ra-cats} as indicating cell rank, so the code above means `concatenate 1-cells'.
  915. For both @code{ra-cat} and @code{ra-cats}, axes other than the concatenation axis must match across all of the arguments.
  916. @example
  917. @verbatim
  918. (ra-cat #t 0 (ra-i 3 2) (ra-i 2))
  919. @end verbatim
  920. @result{} @code{#%2:4:2((0 1) (2 3) (4 5) (0 0) (1 1))}
  921. @end example
  922. @example
  923. @verbatim
  924. (ra-cats #t 1 (ra-i 3 2) (ra-i 2))
  925. @end verbatim
  926. @result{} @code{#%2:4:2((0 1) (2 3) (4 5) (0 1))}
  927. @end example
  928. In particular, it is not enough for the lengths to be the same; both bounds must match.
  929. @example
  930. @verbatim
  931. (ra-cat #t 0 (make-ra 'a '(1 1) '(1 4))
  932. (make-ra 'b '(2 2) '(1 4)))
  933. @end verbatim
  934. @result{} @code{#%2:2@@1:4((a a a a) (b b b b))} ; axes 1 match, axes 0 don't need to
  935. @end example
  936. @example
  937. @verbatim
  938. (ra-cat #t 1 (make-ra 'a '(1 1) '(1 4))
  939. (make-ra 'b '(2 2) '(1 4)))
  940. @end verbatim
  941. @result{} error ; axes 0 don't match
  942. @end example
  943. Here @ref{x-ra-reshape,@code{ra-reshape}} is used to move axis 0 of the second argument into agreement.@footnote{An example of how using lower bounds other than 0 is not worth the trouble, not least for the library author.}
  944. @example
  945. @verbatim
  946. (ra-cat #t 1 (make-ra 'a '(1 1) '(1 4))
  947. (ra-reshape (make-ra 'b '(2 2) '(1 4)) 0 '(1 1)))
  948. @end verbatim
  949. @result{} @code{#%2@@1:1:8((a a a a b b b b))}
  950. @end example
  951. On the concatenation axis, only lengths matter; for both @code{ra-cat} and @code{ra-cats}, the lower bound is 0 in the result, and the lower bounds of the arguments are ignored.
  952. @example
  953. @verbatim
  954. (define a (make-ra 'a '(1 2) '(2 3)))
  955. (define b (make-ra 'b '(1 2)))
  956. (define c (make-ra 'c '(1 2) '(-1 0)))
  957. (ra-format (ra-cat #t 1 a b c))
  958. @end verbatim
  959. @result{}
  960. @verbatim
  961. #%2@1:2:5─┐
  962. │a│a│b│c│c│
  963. ├─┼─┼─┼─┼─┤
  964. │a│a│b│c│c│
  965. └─┴─┴─┴─┴─┘
  966. @end verbatim
  967. @end example
  968. Both @code{ra-cat} and @code{ra-cats} accept a negative concatenation axis. That will rank-extend all the arguments to the left (@code{ra-cat}) or to the right (@code{ra-cats}) before concatenating on the leftmost (@code{ra-cat}) or rightmost (@code{ra-cats}) axis. In the same way, one may give a concatenation axis which is beyond the rank of the argument with the highest rank. Consider
  969. @example
  970. @verbatim
  971. (define abc (list->ra 1 #(a b c)))
  972. (ra-cat #t -1 (ra-i 3) abc)
  973. @end verbatim
  974. @result{} @code{#%2:2:3((0 1 2) (a b c))}
  975. @end example
  976. @example
  977. @verbatim
  978. (ra-cat #t 0 (ra-i 3) abc)
  979. @end verbatim
  980. @result{} @code{#%1:6(0 1 2 a b c)}
  981. @end example
  982. @example
  983. @verbatim
  984. (ra-cat #t 1 (ra-i 3) abc)
  985. @end verbatim
  986. @result{} @code{#%2:3:2((0 a) (1 b) (2 c))}
  987. @end example
  988. vs
  989. @example
  990. @verbatim
  991. (ra-cats #t -1 (ra-i 3) abc)
  992. @end verbatim
  993. @result{} @code{#%2:3:2((0 a) (1 b) (2 c))}
  994. @end example
  995. @example
  996. @verbatim
  997. (ra-cats #t 0 (ra-i 3) abc)
  998. @end verbatim
  999. @result{} @code{#%1:6(0 1 2 a b c)}
  1000. @end example
  1001. @example
  1002. @verbatim
  1003. (ra-cats #t 1 (ra-i 3) abc)
  1004. @end verbatim
  1005. @result{} @code{#%2:2:3((0 1 2) (a b c))}
  1006. @end example
  1007. Cf J append (,) stitch (,.).
  1008. @c ------------------------------------------------
  1009. @node Transposition
  1010. @section Transposition
  1011. @c ------------------------------------------------
  1012. @cindex @code{⍉}, transpose
  1013. @cindex transpose
  1014. @ref{x-ra-transpose, @code{ra-transpose}} 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.
  1015. @example
  1016. @verbatim
  1017. (ra-dimensions (ra-transpose (ra-i 10 20 30) 2 0 1))
  1018. @end verbatim
  1019. @result{} @code{'(20 30 10)}
  1020. @end example
  1021. 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.
  1022. As you'd expect
  1023. @example
  1024. @verbatim
  1025. (ra-transpose (ra-i 2 3) 1 0)
  1026. @end verbatim
  1027. @result{} @code{#%2d:3:2((0 3) (1 4) (2 5))}
  1028. @end example
  1029. 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
  1030. @cindex diagonal
  1031. @example
  1032. @verbatim
  1033. (define A (ra-copy #t (ra-i 3 3)))
  1034. (ra-fill! (ra-transpose A 0 0) 'x)
  1035. A
  1036. @end verbatim
  1037. @result{} @code{#%2:3:3((x 1 2) (3 x 5) (6 7 x))}
  1038. @end example
  1039. 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:
  1040. @example
  1041. @verbatim
  1042. (ra-transpose (ra-i 2 3 4) 1 0 2)
  1043. (ra-transpose (ra-i 2 3 4) 1 0) ; fill with (+ 1 (max 1 0))
  1044. @end verbatim
  1045. @end example
  1046. as are these:
  1047. @example
  1048. @verbatim
  1049. (ra-transpose (ra-i 2 3) 1) ; fill with (+ 1 (max 1))
  1050. (ra-transpose (ra-i 2 3) 1 2)
  1051. @end verbatim
  1052. @end example
  1053. 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 @ref{x-dead-axes,dead axes}. The rank of the result array is always just large enough to fit all the destination axes.
  1054. @example
  1055. @verbatim
  1056. (ra-dimensions (ra-transpose (ra-i 2 3) 1))
  1057. @end verbatim
  1058. @result{} (#f 2 3)
  1059. @end example
  1060. In particular, @code{(ra-transpose A)} is equivalent to @code{(ra-transpose A 0 1 ... (- (ra-rank A) 1))} (which is of course the same array as @code{A}).
  1061. @cindex outer product
  1062. This ability of @code{ra-transpose} can be exploited to compute `outer products'. In the following example the shape @code{[2 2]} of @code{A} matches with the two leading dead axes of @code{(ra-transpose B 2)}:
  1063. @example
  1064. @verbatim
  1065. A : [ 2 2]
  1066. (ra-transpose B 2) : [#f #f 2 2]
  1067. @end verbatim
  1068. @end example
  1069. @cindex prefix matching
  1070. The trailing axes then match through @ref{Rank extension,prefix matching}.
  1071. @example
  1072. @verbatim
  1073. (define A (list->ra 2 '((a b) (c d))))
  1074. (define B (ra-i 2 2))
  1075. (ra-format (ra-map! (make-ra #f 2 2 2 2)
  1076. (λ i (format #f "~{~a~}" i))
  1077. A (ra-transpose B 2)))
  1078. @end verbatim
  1079. @result{}
  1080. @verbatim
  1081. #%4:2:2:2:2═╗
  1082. ║a0│a1║b0│b1║
  1083. ║──┼──║──┼──║
  1084. ║a2│a3║b2│b3║
  1085. ╠═════╬═════╣
  1086. ║c0│c1║d0│d1║
  1087. ║──┼──║──┼──║
  1088. ║c2│c3║d2│d3║
  1089. ╚═════╩═════╝
  1090. @end verbatim
  1091. @end example
  1092. @cindex index placeholder
  1093. Another use is the creation of ‘index placeholders’, e.g.
  1094. @example
  1095. @verbatim
  1096. (define (tensor-index i) (ra-transpose (ra-iota) i))
  1097. (ra-format (ra-map! (make-ra #f 3 4) list (tensor-index 0) (tensor-index 1)))
  1098. @end verbatim
  1099. @result{}
  1100. @verbatim
  1101. #%2:3:4─────┬─────┬─────┐
  1102. │(0 0)│(0 1)│(0 2)│(0 3)│
  1103. ├─────┼─────┼─────┼─────┤
  1104. │(1 0)│(1 1)│(1 2)│(1 3)│
  1105. ├─────┼─────┼─────┼─────┤
  1106. │(2 0)│(2 1)│(2 2)│(2 3)│
  1107. └─────┴─────┴─────┴─────┘
  1108. @end verbatim
  1109. @end example
  1110. @cindex ⍋, grade
  1111. @cindex grade
  1112. The function @ref{x-ra-untranspose, @code{ra-untranspose}} takes its axis arguments the other way from @code{ra-transpose}; 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}, but can be used to reverse an application of @code{ra-transpose} without having to sort (‘grade’) the original axis arguments.
  1113. @example
  1114. @verbatim
  1115. (define a (ra-i 2 3 4))
  1116. (ra-equal? a (ra-untranspose (ra-transpose a 2 0 1) 2 0 1))
  1117. @end verbatim
  1118. @result{} @code{#t}
  1119. @end example
  1120. @c @cindex @code{none}
  1121. @c @anchor{x-none}
  1122. @c @deffn @w{Special objects} {none}
  1123. @c For example...
  1124. @c @example
  1125. @c @verbatim
  1126. @c For example
  1127. @c @end verbatim
  1128. @c @end example
  1129. @c @end deffn
  1130. @c ------------------------------------------------
  1131. @node Other operations on arrays
  1132. @section Other operations on arrays
  1133. @c ------------------------------------------------
  1134. @c ------------------------------------------------
  1135. @node Automatic result arrays
  1136. @section Automatic result arrays
  1137. @c ------------------------------------------------
  1138. Most of the functions of @code{newra} 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 @ref{x-ra-copy, @code{ra-copy}} or @ref{x-ra-map, @code{ra-map}}, that do create a result array. The type and shape of that result array is deduced from the source arguments, as follows.
  1139. @itemize
  1140. @item The default type of the result array is the type of the first of the source arguments. If that type is @code{'d}, however, the default type of the result array is @code{#t}. Usually, a function will allow this default to be overriden with an explicit argument. If that argument is required, then @code{#f} will select the default.
  1141. @item 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}, then it follows that that is the shape of the result.)
  1142. @end itemize
  1143. For example:
  1144. @example
  1145. @verbatim
  1146. (ra-map #t *
  1147. ; shape '((0 1))
  1148. (ra-iota 2 1)
  1149. ; shape '((#f #f) (1 3))
  1150. (ra-transpose (make-ra 9 '(1 3)) 1))
  1151. @end verbatim
  1152. @result{}
  1153. @verbatim
  1154. ; shape of result is '((0 1) (1 3))
  1155. #%2:2@1:3((9 9 9) (18 18 18)
  1156. @end verbatim
  1157. @end example
  1158. @c ------------------------------------------------
  1159. @node Foreign interface
  1160. @section Foreign interface
  1161. @c ------------------------------------------------
  1162. 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} array object.
  1163. For example:
  1164. TODO
  1165. @c ------------------------------------------------
  1166. @node Compatibility with old Guile arrays
  1167. @section Compatibility with old Guile arrays
  1168. @c ------------------------------------------------
  1169. The functions @ref{x-ra->array, @code{ra->array}} and @ref{x-array->ra, @code{array->ra}} are provided to convert to and from @code{newra} arrays and built-in Guile arrays. It is an error to use @code{ra->array} 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.
  1170. @example
  1171. @verbatim
  1172. (define a (make-array 'o 2 3))
  1173. (define b (array->ra a))
  1174. (ra-set! b 'x 1 1)
  1175. (array-set! a 'y 0 2)
  1176. a
  1177. @end verbatim
  1178. @result{} @code{#2((o o y) (o x o))}
  1179. @verbatim
  1180. b
  1181. @end verbatim
  1182. @result{} @code{#%2((o o y) (o x o))}
  1183. @end example
  1184. @code{<aseq>}-root arrays must be type converted before using @code{ra->array}.
  1185. @example
  1186. @verbatim
  1187. (ra->array (ra-copy #t (ra-i 2 3)))
  1188. @end verbatim
  1189. @result{} #2((0 1 2) (3 4 5))
  1190. @end example
  1191. On dead axes, lengths can be set to 1 (with @ref{x-ra-singletonize, @code{ra-singletonize}}) to allow conversion with @code{ra->array} or to other array systems that do singleton broadcasting.
  1192. @example
  1193. @verbatim
  1194. (define a (ra-transpose (ra-i 2 3) 1 3))
  1195. a
  1196. @end verbatim
  1197. @result{} @code{#%4d:d:2:d:3((((0 1 2)) ((3 4 5))))}
  1198. @verbatim
  1199. (ra-singletonize a)
  1200. @end verbatim
  1201. @result{} @code{#%4d:1:2:1:3((((0 1 2)) ((3 4 5))))}
  1202. @end example
  1203. One important difference between the built-in array functions and @code{newra} is that bounds matching in @code{newra} is strict: finite bounds must be identical for axes to match, while for @code{array-map!}, @code{array-for-each}, @code{array-copy!}, etc. the iteration range is the intersection of the ranges of the arguments@footnote{I decided against this approach for @code{newra} because in my experience it results in errors going undetected more often than it saves any work.}. @code{newra} provides @ref{x-ra-clip, @code{ra-clip}} to match ranges easily.
  1204. @example
  1205. @verbatim
  1206. (define a (make-ra-root (vector 'a 'b 'c 'd 'e 'f 'g))) ; range is 0..6
  1207. (define b (ra-reshape (ra-iota 4) 0 '(2 5))) ; range is 2..5
  1208. (ra-copy! a b)
  1209. @end verbatim
  1210. @result{} @code{Throw to key `mismatched-lens' with args `(7 4 at-dim 0)'.}
  1211. @verbatim
  1212. (ra-copy! (ra-clip a b) b)
  1213. a
  1214. @end verbatim
  1215. @result{} @code{#%1:7(a b 0 1 2 3 g)}
  1216. @c Cf. using built-in arrays @c Looks like a Guile bug to me :-/
  1217. @c @verbatim
  1218. @c (define a (vector 'a 'b 'c 'd 'e 'f 'g)))
  1219. @c (define b #1@2:4(0 1 2 3))
  1220. @c (array-copy! b a)
  1221. @c a
  1222. @c @end verbatim
  1223. @c @result{} @code{#(0 1 2 3 e f g)}
  1224. @end example
  1225. @c ------------------------------------------------
  1226. @node The array language
  1227. @chapter The array language
  1228. @c ------------------------------------------------
  1229. NOTE This section is about a facility that hasn't been implemented yet.
  1230. 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)} instead of @code{(ra-map #f + A B)}. The basic @code{newra} iteration operations such as @code{ra-map} already perform rank extension of their arguments (so @code{A} or @code{B} can have a different rank from the result, as long as the prefix axes match). We still need ways to:
  1231. @itemize
  1232. @item
  1233. associate an operation to the ranks of their arguments, so that the right frame of iteration can be chosen.
  1234. @item
  1235. compute the shape and type of the result (if any).
  1236. @item
  1237. handle scalar (non-array) arguments.
  1238. @end itemize
  1239. @c ------------------------------------------------
  1240. @node Verbs
  1241. @section Verbs
  1242. @c ------------------------------------------------
  1243. @c ------------------------------------------------
  1244. @node Reductions
  1245. @section Reductions
  1246. @c ------------------------------------------------
  1247. @c ------------------------------------------------
  1248. @node Hazards
  1249. @chapter Hazards
  1250. @c ------------------------------------------------
  1251. @c ------------------------------------------------
  1252. @node Differences with...
  1253. @section Differences with...
  1254. @c ------------------------------------------------
  1255. If you come to @code{newra} from another array language or library, you may want to be aware of some of these differences. See also the @ref{Cheatsheet}.
  1256. Differences with built-in Guile arrays
  1257. @itemize
  1258. @item @code{newra} 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.
  1259. @end itemize
  1260. Differences with array SRFIs
  1261. For the most part these differences stem from @code{newra} following the conventions of Guile's built in array API.
  1262. @itemize
  1263. @item SRFI-25 uses @code{[)} array bounds, while @code{newra} uses @code{[]} array bounds like Guile's built arrays.
  1264. @item SRFI-25 uses arrays as shape arguments, while @code{newra} uses lists like in Guile's built in array functions.
  1265. @item SRFI-163 uses @code{#}@var{RANK}@code{a} for literal arrays of Scheme values, while @code{newra} uses @code{#%}@var{RANK} instead (@code{#%}@var{RANK}@code{a} is used for literal arrays of characters, following Guile's built in @code{#}@var{RANK}@code{a}).
  1266. @item SRFI-163 uses @code{#0 x} for a literal rank-0 array, while @code{newra} uses @code{#0(x)} (this is configurable with @ref{x-star-ra-parenthesized-rank-zero-star, @code{*ra-parenthesized-rank-zero*}}).
  1267. @end itemize
  1268. @cindex APL
  1269. Differences with APL
  1270. @itemize
  1271. @item The default lower bound (base index) in @code{newra} is 0, as in @code{⎕io←0}. The lower bound isn't global, but it may be different per axis.
  1272. @item @code{newra} arrays of size 1 are not equivalent to scalars and always retain their rank. For example, @code{(make-ra 99)}, @code{(make-ra 99 1)} and @code{(make-ra 99 1 1)} are all different from each other and from the scalar @code{99}, while in APL @code{99}, @code{(1 ⍴ 99)}, and @code{(1 1 ⍴ 99)} are all the same thing.
  1273. @item 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{(ra-transpose a 0)}≡@code{(ra-transpose a 0 1)}, but (assuming @code{a} is of rank 2) @code{⍉a}≡@code{1 0⍉a}. Please check the documentation for each function.
  1274. @end itemize
  1275. @cindex Fortran
  1276. Differences with Fortran
  1277. @itemize
  1278. @item The default lower bound (base index) in @code{newra} is 0, not 1. Like in Fortran, the lower bound may be different for each axis of each array.
  1279. @item 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}) only support row-major order.
  1280. @item @code{newra} uses prefix matching for rank extension on arguments on any rank, while Fortran only performs rank extension on scalar arguments.
  1281. @end itemize
  1282. @cindex Python
  1283. @cindex NumPy
  1284. Differences with NumPy
  1285. @itemize
  1286. @item @code{newra} uses prefix matching for rank extension, while NumPy uses suffix matching (@ref{x-numpy-example-0,example}).
  1287. @item @code{newra} doesn't support singleton broadcasting. Axes of length 1 only match either axes of length 1, or @ref{x-dead-axes,dead axes}. For example, @code{(ra-map #f + (make-ra 90 1) (make-ra 7 2))} is an error because the shapes (2), (1), (2) don't agree.
  1288. @end itemize
  1289. @cindex Octave
  1290. @cindex Matlab
  1291. Differences with Octave
  1292. @itemize
  1293. @item The default lower bound (base index) in @code{newra} is 0, not 1. Lower bounds may be 1 on a particular array (or particular axes of an array), but not globally.
  1294. @item In Octave, the lowest rank an array can be is 2. This isn't true in @code{newra}, so, for example, an array of rank 1 isn't equivalent to an array of rank 2 with a single row (a ‘row vector’).
  1295. @item 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}) only support row-major order.
  1296. @item @code{newra} uses prefix matching for rank extension on arguments on any rank, while Octave only performs rank extension on scalar arguments.
  1297. @end itemize
  1298. @c ------------------------------------------------
  1299. @node Pitfalls and common mistakes
  1300. @section Pitfalls and common mistakes
  1301. @c ------------------------------------------------
  1302. @subsection Using rank extension or dead axes for reduction
  1303. 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} 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} or @code{ra-map!} can be preserved even if (when?) those operations are actually implemented in parallel. However, that still leaves the order of traversal unspecified.
  1304. In that light, the following reduction should be alright when @var{op} is @code{+}, but it's better avoided it if @var{op} is @code{-}, even if it happens to do what you expect on the current version of @code{newra}.
  1305. @example
  1306. @verbatim
  1307. (let ((sum (make-ra 0)))
  1308. (ra-map! sum op sum (list->ra 1 '(1 2 3 4 5)))
  1309. (sum))
  1310. @end verbatim
  1311. @result{} @code{15}
  1312. @end example
  1313. For cases where it matters, it's better to use a function which specifies the order of evaluation, such as @code{ra-fold}.
  1314. @cindex @code{ra-slice-for-each}
  1315. @subsection Holding onto the arguments of @ref{x-ra-slice-for-each,@code{ra-slice-for-each}}'s @var{op}
  1316. @ref{x-ra-slice-for-each,@code{ra-slice-for-each}} may reuse the same array object for different calls to @var{op}. For example
  1317. @example
  1318. @verbatim
  1319. ; `keep the last row that begins with 3' (wrong)
  1320. (let ((a #f))
  1321. (ra-slice-for-each 1
  1322. (lambda (row) (when (= 3 (row 0)) (set! a row)))
  1323. (list->ra 2 '((2 3) (3 5) (3 a) (1 2))))
  1324. a)
  1325. @end verbatim
  1326. @result{} @code{#%1:2(2 3)} ; ?? could be anything
  1327. @end example
  1328. For this to work reliably, you need to copy the array descriptor, which can be done with @ref{x-ra-slice,@code{ra-slice}}.
  1329. @example
  1330. @verbatim
  1331. ; `keep the last row that begins with 3' (fixed)
  1332. (let ((a #f))
  1333. (ra-slice-for-each 1
  1334. (lambda (row) (when (= 3 (row 0)) (set! a (ra-slice row))))
  1335. (list->ra 2 '((2 3) (3 5) (3 a) (1 2))))
  1336. a)
  1337. @end verbatim
  1338. @result{} @code{#%1:2(3 a)}
  1339. @end example
  1340. Of course, if it suits your purpose, you can also copy @var{row} into a new array, with its own storage, using @ref{x-ra-copy,@code{ra-copy}}.
  1341. @subsection Partial application in outer products
  1342. TODO
  1343. @c ------------------------------------------------
  1344. @node Reference
  1345. @chapter Reference
  1346. @c ------------------------------------------------
  1347. @cindex @code{array->ra}
  1348. @anchor{x-array->ra}
  1349. @deffn @w{Function} array->ra a
  1350. Convert built-in Guile array @var{a} (anything that satisfies @code{array?}) to a (@code{newra)} array.
  1351. This function doesn't create a copy of the array, but reuses the root (@code{shared-array-root}) of @var{a}, that is, @code{(eq? (ra-root (array->ra a)) (shared-array-root a))} is @code{#t}.
  1352. @example
  1353. @verbatim
  1354. (define a (make-array 'x 2 2))
  1355. (define b (array->ra v))
  1356. b
  1357. @end verbatim
  1358. @result{} @code{#%2:2:2((x x) (x x))}
  1359. @verbatim
  1360. (ra-fill! b 'y)
  1361. a
  1362. @end verbatim
  1363. @result{} @code{#2((y y) (y y))}
  1364. @end example
  1365. See also: @ref{x-ra->array,@code{ra->array}}.
  1366. @end deffn
  1367. @cindex @code{c-dims}
  1368. @anchor{x-c-dims}
  1369. @deffn @w{Function} c-dims bounds ...
  1370. @cindex packed array
  1371. Create dims (dim vector) for row-major order array (packed elements, last dimension changing fastest).
  1372. Each of the @var{bounds} may be an integer (a length) or a pair of integers (lower and upper bounds).
  1373. @example
  1374. @verbatim
  1375. (c-dims 2 3)
  1376. @end verbatim
  1377. @result{} @code{#(#<<dim> len: 2 lo: 0 step: 3> #<<dim> len: 3 lo: 0 step: 1>)}
  1378. @end example
  1379. The functions @ref{x-make-ra-new,@code{make-ra-new}} and @ref{x-make-ra-root,@code{make-ra-root}} take a dim vector as one of their arguments.
  1380. @end deffn
  1381. @cindex @code{dots}
  1382. @anchor{x-dots}
  1383. @deffn @w{Function} dots [n] ...
  1384. Placeholder for @var{n} full axes, used as argument to @code{ra-from} or @code{ra-amend!}. Without @var{n}, expand to fill the rank of the argument @var{a} of @ref{x-ra-from,@code{ra-from}} or @ref{x-ra-amend!,@code{ra-amend!}}.
  1385. @end deffn
  1386. @cindex @code{make-ra}
  1387. @anchor{x-make-ra}
  1388. @deffn @w{Function} make-ra val bounds ... @result{} a
  1389. Create an array of type @code{#t} with the given @var{bounds}, filled with @var{val}. Each of the bounds may be an integer (a length) or a pair of integers (lower and upper bounds).
  1390. @example
  1391. @verbatim
  1392. (make-ra 0 '(2 3) 4)
  1393. @end verbatim
  1394. @result{} @code{#%2@@2:2:4((0 0 0 0) (0 0 0 0))}
  1395. @end example
  1396. See also: @ref{x-make-typed-ra,@code{make-typed-ra}}, @ref{x-make-ra-new,@code{ra-make-ra-new}}, @ref{x-ra-shape,@code{ra-shape}}.
  1397. @end deffn
  1398. @cindex @code{make-ra-new}
  1399. @anchor{x-make-ra-new}
  1400. @deffn @w{Function} make-ra-new type value dims
  1401. Create an array over a new root of the given @var{type} and size (according to @var{dims}), and fill it with @var{value}.
  1402. @example
  1403. @verbatim
  1404. (make-ra-new 'u8 0 (c-dims 3 2))
  1405. @end verbatim
  1406. @result{} #%2u8:3:2((0 0) (0 0) (0 0))
  1407. @end example
  1408. @end deffn
  1409. @cindex @code{make-ra-root}
  1410. @anchor{x-make-ra-root}
  1411. @deffn @w{Function} make-ra-root root [dims [zero]]
  1412. Create an array over the given @var{root}.
  1413. @example
  1414. @verbatim
  1415. (make-ra-root (vector 1 2 3))
  1416. @end verbatim
  1417. @result{} #%1d:3(1 2 3)
  1418. @end example
  1419. @example
  1420. @verbatim
  1421. (make-ra-root (vector 1 2 3) (vector (make-dim 2)))
  1422. @end verbatim
  1423. @result{} #%1d:2(1 2)
  1424. @end example
  1425. @example
  1426. @verbatim
  1427. (make-ra-root (vector 1 2 3) (vector (make-dim 2)) 1)
  1428. @end verbatim
  1429. @result{} #%1d:2(2 3)
  1430. @end example
  1431. @end deffn
  1432. @cindex @code{make-typed-ra}
  1433. @anchor{x-make-typed-ra}
  1434. @deffn @w{Function} make-typed-ra type val bounds ... @result{} a
  1435. Same as @ref{x-make-ra,@code{make-ra}}, except that the result has the specified @var{type}.
  1436. See also: @ref{x-make-ra,@code{make-ra}}, @ref{x-make-ra-root,@code{ra-make-ra-root}}.
  1437. @end deffn @c make-typed-ra
  1438. @cindex @code{ra->array}
  1439. @anchor{x-ra->array}
  1440. @deffn @w{Function} ra->array a
  1441. Convert (@code{newra}) array @var{a} to built-in Guile array.
  1442. This function does not create a copy of the array, but reuses the root (@code{ra-root}) of @var{a}, that is, @code{(eq? (ra-root a) (shared-array-root (ra->array a)))} is @code{#t}.
  1443. Not all arrays can be converted to built-in Guile arrays. For example, type @code{d} arrays, or arrays with unbounded axes, are not convertible.
  1444. @example
  1445. @verbatim
  1446. (ra->array (ra-i 3)) ; error, type d not convertible
  1447. (ra->array (ra-copy (ra-i 3))) ; ok, (ra-copy (ra-i 3)) has type #t
  1448. (ra->array (ra-transpose (ra-i 2 3) 1)) ; error, not convertible
  1449. (ra->array (ra-singletonize (ra-transpose (ra-i 2 3) 1))) ; ok
  1450. @end verbatim
  1451. @end example
  1452. See also: @ref{x-array->ra,@code{array->ra}}, @ref{x-ra-singletonize,@code{ra-singletonize}}, @ref{x-ra-copy!,@code{ra-copy!}}.
  1453. @end deffn @c ra->array
  1454. @cindex @code{ra-amend!}
  1455. @anchor{x-ra-amend!}
  1456. @deffn @w{Function} ra-amend! a c i ... → a
  1457. Copy @var{c} to the outer product slice of @var{a} by indices @var{i} ...
  1458. @example
  1459. @verbatim
  1460. a(i₀(j₀₀ j₀₁ ...) i₁(j₁₀ j₁₁ ...) ...) ← c(j₀₀ j₀₁ ... j₁₀ j₁₁ ...)
  1461. @end verbatim
  1462. @end example
  1463. where @var{i} : @var{i₀} @var{i₁} ...
  1464. This is equivalent to @code{(ra-copy! (ra-from a i ...) c)} if @code{(ra-from a i ...)} would
  1465. return a shared ra of @var{a}, but it also works in other cases, as long as @var{a} is
  1466. writable. @var{i} may take any of the special values accepted by @code{ra-from}.
  1467. @example
  1468. @verbatim
  1469. (define a (list->ra 1 '(1 2 3)))
  1470. (define x 1)
  1471. (define y (array->ra #(1)))
  1472. (ra-amend! a 9 x) ; modifies a
  1473. (ra-amend! a (array->ra #0(9)) x) ; same thing
  1474. (ra-copy! (ra-from a x) (array->ra #0(9))) ; modifies a
  1475. (ra-amend! a 9 y) ; modifies a
  1476. (ra-copy! (ra-from a y) (array->ra #0(9))) ; (ra-from a y) is a new array, so a is NOT modified
  1477. (ra-amend! (array->ra #(2 3 4)) 9 1) ; error, (array->ra #(2 3 4)) is not mutable
  1478. @end verbatim
  1479. @end example
  1480. If @var{i} contains repeated indices or the steps of @var{a} make it so that the same elements of @var{a}
  1481. are referenced more than once, then the value that ends up in @var{a} may correspond to any of the
  1482. indices that match those elements. @code{newra} will @emph{not} check that each element of @var{a} is represented uniquely in its root.
  1483. @example
  1484. @verbatim
  1485. (ra-amend! a (array->ra #(6 7 8)) (ra-tile (array->ra #0(1)) 0 3))
  1486. @end verbatim
  1487. @result{} #%1:3(1 8 3) ; do not rely on 8 ending up there
  1488. @end example
  1489. This function returns the modified array @var{a}.
  1490. See also: @ref{x-ra-from,@code{ra-from}}, @ref{x-ra-copy!,@code{ra-copy!}} @ref{x-ra-cell,@code{ra-cell}} @ref{x-ra-ref,@code{ra-ref}} @ref{x-ra-slice,@code{ra-slice}} @ref{x-ra-set!,@code{ra-set!}}.
  1491. @end deffn @c ra-amend!
  1492. @cindex @code{ra-any}
  1493. @anchor{x-ra-any}
  1494. @deffn @w{Function} ra-any pred? a ...
  1495. See also: @ref{x-ra-fold,@code{ra-fold}}, @ref{x-ra-every,@code{ra-every}}.
  1496. @end deffn @c ra-any
  1497. @cindex @code{ra-cell}
  1498. @anchor{x-ra-cell}
  1499. @deffn @w{Function} ra-cell a i ...
  1500. Look up array cell.
  1501. Let @var{k} be the rank of @var{a} minus the number of @var{i ...} If @var{k} is zero, return the array element at @var{i ...}, like @ref{x-ra-ref,@code{ra-ref}}; else return a @var{k}-view of @var{a}, like @ref{x-ra-slice,@code{ra-slice}}.
  1502. It is an error if the number of @var{i ...} exceeds the rank of @var{a}.
  1503. @example
  1504. @verbatim
  1505. (define a (ra-copy (ra-i 3 2)))
  1506. (ra-cell a 0)
  1507. (ra-slice a 0) ; same thing
  1508. @end verbatim
  1509. @result{} @code{#%1(0 1 2)}
  1510. @verbatim
  1511. (ra-slice a 0 1)
  1512. @end verbatim
  1513. @result{} @code{#%0(4)}
  1514. @verbatim
  1515. (ra-cell a 0 1)
  1516. (ra-ref a 0 1) ; same thing
  1517. @end verbatim
  1518. @result{} @code{4}
  1519. @end example
  1520. See also: @ref{x-ra-slice,@code{ra-slice}}, @ref{x-ra-ref,@code{ra-ref}}, @ref{x-ra-from,@code{ra-from}}, @ref{Slicing}.
  1521. @end deffn @c ra-cell
  1522. @cindex intersection
  1523. @cindex @code{ra-clip}
  1524. @anchor{x-ra-clip}
  1525. @deffn @w{Function} ra-clip a b @result{} c
  1526. Slice @var{a} to the intersection of the bounds of @var{a} and @var{b}. If @var{a} and @var{b} have different ranks, only the common prefix of @var{a} is sliced.
  1527. @example
  1528. @verbatim
  1529. (define f (make-ra " " '(-4 4) '(-5 3)))
  1530. (define a (make-ra " A " '(-3 0) '(-4 1)))
  1531. (define b (make-ra " B " '(-1 3) '(-1 2)))
  1532. (ra-fill! (ra-clip a b) " x ")
  1533. (ra-copy! (ra-clip f b) (ra-clip b f))
  1534. (ra-copy! (ra-clip f a) (ra-clip a f))
  1535. (ra-format f)
  1536. @end verbatim
  1537. @result{}
  1538. @verbatim
  1539. #%2@-4:9@-5:9───┬───┬───┬───┬───┬───┐
  1540. │ │ │ │ │ │ │ │ │ │
  1541. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1542. │ │ A │ A │ A │ A │ A │ A │ │ │
  1543. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1544. │ │ A │ A │ A │ A │ A │ A │ │ │
  1545. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1546. │ │ A │ A │ A │ x │ x │ x │ B │ │
  1547. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1548. │ │ A │ A │ A │ x │ x │ x │ B │ │
  1549. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1550. │ │ │ │ │ B │ B │ B │ B │ │
  1551. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1552. │ │ │ │ │ B │ B │ B │ B │ │
  1553. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1554. │ │ │ │ │ B │ B │ B │ B │ │
  1555. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1556. │ │ │ │ │ │ │ │ │ │
  1557. └───┴───┴───┴───┴───┴───┴───┴───┴───┘
  1558. @end verbatim
  1559. @verbatim
  1560. (ra-fill! (ra-clip f (ra-clip a b)) " o ")
  1561. (ra-format f)
  1562. @end verbatim
  1563. @result{}
  1564. @verbatim
  1565. #%2@-4:9@-5:9───┬───┬───┬───┬───┬───┐
  1566. │ │ │ │ │ │ │ │ │ │
  1567. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1568. │ │ A │ A │ A │ A │ A │ A │ │ │
  1569. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1570. │ │ A │ A │ A │ A │ A │ A │ │ │
  1571. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1572. │ │ A │ A │ A │ o │ o │ o │ B │ │
  1573. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1574. │ │ A │ A │ A │ o │ o │ o │ B │ │
  1575. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1576. │ │ │ │ │ B │ B │ B │ B │ │
  1577. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1578. │ │ │ │ │ B │ B │ B │ B │ │
  1579. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1580. │ │ │ │ │ B │ B │ B │ B │ │
  1581. ├───┼───┼───┼───┼───┼───┼───┼───┼───┤
  1582. │ │ │ │ │ │ │ │ │ │
  1583. └───┴───┴───┴───┴───┴───┴───┴───┴───┘
  1584. @end verbatim
  1585. @end example
  1586. The result of @code{ra-clip} always shares the root of its first argument @var{a}.
  1587. See also: @ref{Slicing}, @ref{Compatibility with old Guile arrays}.
  1588. @end deffn @c ra-clip
  1589. @cindex @code{ra-dimensions}
  1590. @anchor{x-ra-dimensions}
  1591. @deffn @w{Function} ra-dimensions a
  1592. Return the dimensions of @var{a} as a list, like @ref{x-ra-shape,@code{ra-shape}}, but the dimensions that have lower bound zero are represented by their length alone, instead of a two-element list @code{(lo hi)}. This is a convenience for the common case when lower bounds are zero.
  1593. @example
  1594. @verbatim
  1595. (ra-dimensions (make-ra 0 '(2 3) 4))
  1596. @end verbatim
  1597. @result{} @code{((2 3) 4)}
  1598. @verbatim
  1599. (ra-shape (make-ra 0 '(2 3) 4))
  1600. @end verbatim
  1601. @result{} @code{((2 3) (0 3))}
  1602. @end example
  1603. See also: @ref{x-ra-shape,@code{ra-shape}}, @ref{x-make-ra,@code{make-ra}}.
  1604. @end deffn
  1605. @cindex @code{ra-format}
  1606. @anchor{x-ra-format}
  1607. @deffn @w{Function} ra-format ra port #:fmt #:prefix? #:compact
  1608. @deffnx @w{Function} ra-format ra #f #:fmt #:prefix? #:compact @result{} sc
  1609. Pretty print array @var{ra}.
  1610. Each element @var{x} of @var{ra} is converted to a string using @code{(fmt x)}, or @code{(format #f fmt x)}@footnote{@url{https://www.gnu.org/software/guile/manual/html_node/Formatted-Output.html,@code{(ice-9 format)}}} if @var{fmt} is a string. @var{fmt} defauts to @code{"~a"}. Elements that are arrays are formatted using @code{ra-format} recursively.
  1611. If @var{port} is @code{#f}, nothing is printed and the function returns a rank-2 character array @var{sc} with the result of the printing. Otherwise the array is printed to @var{port} and the function returns unspecified values. The default for @var{port} is @code{#t}, which works as @code{(current-output-port)}.
  1612. If @var{prefix?} is true, the array print prefix @ref{x-ra-print-prefix,@code{ra-print-prefix}} is printed over the first line of the printout if the rank of @var{ra} is 2 or greater, else it is printed on a separate line above the printout.
  1613. If @var{compact} is 0 (the default) separators are printed around every cell. If @var{compact} 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} is 2, the separators for the rank-0 cells are also omitted.
  1614. This function handles arrays of rank up to 14, or up to 16 if @var{compact} > 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 @url{https://unicode.org/charts/nameslist/n_2500.html,box-drawing characters}. This might look better or worse depending on the font.
  1615. A 0-array:
  1616. @example
  1617. @verbatim
  1618. (ra-format (make-ra 'element))
  1619. @end verbatim
  1620. @result{}
  1621. @verbatim
  1622. #%0
  1623. element
  1624. @end verbatim
  1625. @end example
  1626. A 1-array:
  1627. @example
  1628. @verbatim
  1629. (ra-format (ra-i 4))
  1630. @end verbatim
  1631. @result{}
  1632. @verbatim
  1633. #%1d:4
  1634. │0│1│2│3│
  1635. @end verbatim
  1636. @end example
  1637. Compare with the 2-array
  1638. @example
  1639. @verbatim
  1640. (ra-format (ra-i 1 4))
  1641. @end verbatim
  1642. @result{}
  1643. @verbatim
  1644. #%2d:1:4┐
  1645. │0│1│2│3│
  1646. └─┴─┴─┴─┘
  1647. @end verbatim
  1648. @end example
  1649. Another 2-array:
  1650. @example
  1651. @verbatim
  1652. (ra-format (ra-i 3 4) #:prefix? #f)
  1653. @end verbatim
  1654. @result{}
  1655. @verbatim
  1656. ┌─┬─┬──┬──┐
  1657. │0│1│ 2│ 3│
  1658. ├─┼─┼──┼──┤
  1659. │4│5│ 6│ 7│
  1660. ├─┼─┼──┼──┤
  1661. │8│9│10│11│
  1662. └─┴─┴──┴──┘
  1663. @end verbatim
  1664. @end example
  1665. A 5-array:
  1666. @example
  1667. @verbatim
  1668. (ra-format (ra-i 2 2 3 2 4) #:prefix? #f)
  1669. @end verbatim
  1670. @result{}
  1671. @verbatim
  1672. ┃═══════════╦═══════════╦═══════════┃═══════════╦═══════════╦═══════════┃
  1673. ┃ 0│ 1│ 2│ 3║ 8│ 9│10│11║16│17│18│19┃48│49│50│51║56│57│58│59║64│65│66│67┃
  1674. ┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃
  1675. ┃ 4│ 5│ 6│ 7║12│13│14│15║20│21│22│23┃52│53│54│55║60│61│62│63║68│69│70│71┃
  1676. ┃═══════════╬═══════════╬═══════════┃═══════════╬═══════════╬═══════════┃
  1677. ┃24│25│26│27║32│33│34│35║40│41│42│43┃72│73│74│75║80│81│82│83║88│89│90│91┃
  1678. ┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃──┼──┼──┼──║──┼──┼──┼──║──┼──┼──┼──┃
  1679. ┃28│29│30│31║36│37│38│39║44│45│46│47┃76│77│78│79║84│85│86│87║92│93│94│95┃
  1680. ┃═══════════╩═══════════╩═══════════┃═══════════╩═══════════╩═══════════┃
  1681. @end verbatim
  1682. @end example
  1683. The same 5-array in compact mode:
  1684. @example
  1685. @verbatim
  1686. (ra-format (ra-i 2 2 3 2 4) #:prefix? #f #:compact 1)
  1687. @end verbatim
  1688. @result{}
  1689. @verbatim
  1690. ║───────────┬───────────┬───────────║───────────┬───────────┬───────────║
  1691. ║ 0 1 2 3│ 8 9 10 11│16 17 18 19║48 49 50 51│56 57 58 59│64 65 66 67║
  1692. ║ 4 5 6 7│12 13 14 15│20 21 22 23║52 53 54 55│60 61 62 63│68 69 70 71║
  1693. ║───────────┼───────────┼───────────║───────────┼───────────┼───────────║
  1694. ║24 25 26 27│32 33 34 35│40 41 42 43║72 73 74 75│80 81 82 83│88 89 90 91║
  1695. ║28 29 30 31│36 37 38 39│44 45 46 47║76 77 78 79│84 85 86 87│92 93 94 95║
  1696. ║───────────┴───────────┴───────────║───────────┴───────────┴───────────║
  1697. @end verbatim
  1698. @end example
  1699. @cindex SRFI-163
  1700. A nested array (example from @mybibcite{SRFI-163}):
  1701. @example
  1702. @verbatim
  1703. (ra-format (call-with-input-string "#%2@1:2@1:3((#%2((1 2) (3 4)) 9 #%2((3 4) (5 6)))
  1704. (#%(42 43) #%2((8 7 6)) #%2((90 91) (100 101))))))"
  1705. read))
  1706. @end verbatim
  1707. @result{}
  1708. @verbatim
  1709. #%2@1:2@1:3─────┬─────────┐
  1710. │#%2:2:2│ 9│ #%2:2:2│
  1711. ││1│2│ │ │ │3│4│ │
  1712. │├─┼─┤ │ │ ├─┼─┤ │
  1713. ││3│4│ │ │ │5│6│ │
  1714. │└─┴─┘ │ │ └─┴─┘ │
  1715. ├───────┼───────┼─────────┤
  1716. │#%1:2 │#%2:1:3│#%2:2:2─┐│
  1717. ││42│43│││8│7│6│││ 90│ 91││
  1718. │ │└─┴─┴─┘│├───┼───┤│
  1719. │ │ ││100│101││
  1720. │ │ │└───┴───┘│
  1721. └───────┴───────┴─────────┘
  1722. @end verbatim
  1723. @end example
  1724. Looking at the return value when @var{port} is @code{#f}:
  1725. @example
  1726. @verbatim
  1727. (ra-format (ra-format (ra-i 2 3) #f #:prefix? #f) #:prefix? #f)
  1728. @end verbatim
  1729. @result{}
  1730. @verbatim
  1731. ┌─┬─┬─┬─┬─┬─┬─┐
  1732. │┌│─│┬│─│┬│─│┐│
  1733. ├─┼─┼─┼─┼─┼─┼─┤
  1734. │││0│││1│││2│││
  1735. ├─┼─┼─┼─┼─┼─┼─┤
  1736. │├│─│┼│─│┼│─│┤│
  1737. ├─┼─┼─┼─┼─┼─┼─┤
  1738. │││3│││4│││5│││
  1739. ├─┼─┼─┼─┼─┼─┼─┤
  1740. │└│─│┴│─│┴│─│┘│
  1741. └─┴─┴─┴─┴─┴─┴─┘
  1742. @end verbatim
  1743. @end example
  1744. The same array with @code{#:compact 2}:
  1745. @example
  1746. @verbatim
  1747. (ra-format (ra-format (ra-i 2 3) #f #:prefix? #f) #:prefix? #f #:compact 2)
  1748. @end verbatim
  1749. @result{}
  1750. @verbatim
  1751. ┌╌╌╌╌╌╌╌┐
  1752. ┆┌─┬─┬─┐┆
  1753. ┆│0│1│2│┆
  1754. ┆├─┼─┼─┤┆
  1755. ┆│3│4│5│┆
  1756. ┆└─┴─┴─┘┆
  1757. └╌╌╌╌╌╌╌┘
  1758. @end verbatim
  1759. @end example
  1760. Using a custom element formatter:
  1761. @example
  1762. @verbatim
  1763. (ra-format (ra-map! (make-ra #f 4 4) sqrt (ra-reshape (ra-iota 20 -10) 0 4 4))
  1764. #:fmt (λ (x) (format #f (cond ((real? x) "~4,2f")
  1765. ((complex? x) "~4,2i")
  1766. (else "~a"))
  1767. x)))
  1768. @end verbatim
  1769. @result{}
  1770. @verbatim
  1771. #%2:4:4────┬──────────┬──────────┬──────────┐
  1772. │0.00+3.16i│0.00+3.00i│0.00+2.83i│0.00+2.65i│
  1773. ├──────────┼──────────┼──────────┼──────────┤
  1774. │0.00+2.45i│0.00+2.24i│0.00+2.00i│0.00+1.73i│
  1775. ├──────────┼──────────┼──────────┼──────────┤
  1776. │0.00+1.41i│0.00+1.00i│ 0.00│ 1.00│
  1777. ├──────────┼──────────┼──────────┼──────────┤
  1778. │ 1.41│ 1.73│ 2.00│ 2.24│
  1779. └──────────┴──────────┴──────────┴──────────┘
  1780. @end verbatim
  1781. @end example
  1782. If any of the lengths of @var{ra} is 0, only the prefix is printed.
  1783. This function doesn't handle large arrays in any particular way. User beware!
  1784. See also: @ref{x-ra-print,@code{ra-print}}, @ref{x-star-ra-print-star, @code{*ra-print*}}.
  1785. @end deffn
  1786. @cindex @code{ra-i}
  1787. @anchor{x-ra-i}
  1788. @deffn @w{Function} ra-i bounds ...
  1789. Create a multidimensional index array with the given @var{bounds}. Each of the bounds may be an integer (a length) or a pair of integers (lower and upper bounds).
  1790. The root is of type @code{d}. The first upper bound that isn't @code{#f} may be @code{#t}; this creates an unbounded axis.
  1791. @example
  1792. @verbatim
  1793. (ra-i 2 3 4)
  1794. @end verbatim
  1795. @result{} #%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)))
  1796. @end example
  1797. See also: @ref{x-ra-iota,@code{ra-iota}}, @ref{x-ra-index-map!,@code{ra-index-map!}}. @footnote{Cf. @code{array-index} from @mybibcite{SRFI-164}.}
  1798. @end deffn
  1799. @cindex @code{ra-index-map!}
  1800. @anchor{x-ra-index-map!}
  1801. @deffn @w{Function} ra-index-map! a op @result{} a
  1802. Iterate over array @var{a} in unspecified order, assigning to each element the result of @code{(op i₀ ...)}, where @code{i₀ ...} are the indices of that element.
  1803. For example:
  1804. @example
  1805. @verbatim
  1806. (ra-index-map! (make-ra #t 3 4) -)
  1807. (ra-map! (make-ra #t 3 4) - (ra-iota) (ra-transpose (ra-iota) 1)) ; same thing
  1808. @end verbatim
  1809. @result{} @code{#%2:3:4((0 -1 -2 -3) (1 0 -1 -2) (2 1 0 -1))}
  1810. @end example
  1811. See also: @ref{x-ra-map!,@code{ra-map!}}, @ref{Iteration}.
  1812. @end deffn
  1813. @cindex @code{ra-iota}
  1814. @anchor{x-ra-iota}
  1815. @deffn @w{Function} ra-iota len [lo [step]]
  1816. @deffnx @w{Function} ra-iota
  1817. Create rank-1 index array. The root is of type @code{d}. @var{lo} defaults to 0 and @var{step} to 1.
  1818. @example
  1819. @verbatim
  1820. (ra-iota 4 3 -1)
  1821. @end verbatim
  1822. @result{} #%1d:4(3 2 1 0)
  1823. @end example
  1824. @code{(ra-iota)} is unbounded both ways, e.g.
  1825. @example
  1826. @verbatim
  1827. (ra-shape (ra-iota))
  1828. @end verbatim
  1829. @result{} @code{((#f #f))}
  1830. @verbatim
  1831. ((ra-iota) -100000000000)
  1832. @end verbatim
  1833. @result{} -100000000000
  1834. @end example
  1835. See also: @ref{x-ra-i,@code{ra-i}}.
  1836. @end deffn
  1837. @cindex @code{ra-cat}
  1838. @anchor{x-ra-cat}
  1839. @deffn @w{Function} ra-cat type i a ... @result{} b
  1840. Concatenate arrays @var{a} ... along axis @var{i}. The arguments are prefix-matched and rank extended before concatenation. All axes must match, other than the concatenation axis.
  1841. This function always produces a new array, of the type given. If @var{type} is @code{#f} then the type of the first @var{a} is used, unless that is @code{d}, in which case the result is of type @code{#t}. The lower bound in the concatenation axis of the result is 0; the lower bounds of the arguments in the concatenation axis are ignored.
  1842. @example
  1843. @verbatim
  1844. (ra-cat #f 1 #%1(a b) #%2((0 1) (2 3)))
  1845. @end verbatim
  1846. @result{} #%2((a 0 1) (b 2 3))
  1847. @end example
  1848. See also: @ref{x-ra-cats,@code{ra-cats}}, @ref{x-ra-tile,@code{ra-tile}}, @ref{Concatenation}.
  1849. @end deffn @c ra-cat
  1850. @cindex @code{ra-cats}
  1851. @anchor{x-ra-cats}
  1852. @deffn @w{Function} ra-cats type i a ... @result{} b
  1853. Concatenate @var{i}-items of arrays @var{a} ... . The arguments are suffix-matched and rank extended before concatenation. All axes must match, other than the concatenation axis.
  1854. This function always produces a new array, of the type given. If @var{type} is @code{#f} then the type of the first @var{a} is used, unless that is @code{d}, in which case the result is of type @code{#t}. The lower bound in the concatenation axis of the result is 0; the lower bounds of the arguments in the concatenation axis are ignored.
  1855. @example
  1856. @verbatim
  1857. (ra-cats #t 1 #%2((0 1) (2 3)) #%(a b))
  1858. @end verbatim
  1859. @result{} #%2((0 1) (2 3) (a b))
  1860. @end example
  1861. See also: @ref{x-ra-cat,@code{ra-cat}}, @ref{x-ra-tile,@code{ra-tile}}, @ref{Concatenation}.
  1862. @end deffn @c ra-cats
  1863. @cindex @code{ra-copy}
  1864. @anchor{x-ra-copy}
  1865. @deffn @w{Function} ra-copy src @result{} dst
  1866. @deffnx @w{Function} ra-copy type src @result{} dst
  1867. Create a new array of type @var{type} and copy @var{src} into it. If @var{type} is @code{#f} or isn't given, use the type of @var{src}, unless that type is @code{d}, in which case the result is of type @code{#t}.
  1868. See also @ref{x-ra-copy!,@code{ra-copy!}} @ref{x-ra-amend!,@code{ra-amend!}} @ref{x-ra-set!,@code{ra-set!}}.
  1869. @end deffn @c ra-copy
  1870. @cindex @code{ra-copy!}
  1871. @anchor{x-ra-copy!}
  1872. @deffn @w{Function} ra-copy! dst src @result{} dst
  1873. Copy @var{src} to @var{dst}. The arguments must have matching shapes and be of compatible types.
  1874. For valid arguments, this is equivalent to any one of
  1875. @verbatim
  1876. (ra-map! dst values src)
  1877. (ra-amend! dst src)
  1878. @end verbatim
  1879. See also @ref{x-ra-copy,@code{ra-copy}} @ref{x-ra-amend!,@code{ra-amend!}} @ref{x-ra-set!,@code{ra-set!}} @ref{x-ra-map!,@code{ra-map!}}.
  1880. @end deffn @c ra-copy!
  1881. @cindex @code{ra-equal?}
  1882. @anchor{x-ra-equal?}
  1883. @deffn @w{Function} ra-equal? a ... → boolean
  1884. Return @code{#t} if the arrays @var{a} ... have the same shapes and types and their
  1885. corresponding elements are all @code{equal?} to each other, or @code{#f} otherwise.
  1886. 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:
  1887. @example
  1888. @verbatim
  1889. (import (ice-9 control))
  1890. (define (ra-equal? . a) (let/ec exit (apply ra-for-each (λ a (unless (apply equal? a) (exit #f))) a) #t))
  1891. @end verbatim
  1892. @end example
  1893. See also: @ref{x-ra-for-each,@code{ra-for-each}}, @ref{x-ra-fold,@code{ra-fold}}, @ref{x-ra-every,@code{ra-every}}, @ref{x-ra-any,@code{ra-any}}.
  1894. @end deffn @c ra-equal?
  1895. @cindex @code{ra-every}
  1896. @anchor{x-ra-every}
  1897. @deffn @w{Function} ra-every pred? a ...
  1898. See also: @ref{x-ra-fold,@code{ra-fold}}, @ref{x-ra-any,@code{ra-any}}.
  1899. @end deffn @c ra-every
  1900. @cindex @code{ra-fill!}
  1901. @anchor{x-ra-fill!}
  1902. @deffn @w{Function} ra-fill! dst value @result{} dst
  1903. Assign @var{value} to each element of @var{dst}. The arguments must be of compatible types.
  1904. This is equivalent to any one of
  1905. @example
  1906. @verbatim
  1907. (ra-map! dst (const value))
  1908. (ra-copy! dst (make-ra value))
  1909. (ra-amend! dst (make-ra value))
  1910. (ra-amend! dst value) ; when value isn't an array
  1911. @end verbatim
  1912. @end example
  1913. Compare
  1914. @example
  1915. @verbatim
  1916. (ra-fill! (make-ra #f 2 2) (make-ra 'x))
  1917. @end verbatim
  1918. @result{} #%2:2:2((#%0(x) #%0(x)) (#%0(x) #%0(x)))
  1919. @verbatim
  1920. (ra-amend! (make-ra #f 2 2) 'x)
  1921. @end verbatim
  1922. @result{} #%2:2:2((x x) (x x))
  1923. @verbatim
  1924. (ra-amend! (make-ra #f 2 2) (make-ra 'x))
  1925. @end verbatim
  1926. @result{} #%2:2:2((x x) (x x))
  1927. @verbatim
  1928. (ra-amend! (make-ra #f 2 2) (make-ra (make-ra 'x)))
  1929. @end verbatim
  1930. @result{} #%2:2:2((#%0(x) #%0(x)) (#%0(x) #%0(x)))
  1931. @end example
  1932. See also: @ref{x-ra-set!,@code{ra-set!}}, @ref{x-ra-copy!,@code{ra-copy!}}, @ref{x-ra-amend!,@code{ra-amend!}}.
  1933. @end deffn @c ra-fill!
  1934. @cindex @code{ra-fold}
  1935. @anchor{x-ra-fold}
  1936. @deffn @w{Function} ra-fold op knil a ...
  1937. @c Maybe any ravel.
  1938. Returns @code{(... (op (op knil a₀ ...) a₁ ...) ...)}, where @var{a}₀ @var{a}₁ ... is the row-major ravel of @var{a} (after rank extension). The shapes of @var{a} ... must match. Example:
  1939. @example
  1940. @verbatim
  1941. (ra-fold list 99 (ra-i 2) (ra-i 2 3))
  1942. @end verbatim
  1943. @result{} @code{((((((99 0 0) 0 1) 0 2) 1 3) 1 4) 1 5)}
  1944. @end example
  1945. See also: @ref{x-ra-every,@code{ra-every}}, @ref{x-ra-any,@code{ra-any}}, @ref{Iteration}.
  1946. @end deffn @c ra-fold
  1947. @cindex @code{ra-for-each}
  1948. @anchor{x-ra-for-each}
  1949. @deffn @w{Function} ra-for-each op a ...
  1950. Apply @var{op} to each tuple of elements from arrays @var{a} ... The shapes of @var{a} must match.
  1951. See also: @ref{x-ra-slice-for-each, @code{ra-slice-for-each}}, @ref{x-ra-map!,@code{ra-map}}, @ref{Iteration}.
  1952. @end deffn @c ra-for-each
  1953. @cindex @code{ra-from}
  1954. @anchor{x-ra-from}
  1955. @deffn @w{Function} ra-from a i ... → b
  1956. Outer product slice of @var{a} by indices @var{i} ...
  1957. The shape of @var{b} is the concatenation of the shapes of @var{i}... and the
  1958. contents are obtained by looking up in each dimension of @var{a} by the indices @var{i},
  1959. that is
  1960. @example
  1961. @verbatim
  1962. b(j₀₀ j₀₁ ... j₁₀ j₁₁ ...) = a(i₀(j₀₀ j₀₁ ...) i₁(j₁₀ j₁₁ ...) ...)
  1963. @end verbatim
  1964. @end example
  1965. where @var{i} : @var{i₀} @var{i₁} ... The special value @code{#t} is understood as the full range of @var{a} on that axis.
  1966. Additionally, if each of the @var{i} ... is one of
  1967. @itemize
  1968. @item @code{#t}
  1969. @item an array of type @code{d}
  1970. @item an array of rank 0
  1971. @item an integer
  1972. @end itemize
  1973. then the result @var{b} shares the root of @var{a}. In all other cases a new root is allocated for the result. For example
  1974. @example
  1975. @verbatim
  1976. (define a (list->ra 2 '((1 2 3) (a b c))))
  1977. (define b (ra-from a #t (ra-iota 3 2 -1))) ; same as (ra-reverse a 1)
  1978. b
  1979. @end verbatim
  1980. @result {} @code{#%2:2:3((3 2 1) (c b a))}
  1981. @verbatim
  1982. (eq? (ra-root a) (ra-root b))
  1983. @end verbatim
  1984. @result {} @code{#t}
  1985. @verbatim
  1986. (define c (ra-from a #t (list->ra 1 '(2 1 0))))
  1987. b
  1988. @end verbatim
  1989. @result {} @code{#%2:2:3((3 2 1) (c b a))}
  1990. @verbatim
  1991. (eq? (ra-root a) (ra-root c))
  1992. @end verbatim
  1993. @result {} @code{#f}
  1994. @end example
  1995. Unbounded indices aren't treated especially, so they are only valid if the relevant axis of @var{ra} is itself unbounded.
  1996. @example
  1997. @verbatim
  1998. (ra-i #t 4)
  1999. @end verbatim
  2000. @result {}
  2001. @verbatim
  2002. #%2d:f:4──┐
  2003. │0│1│ 2│ 3│
  2004. ├─┼─┼──┼──┤
  2005. │4│5│ 6│ 7│
  2006. ├─┼─┼──┼──┤
  2007. │8│9│10│11│
  2008. ...........
  2009. @end verbatim
  2010. @verbatim
  2011. (ra-from (ra-i #t 4) (ra-iota #f 0 2))
  2012. @end verbatim
  2013. @result {}
  2014. @verbatim
  2015. #%2d:f:4─┬──┐
  2016. │ 0│ 1│ 2│ 3│
  2017. ├──┼──┼──┼──┤
  2018. │ 8│ 9│10│11│
  2019. ├──┼──┼──┼──┤
  2020. │16│17│18│19│
  2021. .............
  2022. @end verbatim
  2023. @end example
  2024. The type of @var{b} is the same as that of @var{a}, with the only exception that if the type of @var{a} is @code{d} and the root of @var{b} cannot be shared with the root of @var{a}, then the type of @var{b} is @code{#t}.
  2025. @code{ra-from} always returns an array, even if the result has rank 0. This is in contrast to array application (see @ref{Slicing}).
  2026. @example
  2027. @verbatim
  2028. (define A (list->ra 2 '((1 a) (2 b) (3 c))))
  2029. (ra-from A 2 1)
  2030. @end verbatim
  2031. @result{} #%0(b)
  2032. @verbatim
  2033. (A 2 1)
  2034. @end verbatim
  2035. @result{} b
  2036. @end example
  2037. See also: @ref{x-ra-cell,@code{ra-cell}}, @ref{x-ra-ref,@code{ra-ref}}, @ref{x-ra-slice,@code{ra-slice}}, @ref{x-ra-amend!,@code{ra-amend!}}, @ref{Slicing}.@footnote{Cf. @code{array-index-ref} from @mybibcite{SRFI-164}.}
  2038. @end deffn @c ra-from
  2039. @cindex @code{ra-from-copy}
  2040. @anchor{x-ra-from-copy}
  2041. @deffn @w{Function} ra-from-copy a i ... @result{} b
  2042. Like @code{ra-from}, but always return a newly allocated array. This is equivalent to @code{(ra-copy (ra-from a i ...))}, but it doesn't incur a second copy in case @code{ra-from} already allocates a new array.
  2043. See also: @ref{x-ra-from,@code{ra-from}}.
  2044. @end deffn @c ra-from-copy
  2045. @cindex @code{ra-map}
  2046. @anchor{x-ra-map}
  2047. @deffn @w{Function} ra-map type op a0 a ... @result{} dst
  2048. Same as @ref{x-ra-map!,@code{ra-map!}}, but create the result array from the arguments. Unlike @code{ra-map!}, this function requires at least one source argument.
  2049. The type of the result @var{dst} is @var{type} unless that is @code{#f}, in which case the type of @var{a0} is used, unless that is @code{'d}, in which case the result is of type @code{#t}. For the shape of @var{dst} see @ref{Automatic result arrays}.
  2050. @example
  2051. @verbatim
  2052. (ra-format (ra-map 'f64 + (ra-iota 3 1) (ra-i 3 4)))
  2053. @end verbatim
  2054. @result{}
  2055. @verbatim
  2056. #%2f64:3:4┬────┬────┐
  2057. │ 1.0│ 2.0│ 3.0│ 4.0│
  2058. ├────┼────┼────┼────┤
  2059. │ 6.0│ 7.0│ 8.0│ 9.0│
  2060. ├────┼────┼────┼────┤
  2061. │11.0│12.0│13.0│14.0│
  2062. └────┴────┴────┴────┘
  2063. @end verbatim
  2064. @end example
  2065. See also: @ref{x-ra-map!,@code{ra-map!}}, @ref{x-ra-copy,@code{ra-copy}}.
  2066. @end deffn @c ra-map
  2067. @cindex @code{ra-map!}
  2068. @anchor{x-ra-map!}
  2069. @deffn @w{Function} ra-map! dst op a ... @result{} dst
  2070. Iterate over arrays @var{dst} @var{a} ... applying @var{op} to the respective elements in @var{a}, and storing the result in the respective element of @var{dst}. The arguments must have matching shapes and the type of @var{dst} must be compatible with the results of @var{op}.
  2071. This is equivalent to
  2072. @verbatim
  2073. (apply ra-slice-for-each
  2074. (rank dst)
  2075. (λ (dst . a)
  2076. (ra-set! dst (apply op (map ra-ref a))))
  2077. dst a)
  2078. @end verbatim
  2079. See also: @ref{x-ra-map,@code{ra-map}}, @ref{x-ra-for-each,@code{ra-for-each}}, @ref{x-ra-slice-for-each,@code{ra-slice-for-each}}, @ref{Iteration}.
  2080. @end deffn @c ra-map!
  2081. @cindex packed array
  2082. @cindex @code{ra-order-c?}
  2083. @anchor{x-ra-order-c?}
  2084. @deffn @w{Function} ra-order-c? a [n [org]]
  2085. Check whether axes [@var{org} ... @var{org}+@var{n}) of @var{a} are in row-major order. @var{org} defaults to 0.
  2086. If @var{n} 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’).
  2087. @code{(ra-order-c? a n org)} implies @code{(eq? (ra-root a) (ra-root (@ref{x-ra-ravel, @code{ra-ravel}} a n org)))}. Note that the stronger condition @code{(ra-order-c? a)} is not necessary for @code{(eq? (ra-root a) (ra-root (ra-ravel a)))} to hold.
  2088. @end deffn @c ra-order-c?
  2089. @cindex @code{ra-print}
  2090. @anchor{x-ra-print}
  2091. @deffn @w{Function} ra-print ra [port]
  2092. Print an array to @var{port}. @var{port} defaults to @code{(current-output-port)}.
  2093. This is the default array printer. The result is meant to be back-readable, although some special arrays are not supported yet.
  2094. See also: @ref{x-ra-format,@code{ra-format}}, @ref{x-star-ra-print-star,@code{*ra-print*}}, @ref{x-star-ra-parenthesized-rank-zero-star, @code{*ra-parenthesized-rank-zero*}}.
  2095. @end deffn
  2096. @cindex @code{print prefix}
  2097. @cindex @code{ra-print-prefix}
  2098. @anchor{x-ra-print-prefix}
  2099. @deffn @w{Function} ra-print-prefix ra port #:dims?
  2100. Return the print prefix for array @var{ra}. This is a string that details the type, rank, and (optionally) the dimensions of @var{ra}, and is part of the default read syntax for arrays. This is the same syntax as that of the @url{https://www.gnu.org/software/guile/manual/html_node/Array-Syntax.html,the built in Guile arrays}, except that @var{dims?} defaults to true and @code{#%} is used instead of @code{#}.
  2101. This function is provided by the module @code{(newra print)}.
  2102. @example
  2103. @verbatim
  2104. (call-with-output-string (cut ra-print-prefix (make-ra 4 '(3 4) '(2 3)) <>))
  2105. @end verbatim
  2106. @result{} @code{"#%2@@3:2@@2:2"}
  2107. @end example
  2108. @example
  2109. @verbatim
  2110. (call-with-output-string (cut ra-print-prefix (make-ra 4 '(3 4) '(2 3)) <> #:dims? #t))
  2111. @end verbatim
  2112. @result{} @code{"#%2@@3@@2"}
  2113. @end example
  2114. See also: @ref{x-ra-format,@code{ra-format}}, @ref{Writing and reading}.
  2115. @end deffn
  2116. @cindex @code{ra-ravel}
  2117. @anchor{x-ra-ravel}
  2118. @deffn @w{Function} ra-ravel a [n [org]] @result{} b
  2119. Ravel axes [@var{org} ... @var{org}+@var{n}) of array @var{a} in row-major order. @var{n} defaults to the rank of @var{a} and @var{org} defaults to 0.
  2120. For example:
  2121. @example
  2122. @verbatim
  2123. (ra-ravel (ra-i 2 3))
  2124. @end verbatim
  2125. @result{} #%1d:6(0 1 2 3 4 5)
  2126. @end example
  2127. Consider this 3-array:
  2128. @example
  2129. @verbatim
  2130. (ra-format (ra-i 2 3 4))
  2131. @end verbatim
  2132. @result{}
  2133. @verbatim
  2134. #%3d:2:3:4║──┬──┬──┬──║
  2135. ║0│1│ 2│ 3║12│13│14│15║
  2136. ║─┼─┼──┼──║──┼──┼──┼──║
  2137. ║4│5│ 6│ 7║16│17│18│19║
  2138. ║─┼─┼──┼──║──┼──┼──┼──║
  2139. ║8│9│10│11║20│21│22│23║
  2140. ║─┴─┴──┴──║──┴──┴──┴──║
  2141. @end verbatim
  2142. @end example
  2143. Ravel axes 0..1:
  2144. @example
  2145. @verbatim
  2146. (ra-format (ra-ravel (ra-i 2 3 4) 2)) ; or (ra-ravel ... 2 0)
  2147. @end verbatim
  2148. @result{}
  2149. @verbatim
  2150. #%2d:6:4─┬──┐
  2151. │ 0│ 1│ 2│ 3│
  2152. ├──┼──┼──┼──┤
  2153. │ 4│ 5│ 6│ 7│
  2154. ├──┼──┼──┼──┤
  2155. │ 8│ 9│10│11│
  2156. ├──┼──┼──┼──┤
  2157. │12│13│14│15│
  2158. ├──┼──┼──┼──┤
  2159. │16│17│18│19│
  2160. ├──┼──┼──┼──┤
  2161. │20│21│22│23│
  2162. └──┴──┴──┴──┘
  2163. @end verbatim
  2164. @end example
  2165. Ravel axes 1..2:
  2166. @example
  2167. @verbatim
  2168. (ra-format (ra-ravel (ra-i 2 3 4) 2 1))
  2169. @end verbatim
  2170. @result{}
  2171. @verbatim
  2172. @end verbatim
  2173. #%2d:2:12┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
  2174. │ 0│ 1│ 2│ 3│ 4│ 5│ 6│ 7│ 8│ 9│10│11│
  2175. ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
  2176. │12│13│14│15│16│17│18│19│20│21│22│23│
  2177. └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
  2178. @end example
  2179. To ravel other combinations of axes, use @ref{Transposition}.
  2180. @cindex packed array
  2181. 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))}. @footnote{@ref{x-ra-order-c?, @code{ra-order-c?}} is always true for the result of @code{ra-copy}, so the ravel operation in @code{(ra-ravel (ra-copy ra))} is free, but it might not be in @code{(ra-copy (ra-ravel ra))}. So in principle, it is preferable to copy first.}.
  2182. See also: @ref{x-ra-reshape,@code{ra-reshape}}, @ref{x-ra-tile,@code{ra-tile}}, @ref{Reshaping}.
  2183. @end deffn @c ra-ravel
  2184. @cindex @code{ra-ref}
  2185. @anchor{x-ra-ref}
  2186. @deffn @w{Function} ra-ref a i ...
  2187. Look up element of array @var{a}. The indices @var{i ...} must be integers within the bounds of @var{a}. It is an error if the number of @var{i ...} doesn't match the rank of @var{a}.
  2188. See also: @ref{x-ra-cell,@code{ra-cell}}, @ref{x-ra-slice,@code{ra-slice}}, @ref{x-ra-from,@code{ra-from}}, @ref{x-ra-set!,@code{ra-set!}}, @ref{Slicing}.
  2189. @end deffn @c ra-ref
  2190. @cindex @code{ra-reshape}
  2191. @anchor{x-ra-reshape}
  2192. @deffn @w{Function} ra-reshape a k bounds ... @result{} b
  2193. Reshape axis @var{k} of array @var{a} to @var{bounds}.
  2194. Each of @var{bounds} may be an integer (a length) or a pair of integers (lower and upper bounds), or @code{#f}. No more than one of @var{bounds} may be @code{#f}.
  2195. @example
  2196. @verbatim
  2197. (define a (ra-i 4 3))
  2198. (ra-format a)
  2199. @end verbatim
  2200. @result{}
  2201. @verbatim
  2202. #%2d:4:3┐
  2203. │0│ 1│ 2│
  2204. ├─┼──┼──┤
  2205. │3│ 4│ 5│
  2206. ├─┼──┼──┤
  2207. │6│ 7│ 8│
  2208. ├─┼──┼──┤
  2209. │9│10│11│
  2210. └─┴──┴──┘
  2211. @end verbatim
  2212. @verbatim
  2213. (ra-format (ra-reshape a 0 2 2))
  2214. @end verbatim
  2215. @result{}
  2216. @verbatim
  2217. #%3d:2:2:3─┬──║
  2218. ║0│1│2║6│ 7│ 8║
  2219. ║─┼─┼─║─┼──┼──║
  2220. ║3│4│5║9│10│11║
  2221. ║─┴─┴─║─┴──┴──║
  2222. @end verbatim
  2223. @end example
  2224. If one of @var{bounds} is @code{#f}, the missing length is computed as @code{(/ (ra-len ra k) n)} where @var{n} is the total size of the @var{bounds} that are not @code{#f}. It is an error if this isn't a non-negative integer.
  2225. @example
  2226. @verbatim
  2227. (ra-reshape (ra-iota 12) 0 2 2 #f) ; #f will be 3 = 12/(2*2)
  2228. @end verbatim
  2229. @result{} @code{#%3d:2:2:3(((0 1 2) (3 4 5)) ((6 7 8) (9 10 11)))}
  2230. @end example
  2231. @example
  2232. @verbatim
  2233. (ra-reshape (ra-iota 7) 0 3 #f)
  2234. @end verbatim
  2235. @result{} @code{error ; bad-placeholder 7/3}
  2236. @end example
  2237. It is an error if the product of the lengths in @var{bounds} exceeds the length of axis @var{k} of @var{a}. For example
  2238. @example
  2239. @verbatim
  2240. (ra-reshape (ra-i 8 2) 0 2 3)
  2241. @end verbatim
  2242. @result{} @code{#%3d:2:3:2(((0 1) (2 3) (4 5)) ((6 7) (8 9) (10 11))} ; ok, 8 can be reshaped into 2·3
  2243. @verbatim
  2244. (ra-reshape (ra-i 8 2) 0 4 3)
  2245. @end verbatim
  2246. @result{} error ; 8 cannot be reshaped into 4·3
  2247. @end example
  2248. @cindex bounds
  2249. @code{ra-reshape} may be used to change either of the bounds of an axis, not only its length. For example
  2250. @example
  2251. @verbatim
  2252. (ra-format (ra-i 2 3))
  2253. @end verbatim
  2254. @result {}
  2255. @verbatim
  2256. #%2d:2:3
  2257. │0│1│2│
  2258. ├─┼─┼─┤
  2259. │3│4│5│
  2260. └─┴─┴─┘
  2261. @end verbatim
  2262. @end example
  2263. @example
  2264. @verbatim
  2265. (ra-format (ra-reshape (ra-i 2 3) 0 '(1 2)))
  2266. @end verbatim
  2267. @result {}
  2268. @verbatim
  2269. #%2d@1:2:3
  2270. │0│1│2│
  2271. ├─┼─┼─┤
  2272. │3│4│5│
  2273. └─┴─┴─┘
  2274. @end verbatim
  2275. @end example
  2276. The result of @code{ra-reshape} always shares the root of @var{a}.
  2277. See also: @ref{x-ra-ravel,@code{ra-ravel}}, @ref{x-ra-tile,@code{ra-tile}}, @ref{Reshaping}.
  2278. @end deffn @c ra-reshape
  2279. @cindex @code{⌽}, reverse
  2280. @cindex @code{ra-reverse}
  2281. @anchor{x-ra-reverse}
  2282. @deffn @w{Function} ra-reverse a axes ... @result{} b
  2283. Reverse the given @var{axes} of @var{a}, that is, the order of the elements along those axes. The bounds do not change.
  2284. @example
  2285. @verbatim
  2286. (ra-reverse (ra-i 2 3) 0 1)
  2287. @end verbatim
  2288. @result{} #%1d:2:3((5 4 3) (2 1 0))
  2289. @end example
  2290. The reversed array shares the root of @var{a}.
  2291. See also: @ref{x-ra-rotate,@code{ra-rotate}}, @ref{x-ra-rotate,@code{ra-rotate!}}.
  2292. @end deffn
  2293. @cindex @code{⌽}, rotate
  2294. @cindex @code{⊖}, rowel
  2295. @cindex @code{ra-rotate}
  2296. @anchor{x-ra-rotate}
  2297. @deffn @w{Function} ra-rotate n a @result{} b
  2298. Rotate the first axis of @var{a} toward the lower indices (‘to the left’) @var{n} times. @var{n} may be any integer. The result has the type of @var{a}, unless that type is @code{d}, in which case the result is of type @code{#t}.
  2299. This function always returns a new array.
  2300. Example:
  2301. @example
  2302. @verbatim
  2303. (ra-rotate 1 (ra-i 3 2))
  2304. @end verbatim
  2305. @result{} #%1:3:2((2 3) (4 5) (0 1))
  2306. @end example
  2307. See also: @ref{x-ra-rotate!,@code{ra-rotate!}}, @ref{x-ra-reverse,@code{ra-reverse}}.
  2308. @end deffn @c ra-rotate
  2309. @cindex rotate!
  2310. @cindex @code{ra-rotate!}
  2311. @anchor{x-ra-rotate!}
  2312. @deffn @w{Function} ra-rotate! n a @result{} a
  2313. Rotate in place the first axis of @var{a} to the left @var{n} times. @var{n} may be any integer. @var{a} must be writable. This function returns @var{a}.
  2314. Example:
  2315. @example
  2316. @verbatim
  2317. (define a (ra-copy #t (ra-i 3 2)))
  2318. (ra-rotate! 1 a)
  2319. a
  2320. @end verbatim
  2321. @result{} #%1:3:2((2 3) (4 5) (0 1))
  2322. @end example
  2323. See also: @ref{x-ra-rotate,@code{ra-rotate}}, @ref{x-ra-reverse,@code{ra-reverse}}.
  2324. @end deffn @c ra-rotate!
  2325. @cindex @code{ra-slice-for-each}
  2326. @anchor{x-ra-slice-for-each}
  2327. @deffn @w{Function} ra-slice-for-each k op a ...
  2328. Iterate over the @var{k}-frames of arrays @var{a} ..., applying @var{op} to the respective slices. The arguments @var{a} ... must have matching @var{k}-frames.
  2329. Note that it isn't necessary for arguments @var{a} to have rank ≥ @var{k}. Arguments with rank < @var{k} are rank-extended and the corresponding arguments are 0-cells. For example:
  2330. @example
  2331. @verbatim
  2332. (ra-slice-for-each 1
  2333. (λ (a b) (display (list (a) (b))))
  2334. (make-ra-root #(a b))
  2335. (ra-i 2 3))
  2336. @end verbatim
  2337. @result{} @code{(a #%1d:3(0 1 2))(b #%1d:3(3 4 5))}
  2338. @end example
  2339. @example
  2340. @verbatim
  2341. (ra-slice-for-each 2
  2342. (λ (a b) (display (list (a) (b))))
  2343. (make-ra-root #(a b))
  2344. (ra-i 2 3))
  2345. @end verbatim
  2346. @result{} @code{(a 0)(a 1)(a 2)(b 3)(b 4)(b 5)}
  2347. @end example
  2348. See also: @ref{x-ra-map!,@code{ra-map!}}, @ref{x-ra-for-each,@code{ra-for-each}}, @ref{Iteration}.
  2349. @end deffn @c ra-slice-for-each
  2350. @cindex @code{ra-set!}
  2351. @anchor{x-ra-set!}
  2352. @deffn @w{Function} ra-set! a value i ...
  2353. Assign @var{value} to array @var{a} at indices @var{i ...} It is an error if the number of @var{i ...} doesn't match the rank of @var{a}.
  2354. This function returns the modified array @var{a}.
  2355. See also: @ref{x-ra-amend!,@code{ra-amend!}}, @ref{x-ra-ref,@code{ra-ref}}, @ref{Slicing}.
  2356. @end deffn @c ra-set!
  2357. @cindex @code{ra-slice}
  2358. @anchor{x-ra-slice}
  2359. @deffn @w{Function} ra-slice a i ...
  2360. Look up cell of array @var{a}. The indices @var{i ...} must be integers within the bounds of @var{a}.
  2361. This function returns a view of @var{a} with rank @var{k} equal to the rank of @var{a} minus the number of @var{i ...}, even if that is 0. It is an error if the number of @var{i ...} exceeds the rank of @var{a}.
  2362. See also: @ref{x-ra-cell,@code{ra-cell}}, @ref{x-ra-ref,@code{ra-ref}}, @ref{x-ra-from,@code{ra-from}}, @ref{Slicing}.
  2363. @end deffn @c ra-slice
  2364. @cindex @code{ra-shape}
  2365. @anchor{x-ra-shape}
  2366. @deffn @w{Function} ra-shape a @result{} s
  2367. Return the shape (a list of two-element lists, each containing the lower and upper bound of each axis) of array @var{a}.
  2368. @example
  2369. @verbatim
  2370. (ra-shape (make-ra 0 '(2 3) 4))
  2371. @end verbatim
  2372. @result{} @code{((2 3) (0 3))}
  2373. @end example
  2374. See also: @ref{x-ra-dimensions,@code{ra-dimensions}}, @ref{x-make-ra,@code{make-ra}}.
  2375. @end deffn @c ra-shape
  2376. @cindex @code{ra-singletonize}
  2377. @anchor{x-ra-singletonize}
  2378. @deffn @w{Function} ra-singletonize a
  2379. Return an array with the same root and dimensions as @var{a}, except that dead axes (axes with step 0 and undefined length) have their length set to 1.
  2380. @example
  2381. @verbatim
  2382. (ra-dimensions (ra-transpose (ra-i 2 3) 1))
  2383. @end verbatim
  2384. @result{} (#f 2 3)
  2385. @verbatim
  2386. (ra-dimensions (ra-singletonize (ra-transpose (ra-i 2 3) 1)))
  2387. @end verbatim
  2388. @result{} (1 2 3)
  2389. @verbatim
  2390. (ra-dimensions (ra-singletonize (ra-tile (ra-i 2 3) 0 4)))
  2391. @end verbatim
  2392. @result{} (4 2 3) ; no change
  2393. @end example
  2394. @end deffn @c ra-singletonize
  2395. @cindex @code{ra-swap!}
  2396. @anchor{x-ra-swap!}
  2397. @deffn @w{Function} ra-swap! a b @result{} a
  2398. Swap the contents of @var{a} and @var{b}. The swap is executed in unspecified order, so the effect on @var{a} and @var{b} is undefined if @var{a} and @var{b} share storage.
  2399. @example
  2400. @verbatim
  2401. (ra-swap! (make-ra 2 3) (make-typed-ra 'f64 -1 3))
  2402. @end verbatim
  2403. @result{}
  2404. @verbatim
  2405. #%1:3(-1.0 -1.0 -1.0)
  2406. @end verbatim
  2407. @end example
  2408. See also @ref{x-ra-swap-in-order!,@code{ra-swap-in-order!}} @ref{x-ra-copy!,@code{ra-copy!}}.
  2409. @end deffn @c ra-swap!
  2410. @cindex @code{ra-swap-in-order!}
  2411. @anchor{x-ra-swap-in-order!}
  2412. @deffn @w{Function} ra-swap-in-order! a b @result{} a
  2413. Swap the contents of @var{a} and @var{b}. The swap is executed in row-major order.
  2414. @end deffn @c ra-swap-in-order!
  2415. @cindex @code{ra-tile}
  2416. @anchor{x-ra-tile}
  2417. @deffn @w{Function} ra-tile a k bounds ... @result{} b
  2418. Replicate array @var{a} by inserting axes of @var{bounds ...} before axis @var{k}. If @var{t} is the shape of @var{a}, the shape of the result will be
  2419. @example
  2420. @verbatim
  2421. [t₀ ... tₖ₋₁ s₀ ... tₖ ...]
  2422. @end verbatim
  2423. @end example
  2424. Each of the bounds may be an integer (a length) or a pair of integers (lower and upper bounds).
  2425. @example
  2426. @verbatim
  2427. (define a (ra-i 3 4))
  2428. (ra-format a)
  2429. @end verbatim
  2430. @result{}
  2431. @verbatim
  2432. #%2d:3:4──┐
  2433. │0│1│ 2│ 3│
  2434. ├─┼─┼──┼──┤
  2435. │4│5│ 6│ 7│
  2436. ├─┼─┼──┼──┤
  2437. │8│9│10│11│
  2438. └─┴─┴──┴──┘
  2439. @end verbatim
  2440. @end example
  2441. @example
  2442. @verbatim
  2443. (ra-format (ra-tile a 0 2))
  2444. @end verbatim
  2445. @result{}
  2446. @verbatim
  2447. #%3d:2:3:4║─┬─┬──┬──║
  2448. ║0│1│ 2│ 3║0│1│ 2│ 3║
  2449. ║─┼─┼──┼──║─┼─┼──┼──║
  2450. ║4│5│ 6│ 7║4│5│ 6│ 7║
  2451. ║─┼─┼──┼──║─┼─┼──┼──║
  2452. ║8│9│10│11║8│9│10│11║
  2453. ║─┴─┴──┴──║─┴─┴──┴──║
  2454. @end verbatim
  2455. @end example
  2456. @example
  2457. @verbatim
  2458. (ra-format (ra-tile a 1 2))
  2459. @end verbatim
  2460. @result{}
  2461. @verbatim
  2462. #%3d:3:2:4┬─┬─┬─║─┬─┬──┬──║
  2463. ║0│1│2│3║4│5│6│7║8│9│10│11║
  2464. ║─┼─┼─┼─║─┼─┼─┼─║─┼─┼──┼──║
  2465. ║0│1│2│3║4│5│6│7║8│9│10│11║
  2466. ║─┴─┴─┴─║─┴─┴─┴─║─┴─┴──┴──║
  2467. @end verbatim
  2468. @end example
  2469. @example
  2470. @verbatim
  2471. (ra-format (ra-tile a 2 2))
  2472. @end verbatim
  2473. @result{}
  2474. @verbatim
  2475. #%3d:3:4:2─┬──║
  2476. ║0│0║4│4║ 8│ 8║
  2477. ║─┼─║─┼─║──┼──║
  2478. ║1│1║5│5║ 9│ 9║
  2479. ║─┼─║─┼─║──┼──║
  2480. ║2│2║6│6║10│10║
  2481. ║─┼─║─┼─║──┼──║
  2482. ║3│3║7│7║11│11║
  2483. ║─┴─║─┴─║──┴──║
  2484. @end verbatim
  2485. @end example
  2486. Either @var{len} or @var{hi} being @code{#f} creates @ref{x-dead-axes,dead axes}.
  2487. @example
  2488. @verbatim
  2489. (define a (ra-tile (ra-i 2 2) 0 #f #f))
  2490. (define b (ra-transpose (ra-i 2 2) 2)) ; same thing
  2491. @end verbatim
  2492. @result{} @code{#%4d:d:d:2:2((((0 1) (2 3))))}
  2493. @end example
  2494. The tiled array shares the root of @var{a}.
  2495. See also: @ref{x-ra-ravel,@code{ra-ravel}}, @ref{x-ra-reshape,@code{ra-reshape}}, @ref{Reshaping}.
  2496. @end deffn
  2497. @cindex @code{ra-transpose}
  2498. @anchor{x-ra-transpose}
  2499. @deffn @w{Function} ra-transpose a axes ... @result{} b
  2500. Transpose axes 0, 1, ... of @var{a} to matching destination @var{axes}.
  2501. @example
  2502. @verbatim
  2503. (ra-transpose (ra-i 2 3) 1 0)
  2504. @end verbatim
  2505. @result{} #%1d:3:2((0 3) (1 4) (2 5))
  2506. @end example
  2507. The transposed array shares the root of @var{a}.
  2508. See also: @ref{x-ra-untranspose,@code{ra-untranspose}}, @ref{Transposition}.
  2509. @end deffn
  2510. @cindex @code{ra-untranspose}
  2511. @anchor{x-ra-untranspose}
  2512. @deffn @w{Function} ra-untranspose a axes ... @result{} b
  2513. Transpose @var{axes} of @var{a} to matching destination axes 0, 1, ...
  2514. @example
  2515. @verbatim
  2516. (ra-untranspose (ra-transpose (ra-i 2 3 4) 2 1 0) 2 1 0)
  2517. @end verbatim
  2518. @result{} @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)))}
  2519. @end example
  2520. but
  2521. @example
  2522. @verbatim
  2523. (ra-transpose (ra-transpose (ra-i 2 3 4) 2 1 0) 2 1 0)
  2524. @end verbatim
  2525. @result{} @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)))}
  2526. @end example
  2527. The transposed array shares the root of @var{a}.
  2528. See also: @ref{x-ra-transpose,@code{ra-transpose}}, @ref{Transposition}.
  2529. @end deffn @c ra-untranspose
  2530. @c ------------------------------------------------
  2531. @node Cheatsheet
  2532. @chapter Cheatsheet
  2533. @c ------------------------------------------------
  2534. @c https://cheatsheets.quantecon.org/
  2535. @c https://hyperpolyglot.org/fortran
  2536. 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...
  2537. The APL examples assume @code{⎕io←0}. The @code{newra} examples use @code{(define ⍉ ra-transpose)}, which @code{newra} itself doesn't provide.
  2538. @multitable @columnfractions .2 .2 .2 .2 .2
  2539. @item
  2540. @tab
  2541. @code{newra}
  2542. @tab
  2543. APL
  2544. @tab
  2545. @cindex NumPy
  2546. NumPy
  2547. @tab
  2548. Octave
  2549. @item
  2550. 1×n array
  2551. @tab
  2552. @verbatim
  2553. ∗ #%2((1 2 3))
  2554. ────
  2555. (list->ra 2 '((1 2 3)))
  2556. ────
  2557. (ra-reshape (list->ra 1 '(1 2 3)) 0 1 3)
  2558. @end verbatim
  2559. @tab
  2560. @verbatim
  2561. 1 3 ⍴ 1 2 3
  2562. @end verbatim
  2563. @tab
  2564. @verbatim
  2565. np.array([1, 2, 3]).reshape(1, 3)
  2566. @end verbatim
  2567. @tab
  2568. @verbatim
  2569. [1 2 3]
  2570. @end verbatim
  2571. @item
  2572. n×1 array
  2573. @tab
  2574. @verbatim
  2575. ∗ #%2((1) (2) (3))
  2576. ────
  2577. (list->ra 2 '((1) (2) (3)))
  2578. ────
  2579. (ra-reshape (list->ra 1 '(1 2 3)) 0 3 1)
  2580. @end verbatim
  2581. @tab
  2582. @verbatim
  2583. 3 1 ⍴ 1 2 3
  2584. @end verbatim
  2585. @tab
  2586. @verbatim
  2587. np.array([1, 2, 3]).reshape(3, 1)
  2588. @end verbatim
  2589. @tab
  2590. @verbatim
  2591. [1 2 3].'
  2592. @end verbatim
  2593. @item
  2594. rank 1 array
  2595. @tab
  2596. @verbatim
  2597. ∗ #%(1 2 3)
  2598. ────
  2599. (list->ra 1 '(1 2 3))
  2600. @end verbatim
  2601. @tab
  2602. @verbatim
  2603. 1 2 3
  2604. @end verbatim
  2605. @tab
  2606. @verbatim
  2607. np.array([1, 2, 3])
  2608. @end verbatim
  2609. @tab
  2610. n/a
  2611. @item
  2612. integers from @var{a} to @var{b} with step size @var{k}
  2613. @tab
  2614. @verbatim
  2615. (ra-iota (euclidean/ (- b a (- k)) k) a k)
  2616. @end verbatim
  2617. @tab
  2618. @verbatim
  2619. a + k × ι ⌊ (b-a) ÷ k
  2620. @end verbatim
  2621. @tab
  2622. @verbatim
  2623. np.arange(a, b+1, k)
  2624. @end verbatim
  2625. @tab
  2626. @verbatim
  2627. j:k:n
  2628. @end verbatim
  2629. @item
  2630. equispaced sequence [a .. b] with @var{n} points
  2631. @tab
  2632. @verbatim
  2633. (ra-iota n a (/ (- b a) (- n 1)))
  2634. @end verbatim
  2635. @tab
  2636. @verbatim
  2637. a + ((b-a) ÷ (n-1)) × ι n
  2638. @end verbatim
  2639. @tab
  2640. @verbatim
  2641. np.linspace(a, b, n)
  2642. @end verbatim
  2643. @tab
  2644. @verbatim
  2645. linspace(a, b, n)
  2646. @end verbatim
  2647. @item
  2648. integer sequence :p
  2649. @tab
  2650. @verbatim
  2651. (ra-iota n a k)
  2652. @end verbatim
  2653. @tab
  2654. @verbatim
  2655. a + k × ι n
  2656. @end verbatim
  2657. @tab
  2658. @verbatim
  2659. np.arange(a, a+k*n, k)
  2660. @end verbatim
  2661. @tab
  2662. @verbatim
  2663. a:(a+k*(n-1)):k
  2664. @end verbatim
  2665. @item
  2666. 2x2 array
  2667. @tab
  2668. @verbatim
  2669. ∗ #%2((1 2) (3 4))
  2670. (list->ra 2 '((1 2) (3 4)))
  2671. @end verbatim
  2672. @tab
  2673. @verbatim
  2674. 2 2 ⍴ 1 2 3 4
  2675. @end verbatim
  2676. @tab
  2677. @verbatim
  2678. p.array([[1, 2], [3, 4]])
  2679. @end verbatim
  2680. @tab
  2681. @verbatim
  2682. [1, 2; 3, 4]
  2683. @end verbatim
  2684. @item
  2685. array of zeros
  2686. @tab
  2687. @verbatim
  2688. (make-ra 0 2 2)
  2689. @end verbatim
  2690. @tab
  2691. @verbatim
  2692. 2 2 ⍴ 0
  2693. @end verbatim
  2694. @tab
  2695. @verbatim
  2696. np.zeros((2, 2))
  2697. @end verbatim
  2698. @tab
  2699. @verbatim
  2700. zeros(2, 2)
  2701. @end verbatim
  2702. @item
  2703. array of ones
  2704. @tab
  2705. @verbatim
  2706. (make-ra 1 2 2)
  2707. @end verbatim
  2708. @tab
  2709. @verbatim
  2710. 2 2 ⍴ 1
  2711. @end verbatim
  2712. @tab
  2713. @verbatim
  2714. np.ones((2, 2))
  2715. @end verbatim
  2716. @tab
  2717. @verbatim
  2718. ones(2, 2)
  2719. @end verbatim
  2720. @item
  2721. identity matrix
  2722. @tab
  2723. @verbatim
  2724. (let ((a (make-ra 0 2 2)))
  2725. (ra-fill! (⍉ a 0 0) 1)
  2726. a)
  2727. @end verbatim
  2728. @tab
  2729. @verbatim
  2730. 2 2 ⍴ 1 , 2 ⍴ 0
  2731. @end verbatim
  2732. @tab
  2733. @verbatim
  2734. np.eye(2)
  2735. @end verbatim
  2736. @tab
  2737. @verbatim
  2738. eye(2, 2)
  2739. @end verbatim
  2740. @item
  2741. create diagonal matrix
  2742. @tab
  2743. @verbatim
  2744. (let* ((v #%(1 2 3))
  2745. (a (make-ra 0 (ra-len v) (ra-len v))))
  2746. (ra-copy! (⍉ a 0 0) v)
  2747. a)
  2748. @end verbatim
  2749. @tab
  2750. @verbatim
  2751. v ← 1 2 3
  2752. a ← ((⍴ v), ⍴ v) ⍴ 0
  2753. (0 0 ⍉ a) ← v
  2754. a
  2755. @end verbatim
  2756. @tab
  2757. @verbatim
  2758. np.diag([1, 2, 3])
  2759. @end verbatim
  2760. @tab
  2761. @verbatim
  2762. diag([1 2 3])
  2763. @end verbatim
  2764. @item
  2765. transpose
  2766. @tab
  2767. @verbatim
  2768. (⍉ A 1 0)
  2769. @end verbatim
  2770. @tab
  2771. @cindex @code{⍉}, transpose
  2772. @verbatim
  2773. 1 0 ⍉ A
  2774. @end verbatim
  2775. @tab
  2776. @verbatim
  2777. A.T
  2778. @end verbatim
  2779. @tab
  2780. @verbatim
  2781. A.'
  2782. @end verbatim
  2783. @item
  2784. cat horizontally
  2785. @tab
  2786. @verbatim
  2787. ∗ (define a #%(1 2))
  2788. (ra-cat #f 0 a a)
  2789. @end verbatim
  2790. @tab
  2791. @verbatim
  2792. a ← 1 2
  2793. a , a
  2794. @end verbatim
  2795. @tab
  2796. @verbatim
  2797. a = np.array([1, 2])
  2798. np.hstack((a, a))
  2799. @end verbatim
  2800. @tab
  2801. @verbatim
  2802. a = [1 2]
  2803. [a a]
  2804. @end verbatim
  2805. @item
  2806. cat vertically
  2807. @tab
  2808. @verbatim
  2809. ∗ (define a #%(1 2))
  2810. (ra-cats #f 1 a a)
  2811. @end verbatim
  2812. @tab
  2813. @verbatim
  2814. a ← 1 2
  2815. a ⍪ a
  2816. @end verbatim
  2817. @tab
  2818. @verbatim
  2819. a = np.array([1, 2])
  2820. np.vstack((a, a))
  2821. @end verbatim
  2822. @tab
  2823. @verbatim
  2824. a = [1 2]
  2825. [a; a]
  2826. @end verbatim
  2827. @item
  2828. convert matrix to vector
  2829. @tab
  2830. @verbatim
  2831. (ra-ravel a)
  2832. @end verbatim
  2833. @tab
  2834. @verbatim
  2835. , a
  2836. @end verbatim
  2837. @tab
  2838. @verbatim
  2839. a.flatten()
  2840. @end verbatim
  2841. @tab
  2842. @verbatim
  2843. a(:)
  2844. @end verbatim
  2845. @item
  2846. flip matrix left/right
  2847. @tab
  2848. @c todo define a copy of np.tile's behavior
  2849. @verbatim
  2850. (ra-reverse a 1)
  2851. @end verbatim
  2852. @tab
  2853. @cindex @code{⌽}, reverse
  2854. @verbatim
  2855. ⌽ a
  2856. @end verbatim
  2857. @tab
  2858. @verbatim
  2859. np.fliplr(a)
  2860. @end verbatim
  2861. @tab
  2862. @verbatim
  2863. fliplr(a)
  2864. @end verbatim
  2865. @item
  2866. flip matrix up/down
  2867. @tab
  2868. @c todo define a copy of np.tile's behavior
  2869. @verbatim
  2870. (ra-reverse a 0)
  2871. @end verbatim
  2872. @tab
  2873. @cindex @code{⊖}, rowel
  2874. @verbatim
  2875. ⊖ a
  2876. @end verbatim
  2877. @tab
  2878. @verbatim
  2879. np.flipud(a)
  2880. @end verbatim
  2881. @tab
  2882. @verbatim
  2883. flipud(a)
  2884. @end verbatim
  2885. @item
  2886. broadcast a function over arrays
  2887. @tab
  2888. @verbatim
  2889. (define (f x) (* x x))
  2890. (define (g x y) (+ 2 x (* y y)))
  2891. (define x (ra-iota 10 1))
  2892. (define y (ra-iota 10 2))
  2893. (ra-map #f f x)
  2894. (ra-map #f g x y)
  2895. @end verbatim
  2896. @tab
  2897. tbf
  2898. @tab
  2899. @verbatim
  2900. def f(x): return x**2
  2901. def g(x, y): return x + 2 + y**2
  2902. x = np.arange(1, 11)
  2903. y = np.arange(2, 12)
  2904. f(x)
  2905. g(x, y)
  2906. @end verbatim
  2907. @tab
  2908. @verbatim
  2909. f = @(x) x.^2
  2910. g = @(x, y) x + 2 + y.^2
  2911. x = 1:10
  2912. y = 2:11
  2913. f(x)
  2914. g(x, y)
  2915. @end verbatim
  2916. @item
  2917. for matrix @code{a}, access one element
  2918. @tab
  2919. @verbatim
  2920. (a 2 2)
  2921. ────
  2922. (ra-from a 2 2)
  2923. @end verbatim
  2924. @tab
  2925. @verbatim
  2926. a[2; 2]
  2927. @end verbatim
  2928. @tab
  2929. @verbatim
  2930. a[2, 2]
  2931. @end verbatim
  2932. @tab
  2933. @verbatim
  2934. a(2, 2)
  2935. @end verbatim
  2936. @item
  2937. for matrix @code{a}, access row block
  2938. @tab
  2939. @verbatim
  2940. (ra-from a (ra-iota 4 1))
  2941. @end verbatim
  2942. @tab
  2943. @verbatim
  2944. a[1 + ι 4; ]
  2945. @end verbatim
  2946. @tab
  2947. @verbatim
  2948. a[1:5, :]
  2949. @end verbatim
  2950. @tab
  2951. @verbatim
  2952. a(1:4, :)
  2953. @end verbatim
  2954. @item
  2955. for matrix @code{a}, access column block
  2956. @tab
  2957. @verbatim
  2958. (ra-from a #t (ra-iota 4 1))
  2959. @end verbatim
  2960. @tab
  2961. @verbatim
  2962. a[; 1 + ι 4]
  2963. @end verbatim
  2964. @tab
  2965. @verbatim
  2966. a[:, 1:5]
  2967. @end verbatim
  2968. @tab
  2969. @verbatim
  2970. a(:, 1:4)
  2971. @end verbatim
  2972. @item
  2973. copy of matrix with row removed
  2974. @tab
  2975. @verbatim
  2976. (ra-from a (list->ra 1 '(1 2 4)))
  2977. @end verbatim
  2978. @tab
  2979. @verbatim
  2980. a[1 2 4; ]
  2981. @end verbatim
  2982. @tab
  2983. @verbatim
  2984. a[[1 2 4], :]
  2985. @end verbatim
  2986. @tab
  2987. @verbatim
  2988. a([1 2 4], :)
  2989. @end verbatim
  2990. @item
  2991. diagonal of matrix
  2992. @tab
  2993. @verbatim
  2994. (⍉ a 0 0)
  2995. @end verbatim
  2996. @tab
  2997. @verbatim
  2998. 0 0 ⍉ a
  2999. @end verbatim
  3000. @tab
  3001. @verbatim
  3002. np.diag(a)
  3003. @end verbatim
  3004. @tab
  3005. @verbatim
  3006. diag(a)
  3007. @end verbatim
  3008. @item
  3009. dimensions of matrix
  3010. @tab
  3011. @verbatim
  3012. (match (ra-dimensions a)
  3013. ((nrow ncol) ...))
  3014. @end verbatim
  3015. @tab
  3016. @verbatim
  3017. nrow ← (ρ a)[0]
  3018. ncol ← (ρ a)[1]
  3019. @end verbatim
  3020. @tab
  3021. @verbatim
  3022. nrow, ncol = np.shape(A)
  3023. @end verbatim
  3024. @tab
  3025. @verbatim
  3026. [nrow ncol] = size(A)
  3027. @end verbatim
  3028. @item
  3029. sum/max/min each column of matrix
  3030. @tab
  3031. @verbatim
  3032. (define id 0/-inf.0/+inf.0)
  3033. (define op +/max/min)
  3034. (let ((b (make-ra id (ra-len a 1))))
  3035. (ra-map! b op b (⍉ 1 0)))
  3036. @end verbatim
  3037. @tab
  3038. @verbatim
  3039. + / ⍉ a
  3040. ⌈ / ⍉ a
  3041. ⌊ / ⍉ a
  3042. @end verbatim
  3043. @tab
  3044. @verbatim
  3045. np.sum(a, 0)
  3046. np.max(a, 0)
  3047. np.min(a, 0)
  3048. @end verbatim
  3049. @tab
  3050. @verbatim
  3051. sum(a, 1)
  3052. max(a, 1)
  3053. min(a, 1)
  3054. @end verbatim
  3055. @item
  3056. sum/max/min each row of matrix
  3057. @tab
  3058. @verbatim
  3059. (define id 0/-inf.0/+inf.0)
  3060. (define op +/max/min)
  3061. (let ((b (make-ra id (ra-len a 0))))
  3062. (ra-map! b op b a))
  3063. @end verbatim
  3064. @tab
  3065. @verbatim
  3066. + / a
  3067. ⌈ / a
  3068. ⌊ / a
  3069. @end verbatim
  3070. @tab
  3071. @verbatim
  3072. np.sum(a, 1)
  3073. np.max(a, 1)
  3074. np.min(a, 1)
  3075. @end verbatim
  3076. @tab
  3077. @verbatim
  3078. sum(a, 2)
  3079. max(a, 2)
  3080. min(a, 2)
  3081. @end verbatim
  3082. @item
  3083. sum/max/min the whole matrix
  3084. @tab
  3085. @verbatim
  3086. (define id 0/-inf.0/+inf.0)
  3087. (define op +/max/min)
  3088. (ra-fold op id a)
  3089. @end verbatim
  3090. @tab
  3091. @verbatim
  3092. + / , a
  3093. ⌈ / , a
  3094. ⌊ / , a
  3095. @end verbatim
  3096. @tab
  3097. @verbatim
  3098. np.sum(a)
  3099. np.max(a)
  3100. np.min(a)
  3101. @end verbatim
  3102. @tab
  3103. @verbatim
  3104. sum(a)
  3105. max(a)
  3106. min(a)
  3107. @end verbatim
  3108. @item
  3109. dot product of vectors
  3110. @tab
  3111. @verbatim
  3112. (ra-fold
  3113. (λ (c a b) (+ c (* a b)))
  3114. a b)
  3115. @end verbatim
  3116. @tab
  3117. @verbatim
  3118. a + . × b
  3119. @end verbatim
  3120. @tab
  3121. @verbatim
  3122. a @ b
  3123. @end verbatim
  3124. @tab
  3125. @verbatim
  3126. dot(a, b)
  3127. @end verbatim
  3128. @item
  3129. matrix product
  3130. @tab
  3131. @verbatim
  3132. (let* ((c (make-ra 0 (ra-len a 0) (ra-len b 1)))
  3133. (cc (⍉ c 0 2)))
  3134. (ra-map! cc (λ (c a b) (+ c (* a b)))
  3135. cc a (⍉ b 1))
  3136. c)
  3137. @end verbatim
  3138. @tab
  3139. @verbatim
  3140. a + . × b
  3141. @end verbatim
  3142. @tab
  3143. @verbatim
  3144. a @ b
  3145. @end verbatim
  3146. @tab
  3147. @verbatim
  3148. a * b
  3149. @end verbatim
  3150. @item
  3151. elementwise product of matrices
  3152. @tab
  3153. @verbatim
  3154. (ra-map #f * a b)
  3155. @end verbatim
  3156. @tab
  3157. @verbatim
  3158. a × b
  3159. @end verbatim
  3160. @tab
  3161. @verbatim
  3162. a * b
  3163. @end verbatim
  3164. @tab
  3165. @verbatim
  3166. a .* b
  3167. @end verbatim
  3168. @anchor{x-numpy-example-0}
  3169. @item
  3170. multiply each element of vector by each row of matrix
  3171. @tab
  3172. @verbatim
  3173. (ra-map #f * m v)
  3174. @end verbatim
  3175. @tab
  3176. @verbatim
  3177. m ×⍤1 0 v
  3178. @end verbatim
  3179. @tab
  3180. @verbatim
  3181. m * v[:, np.newaxis]
  3182. ────
  3183. np.diag(v) * m
  3184. @end verbatim
  3185. @tab
  3186. @verbatim
  3187. diag(v) * m
  3188. @end verbatim
  3189. @item
  3190. multiply each element of vector by each column of matrix
  3191. @tab
  3192. @verbatim
  3193. (ra-map #f * m (⍉ v 1))
  3194. @end verbatim
  3195. @tab
  3196. @verbatim
  3197. m ×⍤1 1 v
  3198. @end verbatim
  3199. @tab
  3200. @verbatim
  3201. m * v
  3202. ────
  3203. m * v[np.newaxis, :]
  3204. ────
  3205. m * np.diag(v)
  3206. @end verbatim
  3207. @tab
  3208. @verbatim
  3209. m * diag(v)
  3210. @end verbatim
  3211. @item
  3212. ...
  3213. @tab
  3214. ...
  3215. @tab
  3216. ...
  3217. @tab
  3218. ...
  3219. @tab
  3220. ...
  3221. @end multitable
  3222. @c ------------------------------------------------
  3223. @node @mybibnode{}
  3224. @chapter Sources
  3225. @c ------------------------------------------------
  3226. @multitable @columnfractions .1 .9
  3227. @item @mybibitem{Abr70} @tab Philip S. Abrams. An APL machine. Technical report SLAC-114 UC-32 (MISC), Stanford Linear Accelerator Center, Stanford University, Stanford, CA, USA, February 1970.
  3228. @item @mybibitem{Ber87} @tab Robert Bernecky. An introduction to function rank. ACM SIGAPL APL Quote Quad, 18(2):39–43, December 1987.
  3229. @item @mybibitem{bli17} @tab The Blitz++ meta-template library. @url{http://blitz.sourceforge.net}, November 2017.
  3230. @item @mybibitem{Cha86} @tab Gregory J. Chaitin. Physics in APL2, June 1986.
  3231. @item @mybibitem{FI68} @tab Adin D. Falkoff and Kenneth Eugene Iverson. APL\360 User’s manual. IBM Thomas J. Watson Research Center, August 1968.
  3232. @item @mybibitem{FI73} @tab Adin D. Falkoff and Kenneth Eugene Iverson. The design of APL. IBM Journal of Research and Development, 17(4):5–14, July 1973.
  3233. @item @mybibitem{FI78} @tab Adin D. Falkoff and Kenneth Eugene Iverson. The evolution of APL. ACM SIGAPL APL, 9(1):30– 44, 1978.
  3234. @item @mybibitem{J S} @tab J Primer. J Software, @url{https://www.jsoftware.com/help/primer/contents.htm}, November 2017.
  3235. @item @mybibitem{Mat} @tab MathWorks. MATLAB documentation, @url{https://www.mathworks.com/help/matlab/}, November 2017.
  3236. @item @mybibitem{Octave} @tab GNU Octave documentation (version 6.3.0), @url{https://octave.org/doc/v6.3.0}, 2020.
  3237. @item @mybibitem{num17} @tab NumPy. @url{http://www.numpy.org}, November 2017.
  3238. @item @mybibitem{Ric08} @tab Henry Rich. J for C programmers, February 2008.
  3239. @item @mybibitem{SSM14} @tab 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.
  3240. @item @mybibitem{Wad90} @tab Philip Wadler. Deforestation: transforming programs to eliminate trees. Theoretical Computer Science, 73(2): 231--248, June 1990. @url{https://doi.org/10.1016/0304-3975%2890%2990147-A}
  3241. @item @mybibitem{SRFI-4} @tab Marc Feeley. SRFI-4: Homogeneous numeric vector datatypes, May 1999. @url{https://srfi.schemers.org/srfi-4/srfi-4.html}
  3242. @item @mybibitem{SRFI-25} @tab Jussi Piitulainen. SRFI-25: Multi-dimensional array primitives, May 2002. @url{https://srfi.schemers.org/srfi-25/srfi-25.html}
  3243. @item @mybibitem{SRFI-122} @tab Bradley J. Lucier. SRFI-122: Nonempty intervals and generalized arrays, December 2016. @url{https://srfi.schemers.org/srfi-122/srfi-122.html}
  3244. @item @mybibitem{SRFI-160} @tab John Cowan and Shiro Kawai. SRFI-160: Homogeneous numeric vector libraries, November 2020. @url{https://srfi.schemers.org/srfi-160/srfi-160.html}
  3245. @item @mybibitem{S7} @tab S7 Scheme: Multidimensional vectors. Accessed June 2022. @url{https://ccrma.stanford.edu/software/snd/snd/s7.html#multidimensionalvectors}
  3246. @item @mybibitem{SRFI-163} @tab Per Bothner. SRFI-163: Enhanced array literals, January 2019. @url{https://srfi.schemers.org/srfi-163/srfi-163.html}
  3247. @item @mybibitem{SRFI-164} @tab Per Bothner. SRFI-164: Enhanced multi-dimensional arrays, August 2019. @url{https://srfi.schemers.org/srfi-164/srfi-164.html}
  3248. @item @mybibitem{SRFI-231} @tab Bradley J. Lucier. SRFI-231: Intervals and generalized arrays, September 2022. @url{https://srfi.schemers.org/srfi-164/srfi-164.html}
  3249. @end multitable
  3250. @c ------------------------------------------------
  3251. @node Indices
  3252. @unnumbered Indices
  3253. @c ------------------------------------------------
  3254. @c @node Concept Index
  3255. @c @unnumbered Concept Index
  3256. @printindex cp
  3257. @c @node Function Index
  3258. @c @unnumbered Function Index
  3259. @c @printindex fn
  3260. @c \nocite{JLangReference,FalkoffIverson1968,Abrams1970,FalkoffIverson1973,FalkoffIverson1978,APLexamples1,ArraysCowan,KonaTheLanguage,blitz++2001}
  3261. @bye