Generic arithmetic on vectors

In SBCL, I'm finding some generic arithmetic is returning an error. The trace is below. Basically, when I try to (antik:* x y), and x and y are sequences, it fails if x is of type (simple-array fixnum) and y is of type (simple-array double-float). The problem appears to be in generic.lisp, where *i is defined to fall through to (map (type-of x) #'*i x y), thus assuming that the type produced by the product is the same as the type of the first argument. In general, that won't be the case because of the numerical tower, floating point contagion, etc. Even operating on two fixnums can create a bignum, so operands of type (simple-array fixnum) can need to create an array of type (simple-array integer). Here's the trace: ~$ sbcl This is SBCL 1.1.14.debian, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * (defvar x1 (make-array 3 :element-type 'double-float :initial-contents '(1d0 2d0 3d0))) X1 * (defvar i1 (make-array 3 :element-type 'fixum :initial-contents '(1 2 3))) I1 * x1 #(1.0d0 2.0d0 3.0d0) * i1 #(1 2 3) * (type-of x1) (SIMPLE-ARRAY DOUBLE-FLOAT (3)) * (type-of i1) (SIMPLE-VECTOR 3) * (ql:quickload "antik") To load "antik": Load 1 ASDF system: antik ; Loading "antik" ......... ("antik") * (antik:* i1 x1) #(1.0 4.0 9.0) * (antik:* x1 i1) #(1.0 4.0 9.0) * (antik:* x1 (coerce i1 '(vector fixnum))) #(1.0 4.0 9.0) * (antik:* (coerce i1 '(vector fixnum)) x1 ) debugger invoked on a TYPE-ERROR in thread #<THREAD "main thread" RUNNING {1002A8AF83}>: The value 1.0d0 is not of type FIXNUM. Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (SB-IMPL::OPTIMIZED-DATA-VECTOR-SET #<unavailable argument> #<unavailable argument> #<unavailable argument>) 0] backtrace Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1002A8AF83}> 0: (SB-IMPL::OPTIMIZED-DATA-VECTOR-SET #<unavailable argument> #<unavailable argument> #<unavailable argument>) 1: ((FLET SB-IMPL::F :IN SB-IMPL::%MAP-TO-VECTOR) 1 1.0d0) 2: (SB-IMPL::%MAP-FOR-EFFECT #<CLOSURE (FLET SB-IMPL::F :IN SB-IMPL::%MAP-TO-VECTOR) {7FFFF6BBF73B}> (#(1 2 3) #(1.0d0 2.0d0 3.0d0))) 3: (SB-IMPL::%MAP-TO-VECTOR (SIMPLE-ARRAY FIXNUM (3)) #<STANDARD-GENERIC-FUNCTION ANTIK::*I (10)> (#(1 2 3) #(1.0d0 2.0d0 3.0d0))) 4: (REDUCE #<STANDARD-GENERIC-FUNCTION ANTIK::*I (10)> (#(1 2 3) #(1.0d0 2.0d0 3.0d0))) 5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ANTIK:* (COERCE I1 (QUOTE (VECTOR FIXNUM))) X1) #<NULL-LEXENV>) 6: (EVAL (ANTIK:* (COERCE I1 (QUOTE (VECTOR FIXNUM))) X1)) 7: (INTERACTIVE-EVAL (ANTIK:* (COERCE I1 (QUOTE (VECTOR FIXNUM))) X1) :EVAL NIL) 8: (SB-IMPL::REPL-FUN NIL) 9: ((LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL)) 10: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL) {1003C615BB}>) 11: (SB-IMPL::TOPLEVEL-REPL NIL) 12: (SB-IMPL::TOPLEVEL-INIT) 13: ((FLET #:WITHOUT-INTERRUPTS-BODY-54 :IN SAVE-LISP-AND-DIE)) 14: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE)) 0] -- Harvey J. Stein hjstein@gmail.com http://www.linkedin.com/in/harveyjstein Selected papers and presentations available at: http://ssrn.com/author=732372

