Я работаю над некоторыми числовыми вычислениями в Common Lisp, и мне нужно вычислить линейную комбинацию нескольких векторов с заданными числовыми коэффициентами. Я переписываю часть кода на Фортране, где это может быть достигнуто res = a1*vec1 + a2*vec2 + ... + an*vecn
. Первоначально я хотел просто написать каждый раз что-то вроде:
(map 'vector
(lambda (x1 x2 ... xn)
(+ (* x1 a1) (* x2 a2) ... (* xn an)))
vec1 vec2 ... vecn)
Но вскоре я заметил, что этот шаблон будет повторяться снова и снова, и поэтому начал писать некоторый код, чтобы абстрагировать его. Поскольку число векторов и, следовательно, количество аргументов лямбды будет варьироваться от места к месту, я подумал, что потребуется макрос. Я придумал следующее:
(defmacro vec-lin-com (coefficients vectors &key (type 'vector))
(let ((args (loop for v in vectors collect (gensym))))
`(map ',type
(lambda ,args
(+ ,@(mapcar #'(lambda (c a) (list '* c a)) coefficients args)))
,@vectors)))
Макрорасширение выражения:
(vec-lin-com (10 100 1000) (#(1 2 3) #(4 5 6) #(7 8 9)))
дает, казалось бы, правильное расширение:
(MAP 'VECTOR
(LAMBDA (#:G720 #:G721 #:G722)
(+ (* 10 #:G720) (* 100 #:G721) (* 1000 #:G722)))
#(1 2 3) #(4 5 6) #(7 8 9))
Пока все хорошо ...
Теперь, когда я пытаюсь использовать его внутри такой функции:
(defun vector-linear-combination (coefficients vectors &key (type 'vector))
(vec-lin-com coefficients vectors :type type))
Я получаю ошибку компиляции, утверждающую, по существу, что The value VECTORS is not of type LIST
. Я не уверен, как подойти к этому. Я чувствую, что упускаю что-то очевидное. Любая помощь будет принята с благодарностью.