Strongly typed matrices in F# - matrix

Is it possible to create a wrapper over the F# PowerPack matrix library to create strongly typed matrices and vectors?
What I mean is I want to store the dimentionality of the matrix/vector in the type itself so that I can say
Create a function mul to multiply 2 matrices with the signature:
mul :: Matrix<float, n, m> -> Matrix<float, m, p> -> Matrix<float, n, p>
where the latter 2 arguments to the Matrix type represent the number of rows and cols and are ints.

The problem here is that n and m are values of ints, whilst type arguments need to be types.
A somewhat hackish solution would be to use a measure type for height and width. Then it could become:
mull :: Matrix<float<(H^m)*(W^n)>> -> Matrix<float<H^m*W^p>> -> Matrix<float<H^n,W^p>>
where H and W are measure types enccoding height and width respectively
[<Measure>] type H
[<Measure>] type W

Related

How to implement This MP problem in ECLIPSE CLP or Prolog?

I want to implement this Summations as Objective and Constraints(1-6)
Could anyone help me that how I can Implement them?
OBJ: Min ∑(i=1..N)∑(j=1..N) Cij * ∑(k=1..K)Xijk
constraint :
∑(k=1..K) Yik=1 (for all i in N)
The following answer is specific to ECLiPSe (it uses loops, array and array slice notation, which are not part of standard Prolog).
I assume that N and K (and presumably C) are given, and your matrices are declared as
dim(C, [N,N]),
dim(X, [N,N,K]),
dim(Y, [N,K]),
You can then set up the constraints in a loop:
constraint : ∑(k=1..K) Yik=1 (for all i in N)
( for(I,1,N), param(Y) do
sum(Y[I,*]) $= 1
),
Note that the notation sum(Y[I,*]) here is a shorthand for sum([Y[I,1],Y[I,2],...,Y[I,K]]) when K is the size of this array dimension.
For your objective, because of the nested sum, an auxiliary loop/list is still necessary:
OBJ: Min ∑(i=1..N)∑(j=1..N) Cij * ∑(k=1..K)Xijk
( multifor([I,J],1,N), foreach(Term,Terms), param(C,X) do
Term = (C[I,J] * sum(X[I,J,*]))
),
Objective = sum(Terms),
...
You then have to pass this objective expression to the solver -- the details depend on which solver you use (e.g. eplex, ic).

Constant shape error in simple code

I have an error with this code and I don't understand why
-"The module or main program array 'u' at (1) must have constant shape."
-Moreover, how can I do this code with a choice of parameters, I mean [U]=vector(N) where I can chose N and it returns me U.
program vector
!declaration
implicit none
integer :: n
integer, parameter :: N=10
real, dimension(N,1) :: U
do n=1,N
U(1,N)=n
end do
print*,U
end program vector
First up, Fortran is caseINsensitive, so n and N are the same thing, and you can't declare two different variables/parameters n and N.
Then you declare U to have shape (N, 1), but seem to use it in the form (1, N).
As for how to auto-generate something like U, you could use something like this:
function vector(n) result(v)
integer, intent(in) :: n
integer :: v(n)
integer :: i
v = [ (i, i=1, n) ]
return
end function vector
One more thing:
You declare U with dimension(1, N) which creates a 2D array with one dimension having length 1. I'm wondering whether you wanted to create a 1D array with range from 1 to N, for which the declaration would need to be dimension(1:N) (or, since Fortran assumes indices start at 1, just dimension(N)).
Addressing the questions in your comment:
The purpose of intent(in) tells the compiler that n is only read, not written to, in this function. Considering that you want to use n as the size of array v, you want that.
With result(v) I tell the compiler that I want to use the name v to refer to the result of the function, not the default (which is the function name). I do this to avoid confusion.
integer :: v(n) is the same as integer, dimension(n) :: v

A concise way to access an element of a set in pseudocode

Let networklocs be a set of elements of the form (n, t, l) where n is a node in the network, t is a clock tick and l is the location of n at time t. How can I get (in a concise way in pseudo-code) the element of networklocs where node and time is given?
I know I can write a function like
getElement(ni,t)
for all (nj,t',l') in networklocs
if nj=ni and t'= t then return (nj,t',l')
But is there a more concise way to access an element of the set networklocs in the pseudo-code?
Note that I would like to keep networklocs as a set, so solutions with maps or arrays do not fit.
Note that returning ni and t is useless because they're already known. In notation and practice, you'd want
Let M be a map: <N, T> -> L
The operation you want is just a map lookup:
l <- M <n, t>
Although the map is the most likely notation, a predicate logic expression can also be used:
Let get(n,t) be x = <n, t, l> | x \in networklocs
The loop you provided as an example is neither correct nor pseudocode. It's a concrete implementation of a map, and it doesn't say what to do when the key is not found.

Image Neighbourhood Processing in Haskell