What type the result should be is not easy to determine in general, as you note. Taking the same type as the first argument is indeed a hack; it's really just a convenience for the most common cases. What you want to do is use grid:map-grid with either :destination (for which you have previously made the correct object, and supplied the object as the argument) or :destination-specification. On Sun, Apr 19, 2015 at 3:15 PM, Harvey Stein <hjstein@gmail.com> wrote:
In SBCL, I'm finding some generic arithmetic is returning an error. The trace is below. Basically, when I try to (antik:* x y), and x and y are sequences, it fails if x is of type (simple-array fixnum) and y is of type (simple-array double-float).
The problem appears to be in generic.lisp, where *i is defined to fall through to (map (type-of x) #'*i x y), thus assuming that the type produced by the product is the same as the type of the first argument. In general, that won't be the case because of the numerical tower, floating point contagion, etc. Even operating on two fixnums can create a bignum, so operands of type (simple-array fixnum) can need to create an array of type (simple-array integer).
Here's the trace:
~$ sbcl This is SBCL 1.1.14.debian, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * (defvar x1 (make-array 3 :element-type 'double-float :initial-contents '(1d0 2d0 3d0)))
X1 * (defvar i1 (make-array 3 :element-type 'fixum :initial-contents '(1 2 3)))
I1 * x1
#(1.0d0 2.0d0 3.0d0) * i1
#(1 2 3) * (type-of x1)
(SIMPLE-ARRAY DOUBLE-FLOAT (3)) * (type-of i1)
(SIMPLE-VECTOR 3) * (ql:quickload "antik") To load "antik": Load 1 ASDF system: antik ; Loading "antik" ......... ("antik") * (antik:* i1 x1)
#(1.0 4.0 9.0) * (antik:* x1 i1)
#(1.0 4.0 9.0) * (antik:* x1 (coerce i1 '(vector fixnum)))
#(1.0 4.0 9.0) * (antik:* (coerce i1 '(vector fixnum)) x1 )
debugger invoked on a TYPE-ERROR in thread #<THREAD "main thread" RUNNING {1002A8AF83}>: The value 1.0d0 is not of type FIXNUM.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level.
(SB-IMPL::OPTIMIZED-DATA-VECTOR-SET #<unavailable argument> #<unavailable argument> #<unavailable argument>) 0] backtrace
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1002A8AF83}> 0: (SB-IMPL::OPTIMIZED-DATA-VECTOR-SET #<unavailable argument> #<unavailable argument> #<unavailable argument>) 1: ((FLET SB-IMPL::F :IN SB-IMPL::%MAP-TO-VECTOR) 1 1.0d0) 2: (SB-IMPL::%MAP-FOR-EFFECT #<CLOSURE (FLET SB-IMPL::F :IN SB-IMPL::%MAP-TO-VECTOR) {7FFFF6BBF73B}> (#(1 2 3) #(1.0d0 2.0d0 3.0d0))) 3: (SB-IMPL::%MAP-TO-VECTOR (SIMPLE-ARRAY FIXNUM (3)) #<STANDARD-GENERIC-FUNCTION ANTIK::*I (10)> (#(1 2 3) #(1.0d0 2.0d0 3.0d0))) 4: (REDUCE #<STANDARD-GENERIC-FUNCTION ANTIK::*I (10)> (#(1 2 3) #(1.0d0 2.0d0 3.0d0))) 5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ANTIK:* (COERCE I1 (QUOTE (VECTOR FIXNUM))) X1) #<NULL-LEXENV>) 6: (EVAL (ANTIK:* (COERCE I1 (QUOTE (VECTOR FIXNUM))) X1)) 7: (INTERACTIVE-EVAL (ANTIK:* (COERCE I1 (QUOTE (VECTOR FIXNUM))) X1) :EVAL NIL) 8: (SB-IMPL::REPL-FUN NIL) 9: ((LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL)) 10: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL) {1003C615BB}>) 11: (SB-IMPL::TOPLEVEL-REPL NIL) 12: (SB-IMPL::TOPLEVEL-INIT) 13: ((FLET #:WITHOUT-INTERRUPTS-BODY-54 :IN SAVE-LISP-AND-DIE)) 14: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))
0]
-- Harvey J. Stein hjstein@gmail.com http://www.linkedin.com/in/harveyjstein Selected papers and presentations available at: http://ssrn.com/author=732372
participants (2)
-
Harvey Stein
-
Liam Healy