How to get all elements of a Haskell UArray - arrays

I am practising my Haskell skills by attempting to build a command line version of Tetris. For the game board I am using UArray as I can freeze and thaw it, and that allows me to see if the current Tetris piece has collided with currently placed pieces without searching through the whole board (which is what I would need to do if I used lists). I have run into the issue that I am not sure how to convert this array to Text or String to output it to the console.
For now I am working with just one row of the board, which I initialise with the following function:
gameBoardWidth = 10 :: Int
initBoard :: UArray Int Char
initBoard = runSTUArray $ do
let lastCol = gameBoardWidth - 1
row <- newArray (0,lastCol) ' '
return row
Now I am not sure how to get the Char out of the array for printing. From the standard Array interface elems looks like what I need, but that does not appear to work on UArrays.
*Main Console Lib Paths_haskell_tetris Data.Array> elems initBoard
• Couldn't match expected type ‘Array i0 e’
with actual type ‘Data.Array.Base.UArray Int Char’
The other idea I had was to try and use the readArray function in a do block, but I am not sure how to concatenate the result of each string in a functional language
Just in case my issue is to do with the packages I have imported, these are my imports:
import Data.Array.Unboxed
import Data.Array.ST
import Control.Monad
import Control.Monad.ST

Your test uses Data.Array.elems which only works on Array.
You need to call instead the class method Data.Array.IArray.elems which works on any immutable array, including UArray.

Related

Python Unsigned 16-bit Integer Array Elements

Is there an equivalent to numpy.array(someArray, dtype=numpy.uint16) by just using the array module in Python 3? I'm trying to build the equivalent of the buffer of a Javascript Uint16Array object: Uint16Array(someArray).buffer).
Here's what I have so far:
import numpy as np
someArray = []
someArray.append(0)
someArray.append(216)
someArray.append(162)
someArray.append(52)
print(bytearray(np.array(someArray, dtype=np.uint16)))
Output: bytearray(b'\x00\x00\xd8\x00\xa2\x004\x00')
But, if I try the following:
import array as arrayModule
someArray = arrayModule.array("I", [])
someArray.append(0)
someArray.append(216)
someArray.append(162)
someArray.append(52)
print(bytearray(someArray.tobytes()))
Output: bytearray(b'\x00\x00\x00\x00\xd8\x00\x00\x00\xa2\x00\x00\x004\x00\x00\x00')
Using the numpy module works but I'd rather find a native way to accomplish the goal as this is the only place that I use numpy... seems inefficient to import a large module just to use it once.
You want to use "H" (unsigned short) instead of "I" (unsigned int). In C, int can be 2 or 4 bytes depending on architecture and its usually 4. You could check someArray.itemsize to verify on your machine.

Calling a numpy function in Cython really slows things down

