
What is the most efficient way to update a position in a matrix or a vector? I came up with this: updateVector :: Vector Double -> Int -> Double -> Vector Double updateVector vec pos val = vec `add` v2 where v2 = fromList $ (replicate (pos) 0.0) ++ ((val - (vec @> pos)):(replicate ((dim vec)- pos - 1) 0.0)) but this seems pretty inefficient to me. thanks, Anatoly

Anatoly Yakovenko wrote:
What is the most efficient way to update a position in a matrix or a vector? I came up with this:
updateVector :: Vector Double -> Int -> Double -> Vector Double updateVector vec pos val = vec `add` v2 where v2 = fromList $ (replicate (pos) 0.0) ++ ((val - (vec @> pos)):(replicate ((dim vec)- pos - 1) 0.0))
but this seems pretty inefficient to me.
thanks, Anatoly
It is probably more efficient to use subVector and join (implemented by copyArray): updateVector' v pos val | pos == 0 = join [b,c] | pos == dim v -1 = join [a,b] | otherwise = join [a,b,c] where a = subVector 0 pos v b = fromList [val] c = subVector (pos+1) (dim v -pos-1) v
updateVector' (fromList [1,2,3,4,5]) 2 57 5 |> [1.0,2.0,57.0,4.0,5.0]
(The three cases are required because empty vectors are not currently allowed.) Something similar can be done for matrices using flatten and reshape. Although vectors and matrices in this library are immutable and intended to be manipulated as a whole by higher level functions, this kind of update functions may often be useful. I will include them soon. Alberto

do you have any plans to provide an interface for inplace updates?
On Sun, Jun 1, 2008 at 3:20 AM, Alberto Ruiz
Anatoly Yakovenko wrote:
What is the most efficient way to update a position in a matrix or a vector? I came up with this:
updateVector :: Vector Double -> Int -> Double -> Vector Double updateVector vec pos val = vec `add` v2 where v2 = fromList $ (replicate (pos) 0.0) ++ ((val - (vec @> pos)):(replicate ((dim vec)- pos - 1) 0.0))
but this seems pretty inefficient to me.
thanks, Anatoly
It is probably more efficient to use subVector and join (implemented by copyArray):
updateVector' v pos val | pos == 0 = join [b,c] | pos == dim v -1 = join [a,b] | otherwise = join [a,b,c] where a = subVector 0 pos v b = fromList [val] c = subVector (pos+1) (dim v -pos-1) v
updateVector' (fromList [1,2,3,4,5]) 2 57 5 |> [1.0,2.0,57.0,4.0,5.0]
(The three cases are required because empty vectors are not currently allowed.)
Something similar can be done for matrices using flatten and reshape.
Although vectors and matrices in this library are immutable and intended to be manipulated as a whole by higher level functions, this kind of update functions may often be useful. I will include them soon.
Alberto

Anatoly Yakovenko wrote:
do you have any plans to provide an interface for inplace updates?
Yes, I will try to write a simple version of Data.Array.ST...
On Sun, Jun 1, 2008 at 3:20 AM, Alberto Ruiz
wrote: Anatoly Yakovenko wrote:
What is the most efficient way to update a position in a matrix or a vector? I came up with this:
updateVector :: Vector Double -> Int -> Double -> Vector Double updateVector vec pos val = vec `add` v2 where v2 = fromList $ (replicate (pos) 0.0) ++ ((val - (vec @> pos)):(replicate ((dim vec)- pos - 1) 0.0))
but this seems pretty inefficient to me.
thanks, Anatoly
It is probably more efficient to use subVector and join (implemented by copyArray):
updateVector' v pos val | pos == 0 = join [b,c] | pos == dim v -1 = join [a,b] | otherwise = join [a,b,c] where a = subVector 0 pos v b = fromList [val] c = subVector (pos+1) (dim v -pos-1) v
updateVector' (fromList [1,2,3,4,5]) 2 57 5 |> [1.0,2.0,57.0,4.0,5.0]
(The three cases are required because empty vectors are not currently allowed.)
Something similar can be done for matrices using flatten and reshape.
Although vectors and matrices in this library are immutable and intended to be manipulated as a whole by higher level functions, this kind of update functions may often be useful. I will include them soon.
Alberto

do you have any plans to provide an interface for inplace updates?
Yes, I will try to write a simple version of Data.Array.ST...
I can try to help you, although I still dont quite grok monads. Wouldn't it be more efficient to use StorableArray, so you can cast from and to C? I am not sure how vectors and matrixes are represented in C, but I imagine it should be possible to manipulate them without resorting to copying between haskell and C.

