Умножение матриц и ДОТ-продукта


Упражнения 2.37. Предположим, что мы представляем векторы и V = (VI) как последовательности числа, и матрицы м = (МиЖ), а последовательности векторов (строк матрица). Например, матрица matrix m

представлен как последовательность ((1 2 3 4) (4 5 6 6) (6 7 8 9)). С этим представление, мы можем использовать последовательность операции, чтобы лаконично выразить основные матричные и векторные операции. Эти операции (которые описаны в любой книге по матричной алгебры) являются следующие:

matrix multiplication equations

Мы можем определить скалярное произведение ас17

(define (dot-product v w)
(accumulate + 0 (map * v w)))

Заполнить недостающие выражения в следующие процедуры для вычисления другие матричные операции. (В процедура накопления-N определяется в упражнения 2.36.)

(define (matrix-*-vector m v)
  (map <??> m))
(define (transpose mat)
  (accumulate-n <??> <??> mat))
(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (map <??> m)))

Я написал следующие решения:

(define (accumulate op initial items)
  (if (null? items)
      initial
      (op (car items) (accumulate op initial (cdr items)))))

(define (accumulate-n op init seqs)
  (if (null? (car seqs))
      null
      (cons (accumulate op init (map (lambda (x) (car x)) seqs))
            (accumulate-n op init (map (lambda (x) (cdr x)) seqs)))))

(define (dot-product v w)
  (accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
  (accumulate-n +
                0
                (map (lambda (row) 
                       (map (lambda (i j) (* i j)) row v)) m)))

(define (transpose mat)
  (accumulate-n (lambda (x y) (cons x y)) null mat))

(define (matrix-*-matrix m n) 
  (let ((cols (transpose n)))
    (map (lambda (m-row) 
           (accumulate-n +
                         0
                         (map (lambda (col) 
                                (map * m-row col))
                              cols))) m)))


(define m1 (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)))
(define m2 (list (list 10 20 30) (list 40 50 60) (list 70 80 90) (list 100 110 120)))

(define v1 (list 10 20 30 40))

Что вы думаете?



4301
5
задан 12 апреля 2011 в 02:04 Источник Поделиться
Комментарии
1 ответ

Ваше определение транспонирования правильно, хотя он может быть написан лаконично, как:

(define (transpose mat)
(accumulate-n cons null mat))

Остальные два определения может быть записана более лаконично, используя функции, определенные ранее. Обратите внимание, что умножение матрицы на вектор является концептуально же, как и получение дот-произведение вектора и числа в каждой строке матрицы. Таким образом, можно определить матрицу-*-вектор в виде:

(define (matrix-*-vector m v)
(map (lambda (row) (dot-product v row)) m))

Данное определение удовлетворяет требование учений.

Аналогично, умножение матриц из A в B является таким же, как транспонирование B и выполнении матрично-векторного умножения с каждой строкой из А. Таким образом, можно определить матрицы*матрицы как:

(define (matrix-*-matrix m n)
(let
((cols (transpose n)))
(map (lambda (row) (matrix-*-vector cols row)) m)))

Если вы хотите пойти дальше, чем упражнения требуется, вы можете использовать функцию выделки. Каррирование позволяет применить функцию добавочного аргументы. Если ваша реализация схемы обеспечивает Карри функция, вы можете написать:

(define (matrix-*-vector m v)
(map (curry dot-product v) m))

(define (matrix-*-matrix m n)
(map (curry matrix-*-vector (transpose n)) m))

2
ответ дан 15 апреля 2011 в 07:04 Источник Поделиться