@@ -79,34 +79,44 @@ export const createMap = /* #__PURE__ */ factory(name, dependencies, ({ typed })
7979 }
8080
8181 const firstArrayIsMatrix = Arrays [ 0 ] . isMatrix
82-
83- const newSize = broadcastSizes ( ...Arrays . map ( M => M . isMatrix ? M . size ( ) : arraySize ( M ) ) )
82+ const sizes = Arrays . map ( M => M . isMatrix ? M . size ( ) : arraySize ( M ) )
83+ const newSize = broadcastSizes ( ...sizes )
84+ const numberOfArrays = Arrays . length
8485
8586 const _get = firstArrayIsMatrix
8687 ? ( matrix , idx ) => matrix . get ( idx )
8788 : get
8889
89- const broadcastedArrays = firstArrayIsMatrix
90- ? Arrays . map ( M => M . isMatrix
91- ? M . create ( broadcastTo ( M . toArray ( ) , newSize ) , M . datatype ( ) )
92- : Arrays [ 0 ] . create ( broadcastTo ( M . valueOf ( ) , newSize ) ) )
93- : Arrays . map ( M => M . isMatrix
94- ? broadcastTo ( M . toArray ( ) , newSize )
95- : broadcastTo ( M , newSize ) )
90+ const firstValues = Arrays . map ( ( collection , i ) => {
91+ const firstIndex = sizes [ i ] . map ( x => 0 )
92+ return collection . isMatrix ? collection . get ( firstIndex ) : get ( collection , firstIndex )
93+ }
94+ )
9695
9796 let callback
97+ let callbackCase
9898
9999 if ( typed . isTypedFunction ( multiCallback ) ) {
100100 const firstIndex = newSize . map ( ( ) => 0 )
101- const firstValues = broadcastedArrays . map ( array => _get ( array , firstIndex ) )
102- const callbackCase = _getTypedCallbackCase ( multiCallback , firstValues , firstIndex , broadcastedArrays )
101+ callbackCase = _getTypedCallbackCase ( multiCallback , firstValues , firstIndex , Arrays )
103102 callback = _getLimitedCallback ( callbackCase )
104103 } else {
105- const numberOfArrays = Arrays . length
106- const callbackCase = _getCallbackCase ( multiCallback , numberOfArrays )
104+ callbackCase = _getCallbackCase ( multiCallback , numberOfArrays )
107105 callback = _getLimitedCallback ( callbackCase )
108106 }
109107
108+ if ( callbackCase < 2 ) {
109+ return mapMultiple ( Arrays , callback )
110+ }
111+
112+ const broadcastedArrays = firstArrayIsMatrix
113+ ? Arrays . map ( M => M . isMatrix
114+ ? M . create ( broadcastTo ( M . toArray ( ) , newSize ) , M . datatype ( ) )
115+ : Arrays [ 0 ] . create ( broadcastTo ( M . valueOf ( ) , newSize ) ) )
116+ : Arrays . map ( M => M . isMatrix
117+ ? broadcastTo ( M . toArray ( ) , newSize )
118+ : broadcastTo ( M , newSize ) )
119+
110120 const broadcastedArraysCallback = ( x , idx ) =>
111121 callback (
112122 [ x , ...broadcastedArrays . slice ( 1 ) . map ( Array => _get ( Array , idx ) ) ] ,
@@ -143,6 +153,69 @@ export const createMap = /* #__PURE__ */ factory(name, dependencies, ({ typed })
143153 return 0
144154 }
145155 }
156+
157+ function mapMultiple ( Collections , callback ) {
158+ // collections can be matrices or arrays
159+ // callback must be a function of the form (collcetions, [index])
160+ const firstCollection = Collections [ 0 ]
161+ const firstCollectionIsMatrix = Boolean ( firstCollection . isMatrix )
162+ const Arrays = Collections . map ( ( collection ) =>
163+ collection . isMatrix ? collection . valueOf ( ) : collection
164+ )
165+ const sizes = Collections . map ( ( collection ) =>
166+ collection . isMatrix ? collection . size ( ) : arraySize ( collection )
167+ )
168+ // this should be changed for the specific function when impelemented
169+ const finalSize = broadcastSizes ( ...sizes )
170+ // the offset means for each initial array, how much smaller is it than the final size
171+ const offsets = sizes . map ( ( size ) => finalSize . length - size . length )
172+ // make the iteration algorithm
173+ const maxDepth = finalSize . length - 1
174+ const index = [ ]
175+ const resultsArray = iterate ( Arrays , 0 )
176+ if ( firstCollectionIsMatrix ) {
177+ const returnMatrix = firstCollection . create ( )
178+ returnMatrix . _data = resultsArray
179+ returnMatrix . _size = finalSize
180+ return returnMatrix
181+ } else {
182+ return resultsArray
183+ }
184+ // will create references to the arrays depth, depending on the offset.
185+
186+ function iterate ( arrays , depth = 0 ) {
187+ // each array can have differt sizes
188+ const N = finalSize [ depth ]
189+ const result = Array ( N )
190+ if ( depth < maxDepth ) {
191+ for ( let i = 0 ; i < N ; i ++ ) {
192+ index [ depth ] = i
193+ // if there is an offset greather than the current dimension
194+ // pass the array, if the size of the array is 1 pass the first
195+ // element of the array
196+ result [ i ] = iterate (
197+ arrays . map ( ( array , arrayIndex ) =>
198+ offsets [ arrayIndex ] > depth
199+ ? array
200+ : array . length === 1
201+ ? array [ 0 ]
202+ : array [ i ]
203+ ) ,
204+ depth + 1
205+ )
206+ }
207+ } else {
208+ for ( let i = 0 ; i < N ; i ++ ) {
209+ index [ depth ] = i
210+ result [ i ] = callback (
211+ arrays . map ( ( a ) => ( a . length === 1 ? a [ 0 ] : a [ i ] ) ) ,
212+ index . slice ( )
213+ )
214+ }
215+ }
216+ return result
217+ }
218+ }
146219 /**
147220 * Map for a multi dimensional array
148221 * @param {Array } array
0 commit comments