<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Matrix Operations</title>
	<atom:link href="http://programmingpraxis.com/2010/06/22/matrix-operations/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingpraxis.com/2010/06/22/matrix-operations/</link>
	<description>A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmer</description>
	<lastBuildDate>Mon, 28 May 2012 03:30:45 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Dmitriy Borodiy</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-3958</link>
		<dc:creator><![CDATA[Dmitriy Borodiy]]></dc:creator>
		<pubDate>Tue, 06 Dec 2011 14:42:04 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-3958</guid>
		<description><![CDATA[My Python solution with convenient operators overloading, though not very effective:

[sourcecode lang=&quot;python&quot;]
class Matrix:
	def __init__(self, rows):
		if not isinstance(rows, list) or \
		not isinstance(rows[0], list) or \
		len(rows) == 0 or len(rows[0]) == 0:
			raise ValueError
		self.rows, self.cols = len(rows), len(rows[0])
		for row in rows:
			if len(row) != self.cols:
				raise ValueError
		self.m = list(map(list, rows))
		
	def __repr__(self):
		return &#039;\n&#039;.join(map(str, self.m))
	
	def __add__(self, other):
		data = []
		for row1, row2 in zip(self.m, other.m):
			data.append(list(map(lambda a, b: a + b, row1, row2)))
		return Matrix(data)
	
	def __mul__(self, other):
		if isinstance(self, Matrix) and isinstance(other, Matrix):
			return self.matrix_mult(other)
		else:
			return self.scalar_mult(other)

	def __rmul__(self, other):
		if isinstance(self, Matrix) and isinstance(other, Matrix):
			return self.matrix_mult(other)
		else:
			return self.scalar_mult(other)
	
	def matrix_mult(self, other):
		if self.cols != other.rows:	
			raise ValueError
		data = []
		for i in range(self.rows):
			row = []
			for j in range(other.cols):
				row.append(sum(map(lambda a: a[0]*a[1], zip(self.m[i], map(lambda l: l[j], other.m)))))
			data.append(row)
		return Matrix(data)
	
	def scalar_mult(self, scalar):
		data = []
		for row in self.m:
			data.append(list(map(lambda x: x * scalar, row)))
		return Matrix(data)
	
	def transpose(self):
		data = []
		for i in range(self.cols):
			data.append(list(map(lambda x: x[i], self.m)))
		return Matrix(data)
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Python solution with convenient operators overloading, though not very effective:</p>
<pre class="brush: python;">
class Matrix:
	def __init__(self, rows):
		if not isinstance(rows, list) or \
		not isinstance(rows[0], list) or \
		len(rows) == 0 or len(rows[0]) == 0:
			raise ValueError
		self.rows, self.cols = len(rows), len(rows[0])
		for row in rows:
			if len(row) != self.cols:
				raise ValueError
		self.m = list(map(list, rows))
		
	def __repr__(self):
		return '\n'.join(map(str, self.m))
	
	def __add__(self, other):
		data = []
		for row1, row2 in zip(self.m, other.m):
			data.append(list(map(lambda a, b: a + b, row1, row2)))
		return Matrix(data)
	
	def __mul__(self, other):
		if isinstance(self, Matrix) and isinstance(other, Matrix):
			return self.matrix_mult(other)
		else:
			return self.scalar_mult(other)

	def __rmul__(self, other):
		if isinstance(self, Matrix) and isinstance(other, Matrix):
			return self.matrix_mult(other)
		else:
			return self.scalar_mult(other)
	
	def matrix_mult(self, other):
		if self.cols != other.rows:	
			raise ValueError
		data = []
		for i in range(self.rows):
			row = []
			for j in range(other.cols):
				row.append(sum(map(lambda a: a[0]*a[1], zip(self.m[i], map(lambda l: l[j], other.m)))))
			data.append(row)
		return Matrix(data)
	
	def scalar_mult(self, scalar):
		data = []
		for row in self.m:
			data.append(list(map(lambda x: x * scalar, row)))
		return Matrix(data)
	
	def transpose(self):
		data = []
		for i in range(self.cols):
			data.append(list(map(lambda x: x[i], self.m)))
		return Matrix(data)
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Eric Pierce</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1444</link>
		<dc:creator><![CDATA[Eric Pierce]]></dc:creator>
		<pubDate>Wed, 21 Jul 2010 20:33:42 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1444</guid>
		<description><![CDATA[My Haskell solution:

[sourcecode]
-- Matrix.hs
--
-- Defines a Matrix data type and operations upon Matrices

data Matrix a = Matrix [[a]]
     deriving (Show, Eq)

-- Add two matrices together
--
--   &gt; addMatrices (Matrix [[1,2,3], [4,5,6]]) (Matrix [[2,3,4], [3,4,5]])
--   Matrix [[3,5,7], [7,9,11]]
--
addMatrices :: (Num a) =&gt; Matrix a -&gt; Matrix a -&gt; Matrix a
addMatrices (Matrix m1) (Matrix m2) = Matrix $ zipWith (zipWith (+)) m1 m2 

-- Multiply a matrix by a scalar
--
--   &gt; multScalar 2 (Matrix [[1,2,3], [4,5,6]])
--   Matrix [[2,4,6], [8,10,12]]
--
multScalar :: (Num a) =&gt; a -&gt; Matrix a -&gt; Matrix a
multScalar x (Matrix m) = Matrix $ map (map (x*)) m

-- Multiply two matrices together
--
--   &gt; multMatrices (Matrix [[1,2,3], [4,5,6]]) (Matrix [[1,2,3,4], [2,3,4,5], [3,4,5,6]])
--   Matrix [[14,20,26,32],[32,47,62,77]]
--
multMatrices :: (Num a) =&gt; Matrix a -&gt; Matrix a -&gt; Matrix a
multMatrices (Matrix m1) (Matrix m2) = Matrix $ [ map (multRow r) m2t &#124; r &lt;- m1 ]
    where (Matrix m2t) = transposeMatrix (Matrix m2)
          multRow r1 r2 = sum $ zipWith (*) r1 r2 

-- Transpose a matrix
--
--   &gt; transposeMatrix (Matrix [[1,2,3], [4,5,6]])
--   Matrix [[1,4], [2,6], [3,6]]
--
transposeMatrix :: Matrix a -&gt; Matrix a
transposeMatrix (Matrix m) = Matrix (zipList m) 

-- Zip together a list of lists. The result is truncated to the length of the
-- shortest list. This is like the builtin zip function, except it can zip
-- together an arbitrary number of lists.
zipList :: [[a]] -&gt; [[a]]
zipList lists
    -- Base cases: there are no lists, or any sub-list is empty
    &#124; length lists == 0          = [] 
    &#124; any ((==0) . length) lists = [] 
    -- Take the head from each sub-list and recurse with the tails
    &#124; otherwise                  = map head lists : zipList (map tail lists)
[/sourcecode]

Not nearly as sexy as @Remco&#039;s, partly because I used a Matrix data type that complicated things somewhat unnecessarily. I wrote zipList from scratch before remembering there was a &#039;transpose&#039; function in Data.List, but overall this was a good learning experience. I remember back when I was into C++, and I wrote some matrix classes--the header declarations alone were longer than this :-)]]></description>
		<content:encoded><![CDATA[<p>My Haskell solution:</p>
<pre class="brush: plain;">
-- Matrix.hs
--
-- Defines a Matrix data type and operations upon Matrices

data Matrix a = Matrix [[a]]
     deriving (Show, Eq)

-- Add two matrices together
--
--   &gt; addMatrices (Matrix [[1,2,3], [4,5,6]]) (Matrix [[2,3,4], [3,4,5]])
--   Matrix [[3,5,7], [7,9,11]]
--
addMatrices :: (Num a) =&gt; Matrix a -&gt; Matrix a -&gt; Matrix a
addMatrices (Matrix m1) (Matrix m2) = Matrix $ zipWith (zipWith (+)) m1 m2 

-- Multiply a matrix by a scalar
--
--   &gt; multScalar 2 (Matrix [[1,2,3], [4,5,6]])
--   Matrix [[2,4,6], [8,10,12]]
--
multScalar :: (Num a) =&gt; a -&gt; Matrix a -&gt; Matrix a
multScalar x (Matrix m) = Matrix $ map (map (x*)) m

-- Multiply two matrices together
--
--   &gt; multMatrices (Matrix [[1,2,3], [4,5,6]]) (Matrix [[1,2,3,4], [2,3,4,5], [3,4,5,6]])
--   Matrix [[14,20,26,32],[32,47,62,77]]
--
multMatrices :: (Num a) =&gt; Matrix a -&gt; Matrix a -&gt; Matrix a
multMatrices (Matrix m1) (Matrix m2) = Matrix $ [ map (multRow r) m2t | r &lt;- m1 ]
    where (Matrix m2t) = transposeMatrix (Matrix m2)
          multRow r1 r2 = sum $ zipWith (*) r1 r2 

-- Transpose a matrix
--
--   &gt; transposeMatrix (Matrix [[1,2,3], [4,5,6]])
--   Matrix [[1,4], [2,6], [3,6]]
--
transposeMatrix :: Matrix a -&gt; Matrix a
transposeMatrix (Matrix m) = Matrix (zipList m) 

-- Zip together a list of lists. The result is truncated to the length of the
-- shortest list. This is like the builtin zip function, except it can zip
-- together an arbitrary number of lists.
zipList :: [[a]] -&gt; [[a]]
zipList lists
    -- Base cases: there are no lists, or any sub-list is empty
    | length lists == 0          = [] 
    | any ((==0) . length) lists = [] 
    -- Take the head from each sub-list and recurse with the tails
    | otherwise                  = map head lists : zipList (map tail lists)
</pre>
<p>Not nearly as sexy as @Remco&#8217;s, partly because I used a Matrix data type that complicated things somewhat unnecessarily. I wrote zipList from scratch before remembering there was a &#8216;transpose&#8217; function in Data.List, but overall this was a good learning experience. I remember back when I was into C++, and I wrote some matrix classes&#8211;the header declarations alone were longer than this :-)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: erislover</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1390</link>
		<dc:creator><![CDATA[erislover]]></dc:creator>
		<pubDate>Tue, 06 Jul 2010 19:01:30 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1390</guid>
		<description><![CDATA[Interestingly I realized after writing it that I duplicated the Haskell version above in Scheme, though I put scalar multiplication into matrix multiplication. I have such a hard time reading Haskell that I couldn&#039;t notice it before! No error checking. A matrix is a list of lists.
[sourcecode lang=&quot;css&quot;]
(define transpose
  (λ(l)
    (if (empty? (first l))
        empty
        (cons (map first l)
              (transpose (map rest l))))))

(define add
  (λ(one two)
    (map (λ(x y)
           (map + x y))
         one two)))

(define times
  (λ(one two)
    (let ((sum (λ(list)
                 (foldl + 0 list))))
      (if (number? one)
          (map (λ(x) (map (λ(y) (* one y)) x)) two)
          (let ((two (transpose two)))
            (map (λ(x) (map (λ(y) (sum (map * x y))) two)) one))))))
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>Interestingly I realized after writing it that I duplicated the Haskell version above in Scheme, though I put scalar multiplication into matrix multiplication. I have such a hard time reading Haskell that I couldn&#8217;t notice it before! No error checking. A matrix is a list of lists.</p>
<pre class="brush: css;">
(define transpose
  (λ(l)
    (if (empty? (first l))
        empty
        (cons (map first l)
              (transpose (map rest l))))))

(define add
  (λ(one two)
    (map (λ(x y)
           (map + x y))
         one two)))

(define times
  (λ(one two)
    (let ((sum (λ(list)
                 (foldl + 0 list))))
      (if (number? one)
          (map (λ(x) (map (λ(y) (* one y)) x)) two)
          (let ((two (transpose two)))
            (map (λ(x) (map (λ(y) (sum (map * x y))) two)) one))))))
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: erislover</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1387</link>
		<dc:creator><![CDATA[erislover]]></dc:creator>
		<pubDate>Tue, 06 Jul 2010 04:43:16 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1387</guid>
		<description><![CDATA[Geir S: list-of-heads is just (map car m)]]></description>
		<content:encoded><![CDATA[<p>Geir S: list-of-heads is just (map car m)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Geir S</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1366</link>
		<dc:creator><![CDATA[Geir S]]></dc:creator>
		<pubDate>Mon, 28 Jun 2010 09:37:50 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1366</guid>
		<description><![CDATA[bah.. indents lost :-( 

one with proper indents on pocoo....

http://paste.pocoo.org/show/nZhGWlzvWmDhV9pRV5im/]]></description>
		<content:encoded><![CDATA[<p>bah.. indents lost :-( </p>
<p>one with proper indents on pocoo&#8230;.</p>
<p><a href="http://paste.pocoo.org/show/nZhGWlzvWmDhV9pRV5im/" rel="nofollow">http://paste.pocoo.org/show/nZhGWlzvWmDhV9pRV5im/</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Geir S</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1365</link>
		<dc:creator><![CDATA[Geir S]]></dc:creator>
		<pubDate>Mon, 28 Jun 2010 09:36:13 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1365</guid>
		<description><![CDATA[;;; A scheme solution. Nothing like the beauty of the haskell one though ;-)


;; Q1
(define (add-matrix m1 m2)
  (cond ((or (null? m1) (null? m2)) &#039;())
        (else (cons (sum-list (car m1) (car m2))
                    (add-matrix (cdr m1) (cdr m2))))))

;; Q1 helper
(define (sum-list l1 l2)
  (cond ((or (null? l1) (null? l2)) &#039;())
        (else (cons (+ (car l1) (car l2))
                    (sum-list (cdr l1) (cdr l2))))))

;; Q2
(define (scale s m)
  (letrec ((scale* (lambda (m)
                     (cond ((null? m) &#039;())
                           (else (cons (mul-list s (car m))
                                       (scale* (cdr m))))))))
    (scale* m)))

;; Q2 helper
(define (mul-list s l)
  (letrec ((mul-list* (lambda (l)
                        (cond ((null? l) &#039;())
                              (else (cons (* s (car l))
                                          (mul-list* (cdr l))))))))
    (mul-list* l)))

;; Q3
(define (X A B)
  (cond ((null? A) &#039;())
        (else (cons (psum (car A) B)
                    (X (cdr A) B)))))

;; Q3 helper - genereate list of cross-sums 
(define (psum l m)
  (letrec ((psum* (lambda (tm)
                    (cond ((null? tm) &#039;())
                          (else (cons (xs l (car tm))
                                      (psum* (cdr tm))))))))
    (psum* (transpose m))))

;; Q3 helper - multiply each element and sum result
(define (xs l1 l2)
  (cond ((or (null? l1) (null? l2)) 0)
        (else (+ (* (car l1) (car l2)) (xs (cdr l1) (cdr l2))))))

;; Q4
(define (transpose m)
  (cond ((null? (car m)) &#039;())
        (else (cons (list-of-heads m)
                    (transpose (list-of-tails m))))))

;; Q4 helper
(define (list-of-heads m)
  (cond ((null? m) &#039;())
        (else (cons (car (car m)) 
                    (list-of-heads (cdr m))))))

;; Q4 helper
(define (list-of-tails m)
  (cond ((null? m) &#039;())
        (else (cons (cdr (car m))
                    (list-of-tails (cdr m))))))]]></description>
		<content:encoded><![CDATA[<p>;;; A scheme solution. Nothing like the beauty of the haskell one though ;-)</p>
<p>;; Q1<br />
(define (add-matrix m1 m2)<br />
  (cond ((or (null? m1) (null? m2)) &#8216;())<br />
        (else (cons (sum-list (car m1) (car m2))<br />
                    (add-matrix (cdr m1) (cdr m2))))))</p>
<p>;; Q1 helper<br />
(define (sum-list l1 l2)<br />
  (cond ((or (null? l1) (null? l2)) &#8216;())<br />
        (else (cons (+ (car l1) (car l2))<br />
                    (sum-list (cdr l1) (cdr l2))))))</p>
<p>;; Q2<br />
(define (scale s m)<br />
  (letrec ((scale* (lambda (m)<br />
                     (cond ((null? m) &#8216;())<br />
                           (else (cons (mul-list s (car m))<br />
                                       (scale* (cdr m))))))))<br />
    (scale* m)))</p>
<p>;; Q2 helper<br />
(define (mul-list s l)<br />
  (letrec ((mul-list* (lambda (l)<br />
                        (cond ((null? l) &#8216;())<br />
                              (else (cons (* s (car l))<br />
                                          (mul-list* (cdr l))))))))<br />
    (mul-list* l)))</p>
<p>;; Q3<br />
(define (X A B)<br />
  (cond ((null? A) &#8216;())<br />
        (else (cons (psum (car A) B)<br />
                    (X (cdr A) B)))))</p>
<p>;; Q3 helper &#8211; genereate list of cross-sums<br />
(define (psum l m)<br />
  (letrec ((psum* (lambda &#8482;<br />
                    (cond ((null? tm) &#8216;())<br />
                          (else (cons (xs l (car tm))<br />
                                      (psum* (cdr tm))))))))<br />
    (psum* (transpose m))))</p>
<p>;; Q3 helper &#8211; multiply each element and sum result<br />
(define (xs l1 l2)<br />
  (cond ((or (null? l1) (null? l2)) 0)<br />
        (else (+ (* (car l1) (car l2)) (xs (cdr l1) (cdr l2))))))</p>
<p>;; Q4<br />
(define (transpose m)<br />
  (cond ((null? (car m)) &#8216;())<br />
        (else (cons (list-of-heads m)<br />
                    (transpose (list-of-tails m))))))</p>
<p>;; Q4 helper<br />
(define (list-of-heads m)<br />
  (cond ((null? m) &#8216;())<br />
        (else (cons (car (car m))<br />
                    (list-of-heads (cdr m))))))</p>
<p>;; Q4 helper<br />
(define (list-of-tails m)<br />
  (cond ((null? m) &#8216;())<br />
        (else (cons (cdr (car m))<br />
                    (list-of-tails (cdr m))))))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Carleton</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1364</link>
		<dc:creator><![CDATA[Paul Carleton]]></dc:creator>
		<pubDate>Sun, 27 Jun 2010 23:07:50 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1364</guid>
		<description><![CDATA[@Remco,

Your post has inspired me to learn Haskell!]]></description>
		<content:encoded><![CDATA[<p>@Remco,</p>
<p>Your post has inspired me to learn Haskell!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1361</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Sun, 27 Jun 2010 10:06:17 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1361</guid>
		<description><![CDATA[@Elvis Montero:

Thanks. Best of luck with learning Haskell. I can highly recommend it :)]]></description>
		<content:encoded><![CDATA[<p>@Elvis Montero:</p>
<p>Thanks. Best of luck with learning Haskell. I can highly recommend it :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Elvis Montero</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1360</link>
		<dc:creator><![CDATA[Elvis Montero]]></dc:creator>
		<pubDate>Sat, 26 Jun 2010 21:45:17 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1360</guid>
		<description><![CDATA[Here&#039;s my &lt;a href=&quot;http://elvismontero.com/progpraxis/MatrixOperations.html&quot; rel=&quot;nofollow&quot;&gt;Java solution&lt;/a&gt;.

@Remco,

Your Haskell solution is gorgeous (its simplicity astounds me). I&#039;ll hopefully be able to churn out solutions like that in Haskell soon!  =)]]></description>
		<content:encoded><![CDATA[<p>Here&#8217;s my <a href="http://elvismontero.com/progpraxis/MatrixOperations.html" rel="nofollow">Java solution</a>.</p>
<p>@Remco,</p>
<p>Your Haskell solution is gorgeous (its simplicity astounds me). I&#8217;ll hopefully be able to churn out solutions like that in Haskell soon!  =)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2010/06/22/matrix-operations/#comment-1352</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Tue, 22 Jun 2010 11:13:41 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.com/?p=2429#comment-1352</guid>
		<description><![CDATA[My Haskell solution (see http://bonsaicode.wordpress.com/2010/06/22/programming-praxis-matrix-operations/ for a version with comments):

[sourcecode lang=&quot;css&quot;]
add :: Num a =&gt; [[a]] -&gt; [[a]] -&gt; [[a]]
add = zipWith $ zipWith (+)

scale :: Num a =&gt; a -&gt; [[a]] -&gt; [[a]]
scale = map . map . (*)

transpose :: [[a]] -&gt; [[a]]
transpose [] = []
transpose xs = foldr (zipWith (:)) (repeat []) xs

mult :: Num a =&gt; [[a]] -&gt; [[a]] -&gt; [[a]]
mult a b = [map (sum . zipWith (*) r) $ transpose b &#124; r &lt;- a]
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Haskell solution (see <a href="http://bonsaicode.wordpress.com/2010/06/22/programming-praxis-matrix-operations/" rel="nofollow">http://bonsaicode.wordpress.com/2010/06/22/programming-praxis-matrix-operations/</a> for a version with comments):</p>
<pre class="brush: css;">
add :: Num a =&gt; [[a]] -&gt; [[a]] -&gt; [[a]]
add = zipWith $ zipWith (+)

scale :: Num a =&gt; a -&gt; [[a]] -&gt; [[a]]
scale = map . map . (*)

transpose :: [[a]] -&gt; [[a]]
transpose [] = []
transpose xs = foldr (zipWith (:)) (repeat []) xs

mult :: Num a =&gt; [[a]] -&gt; [[a]] -&gt; [[a]]
mult a b = [map (sum . zipWith (*) r) $ transpose b | r &lt;- a]
</pre>
]]></content:encoded>
	</item>
</channel>
</rss>