Hello Anatoly,
Yes, I will try to write a simple version of Data.Array.ST... Wouldn't it be more efficient to use StorableArray, so you can cast
there is some difference between them - MutableByteArray# (used for STUArray) is movable Haskell object which is subject to GC while StorableArray has a fixed address and allocated through C malloc(). this makes MBA more appropriate for small arrays while SA should be used for large ones because GC makes memory usage of program 3 times larger -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Anatoly Yakovenko wrote:
do you have any plans to provide an interface for inplace updates? Yes, I will try to write a simple version of Data.Array.ST...
I can try to help you, although I still dont quite grok monads. Wouldn't it be more efficient to use StorableArray, so you can cast from and to C? I am not sure how vectors and matrixes are represented in C, but I imagine it should be possible to manipulate them without resorting to copying between haskell and C.
That's right, the correspondence with StorableArray is direct, and efficient conversion can be easily added to the library. I mentioned the idea of Data.Array.ST to have also the possibility of writing pure code, without IO, internally implemented with inplace updates. Alberto

Hello Alberto, Tuesday, June 3, 2008, 11:27:54 AM, you wrote:
Yes, I will try to write a simple version of Data.Array.ST... That's right, the correspondence with StorableArray is direct, and efficient conversion can be easily added to the library. I mentioned the idea of Data.Array.ST to have also the possibility of writing pure code, without IO, internally implemented with inplace updates.
STRef/STArray operations are just IORef/IOArray operations imported in some way/ you can easily import any other operations to ST monad as far as you use rank-2 types to guarantee that impureness will not escape the runST call. look into unsafeIOtoST function providing unmovable STUArray variant may be a good idea -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat Ziganshin wrote:
Hello Alberto,
Tuesday, June 3, 2008, 11:27:54 AM, you wrote:
Yes, I will try to write a simple version of Data.Array.ST... That's right, the correspondence with StorableArray is direct, and efficient conversion can be easily added to the library. I mentioned the idea of Data.Array.ST to have also the possibility of writing pure code, without IO, internally implemented with inplace updates.
STRef/STArray operations are just IORef/IOArray operations imported in some way/ you can easily import any other operations to ST monad as far as you use rank-2 types to guarantee that impureness will not escape the runST call. look into unsafeIOtoST function
Good! So you can easily "hide" the IO operations in the ST monad. I will definitely look into it.
providing unmovable STUArray variant may be a good idea
Many thanks Bulat!

Hello Alberto, Tuesday, June 3, 2008, 12:56:50 PM, you wrote:
Good! So you can easily "hide" the IO operations in the ST monad. I will definitely look into it.
from implementation POV ST monad is nothing but renamed IO monad which exports only subset of its operations which are guaranteed to safe. or, saying in other words, it's just type hackery around IO monad that provides safe operations it's possible to define ST monad and its operations as following: newtype ST s a = forall s. ST_Constructor (IO a) unsafeIOtoSt action = ST_Constructor action runST (ST_Constructor action) = unsafePerformIO action newtype STRef s a = forall s. STRef (IORef a) readSTRef (STRef ref) = unsafeIOtoSt (readIORef ref) and so on. GHC uses technically (but not ideologically!) different implementation where both monads are specializations of one generic type. while Hugs afair uses exactly this approach. you may also look at ArrayRef lib which reimplements arrays/refs for both compilers in more unified way anyway, because ST is just IO monad modulo type tricks, you can execute any IO action inside ST by lifting it with unsafeIOtoSt -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hello Bulat and Anatoly, I have written a first version of an interface to inplace updates in the ST monad for the hmatrix vectors and matrices. Many things must be improved (range checking, documentation, etc.) but I hope that the general idea makes sense. A few usage examples: http://perception.inf.um.es/~aruiz/darcs/hmatrix/examples/inplace.hs Code: http://perception.inf.um.es/~aruiz/darcs/hmatrix/lib/Data/Packed/ST.hs http://perception.inf.um.es/~aruiz/darcs/hmatrix/doc/html/Data-Packed-ST.htm... Any suggestion will be welcome. I'm impressed by the power of the ST monad, it is extremely useful and elegant. Thank you again for your help! In the future I will also try to include efficient conversions to/from standard Haskell arrays and those of other related libraries like Jed Brown's CArray. Thanks, Alberto Bulat Ziganshin wrote:
Hello Alberto,
Tuesday, June 3, 2008, 12:56:50 PM, you wrote:
Good! So you can easily "hide" the IO operations in the ST monad. I will definitely look into it.
from implementation POV ST monad is nothing but renamed IO monad which exports only subset of its operations which are guaranteed to safe. or, saying in other words, it's just type hackery around IO monad that provides safe operations
it's possible to define ST monad and its operations as following:
newtype ST s a = forall s. ST_Constructor (IO a)
unsafeIOtoSt action = ST_Constructor action
runST (ST_Constructor action) = unsafePerformIO action
newtype STRef s a = forall s. STRef (IORef a)
readSTRef (STRef ref) = unsafeIOtoSt (readIORef ref)
and so on. GHC uses technically (but not ideologically!) different implementation where both monads are specializations of one generic type. while Hugs afair uses exactly this approach. you may also look at ArrayRef lib which reimplements arrays/refs for both compilers in more unified way
anyway, because ST is just IO monad modulo type tricks, you can execute any IO action inside ST by lifting it with unsafeIOtoSt

