X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.runtime%2Fscl%2FVector.scl;fp=bundles%2Forg.simantics.scl.runtime%2Fscl%2FVector.scl;h=51ec078b62126f48a646842d6a416a5106462db4;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.runtime/scl/Vector.scl b/bundles/org.simantics.scl.runtime/scl/Vector.scl new file mode 100644 index 000000000..51ec078b6 --- /dev/null +++ b/bundles/org.simantics.scl.runtime/scl/Vector.scl @@ -0,0 +1,173 @@ +import "Prelude" +import "IterN" + +infixl 7 (**), dotp + +importJava "java.lang.System" where + @JavaName arraycopy + copyFromVector :: Vector a -> Integer -> MVector a -> Integer -> Integer -> () + + @JavaName arraycopy + copyFromMVector :: MVector a -> Integer -> MVector a -> Integer -> Integer -> () + +@inline +mvector :: VecComp a => [a] -> MVector a +mvector l = do + len = length l + result = createMVector len + iterIList (setMVector result) l + result + +@inline +vector :: VecComp a => [a] -> Vector a +vector l = runProc (freezeMVector (mvector l)) + +@inline +vectorF :: VecComp a => Integer -> (Integer -> a) -> Vector a +vectorF l f = runProc do + result = createMVector l + forN l $ \i -> setMVector result i (f i) + freezeMVector result + +@inline +singletonVector :: VecComp a => a -> Vector a +singletonVector v = runProc do + result = createMVector 1 + setMVector result 0 v + freezeMVector result + +@inline +@private +subVector :: Vector a -> Integer -> Integer -> Vector a +subVector src begin end = runProc do + len = end-begin + result = createMVectorProto src len + copyFromVector src begin result 0 len + freezeMVector result + +@inline +concatVector :: Vector a -> Vector a -> Vector a +concatVector a b = runProc do + lenA = lengthVector a + lenB = lengthVector b + result = createMVectorProto a (lenA + lenB) + copyFromVector a 0 result 0 lenA + copyFromVector b 0 result lenA lenB + freezeMVector result + +@inline +mapVector :: VecComp a => VecComp b => (a -> b) -> Vector a -> Vector b +mapVector f a = vectorF (length a) (\i -> f (a!i)) + +@inline +zipVectorsWith :: VecComp a => VecComp b => VecComp c => (a -> b -> c) -> Vector a -> Vector b -> Vector c +zipVectorsWith f a b = vectorF (length a) (\i -> f (a!i) (b!i)) + +instance (VecComp a, Additive a) => Additive (Vector a) where + @inline + zero = runProc (freezeMVector (createMVector 0)) + @inline + a + b = runProc do + lenA = lengthVector a + lenB = lengthVector b + if lenA < lenB + then do + result = createMVectorProto a lenB + forN lenA $ \i -> setMVector result i (a!i + b!i) + copyFromVector b lenA result lenA (lenB-lenA) + freezeMVector result + else if lenA > lenB + then do + result = createMVectorProto a lenA + forN lenB $ \i -> setMVector result i (a!i + b!i) + copyFromVector a lenB result lenB (lenA-lenB) + freezeMVector result + else do + result = createMVectorProto a lenA + forN lenA $ \i -> setMVector result i (a!i + b!i) + freezeMVector result + +instance (VecComp a, Ring a) => Ring (Vector a) where + @inline + a - b = runProc do + lenA = lengthVector a + lenB = lengthVector b + if lenA < lenB + then do + result = createMVectorProto a lenB + forN lenA $ \i -> setMVector result i (a!i - b!i) + forN (lenB-lenA) $ \i -> setMVector result (lenA+i) (- b!(lenA+i)) + freezeMVector result + else if lenA > lenB + then do + result = createMVectorProto a lenA + forN lenB $ \i -> setMVector result i (a!i - b!i) + copyFromVector a lenB result lenB (lenA-lenB) + freezeMVector result + else do + result = createMVectorProto a lenA + forN lenA $ \i -> setMVector result i (a!i - b!i) + freezeMVector result + @inline + neg = mapVector (\x -> -x) + one = fail "Unsupported operation one for Vector" + (*) = fail "Unsupported operation (*) for Vector" + fromInteger = fail "Unsupported operation fromInteger for Vector" + +@inline +dotp :: Ring a => VecComp a => Vector a -> Vector a -> a +dotp a b = foldlN (\sum i -> sum + a!i * b!i) 0 (min (length a) (length b)) + +@inline +normSq a = foldlN (\sum i -> do v = a!i ; sum + v*v) 0 (length a) + +@inline +norm a = sqrt (normSq a) + +maxNorm a = foldlN (\cur i -> max cur (abs (a!i))) 0 (length a) + +l1Norm a = foldlN (\cur i -> cur + abs (a!i)) 0 (length a) + +@inline +(**) :: Ring a => VecComp a => a -> Vector a -> Vector a +s ** a = mapVector (\x -> s*x) a + +instance (Show a, VecComp a) => Show (Vector a) where + s <+ v = s << "vector " <+ [v!i | i <- [0..lengthVector v-1]] + +instance (VecComp a) => Sequence (Vector a) where + @inline + length = lengthVector + @inline + sub = subVector + +instance IndexedSequence Vector where + (!) = getVector + +@inline +iterVector :: (a -> b) -> Vector a -> () +iterVector f v = forN (lengthVector v) (\i -> f (getVector v i)) + +@inline +foldlVector :: (a -> b -> a) -> a -> Vector b -> a +foldlVector f initial v = foldlN (\cur i -> f cur (getVector v i)) initial (lengthVector v) + +@inline +anyVector :: (a -> Boolean) -> Vector a -> Boolean +anyVector f v = anyN (\i -> f (getVector v i)) (lengthVector v) + +@inline +allVector :: (a -> Boolean) -> Vector a -> Boolean +allVector f v = allN (\i -> f (getVector v i)) (lengthVector v) + +@inline +mapFirstVector :: (a -> Maybe b) -> Vector a -> Maybe b +mapFirstVector f v = mapFirstN (\i -> f (getVector v i)) (lengthVector v) + +@inline +containsVector :: Eq a => a -> Vector a -> Boolean +containsVector x v = foldlN (\result i -> result || (v!i == x)) False (lengthVector v) + +@inline +vectorToList :: Vector a -> [a] +vectorToList v = foldlN (\l i -> addList l (v ! i)) [] (lengthVector v)