Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
hello i am trying to learn ocaml by myself and i am implementing matrix multiplication of list of lists, but i have no clue on how to do it. i am trying to do it without any list functions but it seems like most solutions i have come across use list.map.
this is how i implemented add
let rec m_row r1 r2 =
match r1,r2 with
_ -> []
| r1s :: r1', r2s :: r2' -> r1s + r2s :: m_row r1' r2'
let rec m_add x y =
match x,y with
_ -> []
| xs :: x', ys :: y' -> m_row xs ys :: m_add x' y'
You have to split your task into small subtasks and then combine them to get the final program. But before starting coding we have to understand the problem. We represent a matrix as a collection of rows, e.g., a matrix with M rows and N columns is represented as,
[[a11; ...; a1N];
[a21; ...; a2N];
...
[aM1; ...; aMN]]
Given some PxQ matrix B,
[[b11; ...; b1Q];
[b21; ...; b2Q];
...
[bP1; ...; bPQ]]
we would like to form an MxQ matrix C that is the multiplication of matrices A and B,
[[c11; ...; c1Q];
[c21; ...; c2Q];
...
[cM1; ...; cMQ]]
where each element cIJ of the matrix is a cartesian product of row I of the matrix A and column J of the matrix B.
We can conclude that we will need the following primitives to solve our task.
val transpose : matrix -> matrix the function that will take a list of rows and return a list of columns of that matrix. We will need this because we need to iterate over columns of matrix B.
val product : vector -> vector -> scalar that we will use to take a row of matrix A and a column of matrix B to obtain an element of matrix C. The product of [x1; ...; xS] and [y1; ...; yS] is a scalar equal to x1 * y1 + ... + xS * yS
Note that I introduce type aliases here, e.g., we can define them as
type scalar = int
type vector = scalar list
type matrix = vector list
Now we are getting close to the final matrix multiplication procedure. To get a row of the matrix C, we need to iterate over columns of B' (where B' is a transposed matrix B), e.g., map (product row) columns, where columns is a list of column vectors, which is essentially our matrix B'. Therefore our final matrix C is,
[map (product r1) columns;
map (product r2) columns;
....
map (product rM) columns]
which, is a mapping of rows of the matrix A (which is essentially the representation of our matrix A),
let mul matA matB =
let columns = transpose matB in
map (fun row -> map (product row) columns) matA
where map f [x1; ...; xM] is defined as [f x1; ...; f xM]
Related
I am having trouble understanding a method to implement a power function in SML using only iteration and multiplication.
my iteration is the following:
fun iterate 0 f x = x
| iterate n f x = iterate (n-1) f (f x);
while my multiplication is basically iterating recursively
fun multiply 0 f = 0
| multiply f x = iterate x (fn x => x + 1) (multiply x (f-1));
Power function would basically be an iteration of the multiplication of the same base but I don't know which value to decrement
power n f = iterate (mult n n) (fn x => x + 1) (power (n) (f-1))
which is definately wrong
power n f = iterate (mult n n) (fn x => x + 1) (power (n) (f-1))
So, when it comes to naming, I might definitely write power x y or power i j or power x n or some such, since x, y, i, j or n look like they're numbers or integers, whereas f looks like it's a function. So right off the bat you have:
fun power x y = iterate (...a...) (...b...) (...c...)
As for what goes into each of these three parts, ...a..., ...b... and ...c...:
a. The thing iterate calls n, which is the number of times to iterate.
b. The thing iterate calls f, which is the function to apply each time.
c. The thing iterate calls x, which is what is applied each time.
As elaborated on in How to make a multiplication function using just addition function and iterate function in SML, there is no point in making power call itself; the point of using iterate is to hand over recursion to this list-combinator rather than use explicit recursion (where power has a reference to itself somewhere in its definition).
I can't understand a proper answer for these question. does anyone can help me for:
"Our formulation of matrix-vector multiplication assumed that
the matrix M was square. Generalize the algorithm to the case where M is an
r-by-c matrix for some number of rows r and columns c."
I think what it's stating is that a square matrix-vector multiplication is
r-by-r . r-by-1 = M . V
Because a vector only has 1 column and where r is the size of the square (rows and columns) matrix. So to generalise this to a matrix M with r rows and c columns we have
r-by-c . c-by-1 = r-by-1 = M . V
Where V is a vector of length c, or in other words, a c-by-1 matrix
Working with a self-made definition of a (9x9) matrix described as a list of lists of Maybe Ints. I want to create a function that returns the 9 columns of the matrix. I want to do this something like:
cols :: Matrix a -> [Block a]
cols matrix = map (!! n) matrix
where
n = (the values 1 .. 9)
Matrix is described as [Rows] or [[values]]
Block is described as [a]
So I want the output to be a list of lists, where those lists are a list of the first elements of the rows, the second elements of the rows, etc etc.
I see that
map (!! 1) matrix
will return a list of the second elements of the rows, ie the second column of the matrix; but I don't know how to extend this to all the columns of the matrix in a nice function.
I see that
map (!! 1) matrix
Will return a list of the second elements of the rows, ie the second column of the matrix; but I don't know how to extend this to all the columns of the matrix in a nice function.
If this is the way you want to go, you could simply change this to
map (!!i) matrix
in
[map (!!i) matrix | i <- [0.. length (matrix!!0) - 1]]
For example
Prelude> let matrix = [[1,2,3],[4,5,6]]
Prelude> [map (!!i) matrix | i <- [0.. length (matrix!!0) - 1]]
[[1,4],[2,5],[3,6]]
Of course the problem with this is that the complexity is unnecessarily high, as the complexity of !! is linear in its argument. Instead, you could build a recursive function as follows:
Suppose you split each of the elments of matrix to head and tail, respectively
Where do the head of all of the elements of fit in the transposed matrix?
What happens if you now try the same thing on the tail of all of the elements?
If I understand it correctly, you want to calculate the transpose :: [[a]] -> [[a]] of the matrix:
import Data.List(transpose)
cols :: [[a]] -> [[a]]
cols = transpose
You can implement this in an efficient way as follows:
cols :: [[a]] -> [[a]]
cols [] = []
cols ([]:_) = []
cols l = (map head l) : cols (map tail l)
This code works only for rectangular matrices. The code works as follows: if we give cols an empty list, or a list where the first row is empty, than we reached the end of the transpose, so we return an empty list.
If on the other hand there is still a list, and the first row contains one element (and since the matrix is square so do the other), we first take the head of all the rows as the column, and then perform recursion on the tails of the rows to calculate the remaining columns.
The function works in O(n) with n the number of elements (not rows/columns) of the matrix. Or O(r×c) with r the number of rows and c the number of columns.
I'm learning functional programming (in Haskell) by re-writing some of my old C++ code. One example I'm working on involves the Floyd-Warshall graph search which runs on a 2D NxN adjacency matrix to find the shortest path between all pairs. It uses three nested for loops to scan the 2D array and iteratively reach a solution.
The C++ code would typically be:
int size = adjacencyMatrix.size();
for ( int k = 0; k < size; k++)
{
for ( int i = 0; i < size; i++)
{
for ( int j = 0; j < size; j++)
{
double sum = adjacencyMatrix[i][k] + adjacencyMatrix[k][j];
if ( sum < adjacencyMatrix[i][j] )
{
adjacencyMatrix[i][j] = sum;
}
}
}
}
The key to such a graph search is its iterative method. For example the code above is very sequential; it can only be parallelised to a moderate extent as some calculations can't be done till others have completed.
Furthermore, having access to the index of the matrix means some clever manipulations within the array can be done. The innermost loop of the above graph search uses adjacencyMatrix[i][k], adjacencyMatrix[k][j] and adjacencyMatrix[i][j]. I'm aware of the map function in Haskell, but that doesn't seem to have the same power and flexibility as using array indices.
Aside from trying to simulate an imperative procedure in Haskell I can't work out how re-write the above code in a 'pure' functional style.
How does an iterative procedure that uses complex nested loops to access array indices, such as the graph search above, translate to the functional paradigm?
Aside from trying to simulate an imperative procedure in Haskell I can't work out how re-write the above code in a 'pure' functional style.
I'm not sure you can always rewrite a fundamentally imperative algorithm in a functional style. That said, here's how one would translate your example in Haskell. Note that in general, whenever you find yourself really needing to have mutable variables for a bit, you probably want to use the ST monad. For arrays, you have the efficient array package.
Here's what a full translation of that algorithm can look like
import Data.Array.Unboxed (UArray)
import Data.Array.ST (runSTUArray, newListArray, readArray, writeArray)
import Data.Maybe (fromMaybe)
import Control.Monad (when)
import Data.Foldable (for_)
-- | Takes as input the number of vertices, function to weigh edges, and returns
-- a matrix of the shortest distance between every two vertices.
floydWarshall :: Int -> ((Int,Int) -> Maybe Double) -> UArray (Int,Int) Double
floydWarshall n weight = runSTUArray $ do
-- initialize the array with the right values
arr <- newListArray ((0,0),(n-1,n-1))
[ if i == j then 0 else fromMaybe (1 / 0) (weight (i,j))
| i<-[0..(n-1)], j<-[0..(n-1)] ]
-- iteratively improve the shortest distances
for_ [0..(n-1)] $ \k ->
for_ [0..(n-1)] $ \i ->
for_ [0..(n-1)] $ \j -> do
arr_ik <- readArray arr (i,k)
arr_kj <- readArray arr (k,j)
arr_ij <- readArray arr (i,j)
let sum = arr_ik + arr_kj
when (sum < arr_ij)
(writeArray arr (i,j) sum)
return arr
The best option is to use Data.Vector package and use ifoldl with nested imaps which will look like this:
{-# LANGUAGE OverloadedLists #-}
import Data.Vector
type Matrix a = Vector (Vector a)
floydwarshall mat = ifoldl (\m k _ ->
imap (\i row ->
imap (\j v ->
(m!i!k + m!k!j) `min` v) row) m) mat mat
Ifoldl and imap alongside values stored inside vector maps using their indices, which allows you to call values at specific index. The foldl is needed to accumulate all the changes in iterations of k while keeping structure immutable. Inside of imaps you must index inside matrix m which is our accumulator for foldr and which keeps all changes.
If you don't want to import packages, you may always implement imap and ifoldl for stock prelude lists
imap :: (Int -> a -> b) -> [a] -> [b]
imap f = map (uncurry f) . zip [0,1..]
ifoldl :: (b -> Int -> a -> b) -> b -> [a] -> b
ifoldl f acc = foldl (\ac -> uncurry (f ac)) acc . zip [0,1..]
EDITED: According to suggestion by #chi
How to compute the product of two polynomials ?
For example: x^3 + 3x^2 +0.2x and 2x^4 + 3
First I made a type
Type term = {coefficient:int; name:string; exponent:int};;
Type polynomials = term list;;
then I made a function calculate coefficient
let product l l' =
List.concat (List.map (fun e -> List.map (fun e' -> (e*e')) l'.coefficient)
l.coefficient);;
This is where I get stuck. I guess I can use the same function for exponent as well,but the question is asking writing a polynomials function with one param, which means two polynomials will be in the same variable
Can someone help me out here
You seem to be saying that you're asked to write a function to multiply two polynomials, but the function is supposed to have just one parameter. This, indeed, doesn't make a lot of sense.
You can always use a tuple to bundle any number of values into a single value, but there's no reason to do this (that I can see), and it's not idiomatic for OCaml.
Here's a function with one parameter (a pair) that multiplies two ints:
# let multiply (a, b) = a * b;;
val multiply : int * int -> int = <fun>
# multiply (8, 7);;
- : int = 56
(As a separate comment, the code you give doesn't compile.)