I'm trying to call np.random.choice, without replacement, row-by-row in a 2-D numpy array. I'm using Cython to get a speed boost. The code is only running a factor of 3 faster than a pure-python implementation, which is not a great result. The bottleneck is the numpy function call itself. When I comment it out, and just supply a static result of, say [3, 2, 1, 0] to each row, I get a factor of 1000 speedup (of course then it's not doing much of anything :)
My question: is there something I'm doing wrong in calling the numpy function that's causing it to go super slow? In theory it's C talking to C, so it should be fast. I looked at the compiled code, and the call to the numpy function looks complex, with statements like __Pyx_GOTREF and __Pyx_PyObject_GetAttrStr that lead me to believe it's using pure python in the process (bad!!).
My code:
# tag: numpy
import numpy as np
# compile-time info for numpy
cimport numpy as np
np.import_array()
# array dtypes
W_DTYPE = np.float
C_DTYPE = np.int
cdef int NUM_SELECTIONS = 4 # FIXME should be function kwarg
#compile-time dtypes
ctypedef np.float_t W_DTYPE_t
ctypedef np.int_t C_DTYPE_t
def allocate_choices(np.ndarray[W_DTYPE_t, ndim=2] round_weights,
np.ndarray[C_DTYPE_t, ndim=1] choice_labels):
"""
For ea. row in `round_weights` select NUM_SELECTIONS=4 items among
corresponding `choice_labels`, without replacement, with corresponding
probabilities in `round_weights`.
Args:
round_weights (np.ndarray): 2-d array of weights, w/
size [n_rounds, n_choices]
choice_labels (np.ndarray): 1-d array of choice labels,
w/ size [n_choices]; choices must be *INTEGERS*
Returns:
choices (np.ndarray): selected items per round, w/ size
[n_rounds, NUM_SELECTIONS]
"""
assert round_weights.dtype == W_DTYPE
assert choice_labels.dtype == C_DTYPE
assert round_weights.shape[1] == choice_labels.shape[0]
# initialize final choices array
cdef int n_rows = round_weights.shape[0]
cdef np.ndarray[C_DTYPE_t, ndim=2] choices = np.zeros([n_rows, NUM_SELECTIONS],
dtype=C_DTYPE)
# Allocate choices, per round
cdef int i, j
cdef bint replace = False
for i in range(n_rows):
choices[i] = np.random.choice(choice_labels,
NUM_SELECTIONS,
replace,
round_weights[i])
return choices
Update on this, after chatting with some folks and examining the compiled code: #DavidW's comment above put it well:
" In theory it's C talking to C, so it should be fast" - no. Not true.
The main bit of Numpy that cimport numpy gives direct access to is
just faster indexing of arrays. Numpy functions are called using the
normal Python mechanism. They may ultimately be implemented in C, but
that doesn't give a shortcut from Cython's point-of-view.
So this issue here is, calling this Numpy function requires translating the inputs back into python objects, passing them in, and then letting numpy do its thing. I don't think this is the case for all Numpy functions (from timing experiments, some of them I call work quite fast), but plenty are not "Cythonized".

How do I set a vector's elements to point to the first element in an array of arrays?

I've been learning Julia by trying to write a simple rigid body simulation, but I'm still somewhat confused about the assignment and mutating of variables.
I'm storing the points making up the shape of a body into an array of arrays where one vector holds the x,y,z coordinates of a point. For plotting the body with PyPlot the points are first transformed from local coordinates into world coordinates and then assigned to three arrays which hold the x, y, and z coordinates for the points respectively. I would like to have the three arrays only reference the array of arrays values instead of having copies of the values.
The relevant part of my code looks like this
type Rigidbody
n::Integer
k::Integer
bodyXYZ::Array{Array{Float64,1},2}
worldXYZ::Array{Array{Float64,1},2}
worldX::Array{Float64,2}
worldY::Array{Float64,2}
worldZ::Array{Float64,2}
Rotmat::Array{Float64,2}
x::Array{Float64,1}
end
# body.worldXYZ[1,1] = [x; y; z]
# and body.worldX[1,1] should be body.worldXYZ[1,1][1]
function body_to_world(body::Rigidbody)
for j in range(1, body.k)
for i in range(1, body.n)
body.worldXYZ[i,j] = body.x + body.Rotmat*body.bodyXYZ[i,j]
body.worldX[i,j] = body.worldXYZ[i,j][1]
body.worldY[i,j] = body.worldXYZ[i,j][2]
body.worldZ[i,j] = body.worldXYZ[i,j][3]
end
end
return nothing
end
After calling the body_to_world() and checking the elements with === they evaluate to true but if I then for example set
body.worldXYZ[1,1][1] = 99.999
the change is not reflected in body.worldX. The problem is probably something trivial but as can be seen from my code, I am a beginner and could use some help.
body.worldX[i,j] = body.worldXYZ[i,j][1]
You're setting a number to a number here. Numbers are not mutable, so body.worldX[i,j] won't refer back to body.worldXYZ[i,j][1]. What you're thinking of is that the value of an array will be a reference, but numbers don't have references, just the value themselves.
However, I would venture to say that if you're doing something like that, you're going about the problem wrong. You should probably be using types somewhere. Remember, types in Julia give good performance, so don't be afraid of them (and immutable types should be almost perfectly optimized after carneval's PR, so there's really no need to be afraid). Instead, I would make world::Array{Point,2} where
immutable Point{T}
x::T
y::T
z::T
end
Then you can get body.world[i,j].x for the x coordinate, etc. And then for free you can use map((i,j)->Ref(body.world[i,j].x),size(body.world)...) to get an array of references to the x's.
Or, you should be adding dispatches to your type. For example
import Base: size
size(RigidBody) = (n,k)
now size(body) outputs (n,k), as though it's an array. You can complete the array interface with getindex and setindex!. This kind of adding dispatches to your type will help clean up the code immensely.

Filter file by length BEFORE saving haskell

A similar question has been asked, but with a list in hand:
Filter list items by length in Haskell
I already know how to get a word list from a file
getWords path = do contents <- readFile path
return (lines contents)
And then I can filter it to get words of specific length, but...
What I am wondering is if there is a way (preferably not in point-free style - unless necessary) to filter the file by length before saving it as a list of words.
For example, words.txt is file of words with 1 word per line.
filteredWords <- filter (\x -> length x == 3) *Read words.txt in place*
Use the fact that IO is also an instance of Functor
filteredWords <- fmap (filter (\x -> length x == 3)) $ getWords path
Since you asked about how to do it without using getWords: you can use the function composition operator ..
filteredWords <- fmap (filter (\x -> length x == 3) . lines) $ readFile path
I think readFile is in Prelude, if it's not then it will be in System.IO
I am not sure I completely understand this question. It centers around the notion of "before saving it as a list of words", which seems to be misleading in a lazy language. In Haskell, doing
let list1 = someLongList
list2 = filter p list1
in use list2 -- (but do not use list1)
will not cause list1 to be stored in memory completely: rather, elements not satisfying p will be discarded immediately.
Hence, the notion of filtering a list before "saving" it is not meaningful: this is a standard optimization that the compiler will do for you.
Rather, separating input/output and filtering is the preferred way. The alternative, namely mixing I/O and pure computation in the code is generally regarded as a worse approach. Haskell types also encourage the first, simpler, approach.
Yes. Here is an example using pipes that avoids materializing the full list of words. Only the words of the specified length will be retained in memory:
import Pipes
import qualified Pipes.Prelude as Pipes
import qualified System.IO as IO
filteredWords :: FilePath -> IO [String]
filteredWords path =
IO.withFile path IO.ReadMode (\handle -> Pipes.toListM (
Pipes.fromHandle handle >-> Pipes.filter (\x -> length x == 3) ))
So, for example, if your file had 1,000,000 words, but only 4 of them had length 3, then this program would only generate a list of length 4. All the other elements would be discarded immediately after they were read and not stored in memory in some intermediate list.

Dynamic programming with Data.Vector

am using Data.Vector and am currently in need of computing the contents of a vector for use in computing a cryptographic hash(Sha1). I created the following code.
dynamic :: a -> Int -> (Int -> Vector a -> a) -> Vector a
dynamic e n f =
let
start = Data.Vector.replicate n e
in step start 0
where
step vector i = if i==n then vector
else step (vector // [(i,f i vector)]) (i+1)
I created this so that the function f filling out the vector has access to the partial
results along the way. Surely something like this must already exist in Data.Vector, no?
The problem statement is the following: You are to solve a dynamic programming problem where the finished result is an array. You know the size of the array size and you have a recursive function for filling it out.
You probably already saw the function generate, which takes a size n and a function f of type Int -> a and then produces a Vector a of size n. What you probably weren't aware of is that when using this function you actually do have access to the partial results.
What I mean to say is that inside the function you pass to generate you can refer to the vector you're defining and due to Haskell's laziness it will work fine (unless you make it so that the different items of the vector depend on each other in a circular fashion, of course).
Example:
import Data.Vector
tenFibs = generate 10 fib
where fib 0 = 0
fib 1 = 1
fib n = tenFibs ! (n-1) + tenFibs ! (n-2)
tenFibs is now a vector containing the first 10 Fibonacci numbers.
Maybe you could use one of Data.Vector's scan functions?
http://hackage.haskell.org/packages/archive/vector/0.6.0.2/doc/html/Data-Vector.html#32

Resources