I'm new to Haskell, and trying to learn it by thinking in terms of image processing.
So far, I have been stuck thinking about how you would implement a neighbourhood-filtering algorithm in Haskell (or any functional programming language, really).
How would a spatial averaging filter (say 3x3 kernel, 5x5 image) be written functionally? Coming from an entirely imperative background, I can't seem to come up with a way to either structure the data so the solution is elegant, or not do it by iterating through the image matrix, which doesn't seem very declarative.
Working with neighborhoods is easy to do elegantly in a functional language. Operations like convolution with a kernel are higher order functions that can be written in terms of one of the usual tools of functional programming languages - lists.
To write some real, useful code, we'll first play pretend to explain a library.
Pretend
You can think of each image as a function from a coordinate in the image to the value of the data held at that coordinate. This would be defined over all possible coordinates, so it would be useful to pair it with some bounds which tell us where the function is defined. This would suggest a data type like
data Image coordinate value = Image {
lowerBound :: coordinate,
upperBound :: coordinate,
value :: coordinate -> value
}
Haskell has a very similar data type called Array in Data.Array. This data type comes with an additional feature that the value function in Image wouldn't have - it remembers the value for each coordinate so that it never needs to be recomputed. We'll work with Arrays using three functions, which I'll describe in terms of how they'd be defined for Image above. This will help us see that even though we are using the very useful Array type, everything could be written in terms of functions and algebraic data types.
type Array i e = Image i e
bounds gets the bounds of the Array
bounds :: Array i e -> (i, i)
bounds img = (lowerBound img, upperBound img)
The ! looks up a value in the Array
(!) :: Array i e -> i -> e
img ! coordinate = value img coordinate
Finally, makeArray builds an Array
makeArray :: Ix i => (i, i) -> (i -> e) -> Array i e
makeArray (lower, upper) f = Image lower upper f
Ix is a typeclass for things that behave like image coordinates, they have a range. There are instances for most of the base types like Int, Integer, Bool, Char, etc. For example the range of (1, 5) is [1, 2, 3, 4, 5]. There's also an instances for products or tuples of things that themselves have Ix instances; the instance for tuples ranges over all combinations of the ranges of each component. For example, range (('a',1),('c',2)) is
[('a',1),('a',2),
('b',1),('b',2),
('c',1),('c',2)]`
We are only interested in two functions from the Ix typeclass, range :: Ix a => (a, a) -> [a] and inRange :: Ix a => a -> (a, a) -> Bool. inRange quickly checks if a value would be in the result of range.
Reality
In reality, makeArray isn't provided by Data.Array, but we can define it in terms of listArray which constructs an Array from a list of items in the same order as the range of its bounds
import Data.Array
makeArray :: (Ix i) => (i, i) -> (i -> e) -> Array i e
makeArray bounds f = listArray bounds . map f . range $ bounds
When we convolve an array with a kernel, we will compute the neighborhood by adding the coordinates from the kernel to the coordinate we are calculating. The Ix typeclass doesn't require that we can combine two indexes together. There's one candidate typeclass for "things that combine" in base, Monoid, but there aren't instances for Int or Integer or other numbers because there's more than one sensible way to combine them: + and *. To address this, we'll make our own typeclass Offset for things that combine with a new operator called .+.. Usually we don't make typeclasses except for things that have laws. We'll just say that Offset should "work sensibly" with Ix.
class Offset a where
(.+.) :: a -> a -> a
Integers, the default type Haskell uses when you write an integer literal like 9, can be used as offsets.
instance Offset Integer where
(.+.) = (+)
Additionally, pairs or tuples of things that Offset can be combined pairwise.
instance (Offset a, Offset b) => Offset (a, b) where
(x1, y1) .+. (x2, y2) = (x1 .+. x2, y1 .+. y2)
We have one more wrinkle before we write convolve - how will we deal with the edges of the image? I intend to pad them with 0 for simplicity. pad background makes a version of ! that's defined everywhere, outside the bounds of an Array it returns the background.
pad :: Ix i => e -> Array i e -> i -> e
pad background array i =
if inRange (bounds array) i
then array ! i
else background
We're now prepared to write a higher order function for convolve. convolve a b convolves the image b with the kernel a. convolve is higher order because each of its arguments and its result is an Array, which is really a combination of a function ! and its bounds.
convolve :: (Num n, Ix i, Offset i) => Array i n -> Array i n -> Array i n
convolve a b = makeArray (bounds b) f
where
f i = sum . map (g i) . range . bounds $ a
g i o = a ! o * pad 0 b (i .+. o)
To convolve an image b with a kernel a, we make a new image defined over the same bounds as b. Each point in the image can be computed by the function f, which sums the product (*) of the value in the kernel a and the value in the padded image b for each offset o in the range of the bounds of the kernel a.
Example
With the six declarations from the previous section, we can write the example you requested, a spatial averaging filter with a 3x3 kernel applied to a 5x5 image. The kernel a defined below is a 3x3 image that uses one ninth of the value from each of the 9 sampled neighbors. The 5x5 image b is a gradient increasing from 2 in the top left corner to 10 in the bottom right corner.
main = do
let
a = makeArray ((-1, -1), (1, 1)) (const (1.0/9))
b = makeArray ((1,1),(5,5)) (\(x,y) -> fromInteger (x + y))
c = convolve a b
print b
print c
The printed input b is
array ((1,1),(5,5))
[((1,1),2.0),((1,2),3.0),((1,3),4.0),((1,4),5.0),((1,5),6.0)
,((2,1),3.0),((2,2),4.0),((2,3),5.0),((2,4),6.0),((2,5),7.0)
,((3,1),4.0),((3,2),5.0),((3,3),6.0),((3,4),7.0),((3,5),8.0)
,((4,1),5.0),((4,2),6.0),((4,3),7.0),((4,4),8.0),((4,5),9.0)
,((5,1),6.0),((5,2),7.0),((5,3),8.0),((5,4),9.0),((5,5),10.0)]
The convolved output c is
array ((1,1),(5,5))
[((1,1),1.3333333333333333),((1,2),2.333333333333333),((1,3),2.9999999999999996),((1,4),3.6666666666666665),((1,5),2.6666666666666665)
,((2,1),2.333333333333333),((2,2),3.9999999999999996),((2,3),5.0),((2,4),6.0),((2,5),4.333333333333333)
,((3,1),2.9999999999999996),((3,2),5.0),((3,3),6.0),((3,4),7.0),((3,5),5.0)
,((4,1),3.6666666666666665),((4,2),6.0),((4,3),7.0),((4,4),8.0),((4,5),5.666666666666666)
,((5,1),2.6666666666666665),((5,2),4.333333333333333),((5,3),5.0),((5,4),5.666666666666666),((5,5),4.0)]
Depending on the complexity of what you want to do, you might consider using more established libraries, like the oft recommended repa, rather than implementing an image processing kit for yourself.

Pseudo random number generator from two inputs

I need a pseudo random number generator that gives me a number from the range [-1, 1] (range is optional) from two inputs of the type float.
I'll also try to explain why I need it:
I'm using the Diamond-Square algorithm to create a height map for my terrain engine. The terrain is split into patches (Chunked LOD).
The problem with Diamond-Square is that it uses the random function, so let's say two neighbor patches are sharing same point (x, z) then I want the height to be the same for them all so that I won't get some crack effect.
Some may say I could fetch the height information from the neighbor patch, but then the result could be different after which patch was created first.
So that's why I need a pseudo number generator that returns an unique number given two inputs which are the (x, z).
(I'm not asking someone to write such function, I just need a general feedback and or known algorithms that do something similar).
You need something similar to a hash function on the pair (x, z).
I would suggest something like
(a * x + b * z + c) ^ d
where all numbers are integers, a and b are big primes so that the integer multiplications overflow, and c and d are some random integers. ^ is bitwise exclusive or. The result is a random integer which you can scale to the desired range.
This assumes that the map is not used in a game where knowing the terrain is of substantial value, as such a function is not secure for keeping it a secret. In that case you'd better use some cryptographic function.
If you're looking for a bijection from IRxIR -> [-1;1], I can suggest this:
bijection from IR to ]-a:a[
First let's find a bijection from IR-> ]-1;1[ so we just need to find a bijection from IRxIR->IR
tan(x): ]-Pi/2;Pi/2[ -> IR
arctan(x) : IR -> ]-Pi/2;Pi/2[
1/Pi*arctan(x) + 1/2: IR -> ]0;1[
2*arctan(x) : IR->]-Pi:Pi[
and
ln(x) : IR + -> IR
exp(x): IR -> R+
Bijection from ]0,1[ x ]0,1[ -> ]0,1[
let's write:
(x,y) in ]0,1[ x ]0,1[
x= 0,x1x2x3x4...xn...etc where x1x2x3x4...xn represent the decimals of x in base 10
y=0,y1y2y3y4...ym...etc idem
Let's define z=0,x1y1x2y2xx3y3....xnyn...Oym in ]0,1[
Then by construction we can provethere that it is exact bijection from ]0,1[ x ]0,1[ to ]0,1[.
(i'm not sure it's is true for number zith infinite decimals..but it's at least a "very good" injection, tell me if i'm wrong)
let's name this function : CANTOR(x,y)
then 2*CANTOR-1 is a bijection from ]0,1[ x ]0,1[ -> ]-1,1[
Then combining all the above assertions:
here you go, you get the bijection from IRxIR -> ]-1;1[...
You can combine with a bijection from IR-> ]0,1[
IRxIR -> ]-1;1[
(x,y) -> 2*CANTOR(1/Pi*arctan(x) + 1/2,1/Pi*arctan(y) + 1/2)-1
let's define the reciproque, we process the same way:
RCANTOR: z -> (x,y) (reciproque of CANTOR(x,y)
RCANTOR((z+1)/2): ]-1:1[ -> ]01[x ]0,1[
then 1/Pi*tan(RCANTOR((z+1)/2)) + 1/2 : z ->(x,y)
]-1;1[ -> IRxIR
Just pick any old hash function, stick in the binary description of the coordinates and use the output.

Resources