Thanks, that's exactly what i was looking for.
On Thu, Jun 5, 2008 at 8:16 AM, Alberto Ruiz
Hello Bulat and Anatoly,
I have written a first version of an interface to inplace updates in the ST monad for the hmatrix vectors and matrices. Many things must be improved (range checking, documentation, etc.) but I hope that the general idea makes sense.
A few usage examples:
http://perception.inf.um.es/~aruiz/darcs/hmatrix/examples/inplace.hs
Code:
http://perception.inf.um.es/~aruiz/darcs/hmatrix/lib/Data/Packed/ST.hs
http://perception.inf.um.es/~aruiz/darcs/hmatrix/doc/html/Data-Packed-ST.htm...
Any suggestion will be welcome. I'm impressed by the power of the ST monad, it is extremely useful and elegant. Thank you again for your help!
In the future I will also try to include efficient conversions to/from standard Haskell arrays and those of other related libraries like Jed Brown's CArray.
Thanks,
Alberto
Bulat Ziganshin wrote:
Hello Alberto,
Tuesday, June 3, 2008, 12:56:50 PM, you wrote:
Good! So you can easily "hide" the IO operations in the ST monad. I will definitely look into it.
from implementation POV ST monad is nothing but renamed IO monad which exports only subset of its operations which are guaranteed to safe. or, saying in other words, it's just type hackery around IO monad that provides safe operations
it's possible to define ST monad and its operations as following:
newtype ST s a = forall s. ST_Constructor (IO a)
unsafeIOtoSt action = ST_Constructor action
runST (ST_Constructor action) = unsafePerformIO action
newtype STRef s a = forall s. STRef (IORef a)
readSTRef (STRef ref) = unsafeIOtoSt (readIORef ref)
and so on. GHC uses technically (but not ideologically!) different implementation where both monads are specializations of one generic type. while Hugs afair uses exactly this approach. you may also look at ArrayRef lib which reimplements arrays/refs for both compilers in more unified way
anyway, because ST is just IO monad modulo type tricks, you can execute any IO action inside ST by lifting it with unsafeIOtoSt

Good work, Alberto. hmatrix looks like a good solution answer to some of the nested arrays questions we have in Haskell aruiz:
Hello Bulat and Anatoly,
I have written a first version of an interface to inplace updates in the ST monad for the hmatrix vectors and matrices. Many things must be improved (range checking, documentation, etc.) but I hope that the general idea makes sense.
A few usage examples:
http://perception.inf.um.es/~aruiz/darcs/hmatrix/examples/inplace.hs
Code:
http://perception.inf.um.es/~aruiz/darcs/hmatrix/lib/Data/Packed/ST.hs
http://perception.inf.um.es/~aruiz/darcs/hmatrix/doc/html/Data-Packed-ST.htm...
Any suggestion will be welcome. I'm impressed by the power of the ST monad, it is extremely useful and elegant. Thank you again for your help!
In the future I will also try to include efficient conversions to/from standard Haskell arrays and those of other related libraries like Jed Brown's CArray.
Thanks,
Alberto
Bulat Ziganshin wrote:
Hello Alberto,
Tuesday, June 3, 2008, 12:56:50 PM, you wrote:
Good! So you can easily "hide" the IO operations in the ST monad. I will definitely look into it.
from implementation POV ST monad is nothing but renamed IO monad which exports only subset of its operations which are guaranteed to safe. or, saying in other words, it's just type hackery around IO monad that provides safe operations
it's possible to define ST monad and its operations as following:
newtype ST s a = forall s. ST_Constructor (IO a)
unsafeIOtoSt action = ST_Constructor action
runST (ST_Constructor action) = unsafePerformIO action
newtype STRef s a = forall s. STRef (IORef a)
readSTRef (STRef ref) = unsafeIOtoSt (readIORef ref)
and so on. GHC uses technically (but not ideologically!) different implementation where both monads are specializations of one generic type. while Hugs afair uses exactly this approach. you may also look at ArrayRef lib which reimplements arrays/refs for both compilers in more unified way
anyway, because ST is just IO monad modulo type tricks, you can execute any IO action inside ST by lifting it with unsafeIOtoSt
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Alberto Ruiz
-
Anatoly Yakovenko
-
Bulat Ziganshin
-
Don Stewart