Comments (4)
If there is a will, there is a way :D You bring up an interesting question. A solution with exact type signature you presented is not possible without some major change to underlying structure of the library, but that would be a wrong way to go about it anyways.
I am not sure if I will add any of the solutions to the library, but free to use either one of them
Here is a naive and less optimal solution to the problem:
defaultResizeNaive :: (Construct r ix' e, Source r ix e) => e -> ix' -> Array r ix e -> Array D ix' e
defaultResizeNaive e newsz arr =
makeArray (getComp arr) newsz $
handleBorderIndex (Fill e) oldsz (unsafeIndex arr) . fromLinearIndex oldsz . toLinearIndex newsz
where oldsz = size arr
It is sub-optimal because it has to check if index doesn't go out of bounds for every element of new array. But the good thing is that resulting array is D
so no intermediate array has been created and further computation can be fused. Which is also known as "pull" array.
A more involved solution is to actually iterate over the old array while loading it's elements into the new array, and if there is any unfilled space leftover fill it with default value:
defaultResize :: (Source r ix e, Mutable r' ix' e) => e -> ix' -> Array r ix e -> Array r' ix' e
defaultResize e newsz' arr =
unsafePerformIO $ do
let newsz = liftIndex (max 0) newsz'
oldsz = size arr
knew = totalElem newsz
kold = min (totalElem oldsz) knew
comp = getComp arr
marr <- unsafeNew newsz
case comp of
Seq -> do
loopM_ 0 (< kold) (+ 1) $ \i -> unsafeLinearWrite marr i (unsafeLinearIndex arr i)
loopM_ kold (< knew) (+ 1) $ \i -> unsafeLinearWrite marr i e
ParOn wIds ->
withScheduler_ wIds $ \scheduler -> do
splitLinearlyWith_
(numWorkers scheduler)
(scheduleWork scheduler)
kold
(unsafeLinearIndex arr)
(unsafeLinearWrite marr)
let slack = knew - kold
splitLinearlyWith_
(numWorkers scheduler)
(scheduleWork scheduler)
slack
(const e)
(unsafeLinearWrite marr . (+ kold))
unsafeFreeze comp marr
The interesting part about the problem and this last solution is that it would be possible to create a delayed array as well, but of a different kind, namely a "push" array. I've been pondering on this idea for couple of weeks now and considering implementing this new kind of delayed array, we'll see. This would allow nicer solutions for a new class of problems, including this one.
cc @ocramz Thanks for pointing out the topic of Pull/Push arrays to me at Haskell Exchange, it already comes in handy ;)
from massiv.
Wow, I didn't realize it was this tricky! Ultimately, I'd be after a D
array for my current use case, so I'll try both options and see which one works better.
Also, do you have any links about push/pull arrays I could read?
from massiv.
Here is a paper that gives a nice introduction to push pull arrays, but then goes into more stuff: https://svenssonjoel.github.io/writing/defuncEmb.pdf
from massiv.
Now that push arrays are available in massiv we can easily implement this function.
from massiv.
Related Issues (20)
- unstreamIntoM improvements
- iZipWith4 HOT 7
- Breaking changes for massiv-1.0 release HOT 1
- Provide external file (mmaped) representation HOT 3
- Safe stencils aren't completely safe HOT 1
- It would be handy to have `minIndexBy`, `minIndex`, `maxIndexBy`, `maxIndex`.
- Lazier arrays? HOT 4
- Add vector to matrix (and similar operations) HOT 1
- odd behaviour of Sz1 when subtracting something HOT 2
- massiv-serialise/persist testsuites need lot of mem to build HOT 3
- Fix CPP usage so fourmolu doesn't choke
- Add fourmolu to CI
- `findIndex` should not be in `Data.Massiv.Vector` HOT 2
- `resize` should be called `reshape`
- More with nested Arrays HOT 2
- Stand-alone package for Data.Massiv.Core.Index HOT 1
- Ease of Use Improvements
- Gitter link in question template 404s
- Convert `Array U Ix1 a` to `Unboxed.Vector a` without copying HOT 1
- massiv-test test suite failing to build on stackage HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from massiv.