Giter VIP home page Giter VIP logo

numcl's Introduction

Numcl https://travis-ci.org/numcl/numcl.svg?branch=master

This is a Numpy clone in Common Lisp. At the moment the library is written in pure Common Lisp, focusing more on correctness and usefulness, not speed.

https://asciinema.org/a/245792.svg

NEWS

  • 2020/2/26 version 0.2.0 is released!
  • 2020/2/29 matmul* : multi-argument version of matmul is added. It optimizes the multiplication order in order to reduce the runtime / memory.
  • 2020/3/30 Refactored the type inference framework using float infiny / NaNs.
  • 2020/6/29 Minor incompatibility: LOG, LOG2 always return real arrays. Use LOGC instead for the original behavior.

Quick tutorial

In order to guarantee the speed and to simplify the implementation, the arrays given to numcl functions must satisfy the following two conditions:

  • It is a specialized array. Things of type (array single-float), (array (unsigned-byte 16)) etc.
  • It is an array displaced to a simple 1D specialized array. ”Simple array” means a non-displaced, non-adjustable array without fill pointer.

This means you cannot directly feed the arrays such as #2A((0.0 1.0) (2.0 3.0)), which is an array of type (simple-array T).

There are two ways to create an array similar to what you have and is compatible to numcl:

  • (reshape (arange 4.0) '(2 2))
  • (asarray #2A((0.0 1.0) (2.0 3.0)))
    • or (asarray '((0.0 1.0) (2.0 3.0)))
    • or (asarray '(#(0.0 1.0) #(2.0 3.0))).
  • (let ((a (zeros '(2 2) :type 'single-float))) (dotimes (i 2) (dotimes (j 2) (setf (aref a i j) ...)))).

The names and the parameters of numcl functions mostly (rather strictly) follows the numpy counterpart. There are even numpy names, such as dtype, which are just aliases for array-element-type.

Goals

  • Closely follow the numpy API, but still make it lispy.
    • Delegate the documentation effort to Numpy community.
  • Replace the Common Lisp array interface.
    • We do not deviate from the traditional symbols/idioms in Common Lisp unless necessary. Therefore we provide symbols that conflicts the Common Lisp symbol. Math functions become aliases to the original CL functions when the inputs are not arrays.
    • See doc/DETAILS.org#packages .

Features/Contracts

  • APIs are provided as functions, not macros.
    • It is a design flaw otherwise.
    • This does not mean the API is functional — we use procedural code.
  • Still, zero overhead.
    • The APIs are simply the wrappers over simple functions and designed to be fully inlined.
    • Optimization will be done on the compiler side, not by macros.
  • Operations are type-correct.
    • They always return arrays of the most specific array-element-type. For example,
    • (zeros 5) returns a bit vector.
    • (asarray ‘(1 2 3)) returns an (unsigned-byte 2) vector.
    • See doc/DETAILS.org#types .
  • NUMCL Arrays are CL arrays.
    • As this library aims to extend Common Lisp (not to replace part of it) in a compatible way, we do not introduce custom structures/classes for representing an array.
    • See doc/DETAILS.org#representation .

Dependencies

This library is at least tested on implementation listed below (note: I am lazy to update the version list below, but I regularly use it on much newer versions and never encountered a problem. As of writing, it works on 2.0.5.) :

  • SBCL 1.4.12 on X86-64 Linux 4.4.0-141-generic (author’s environment)
  • SBCL 1.5.1 on X86-64 Linux 4.4.0-141-generic (author’s environment)
  • SBCL 2.0.1 on X86-64 Ubuntu 16.04.6 LTS Linux 4.15.0-1028-gcp
  • ccl-1.11.5 on X86-64 Ubuntu 16.04.6 LTS Linux 4.15.0-1028-gcp
  • SBCL 2.0.1 on X86-64 Mac OS X 10.13.6
  • ccl-1.11.5 on X86-64 Mac OS X 10.13.6
  • SBCL 2.0.0 on X86-64 Windows Server, version 1809
  • SBCL 2.0.0 on Arm64 Ubuntu 16.04.6 LTS Linux 5.3.0-19-generic
  • SBCL 1.5.8 on ppc64le Ubuntu 16.04.6 LTS Linux 5.0.0-37-generic

Dependency graph:

./numcl.png

Author, License, Copyright

Masataro Asai ([email protected])

Licensed under LGPL v3.

Copyright (c) 2019 IBM Corporation

numcl's People

Contributors

0xflotus avatar afranson avatar benzwick avatar commander-trashdin avatar digikar99 avatar guicho271828 avatar kilianmh avatar mparlaktuna avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

numcl's Issues

ASET-REPLACE and CONCATENATE test failures on Windows CCL

Hello,

I downloaded numcl via quicklisp. Below is the transcript of the failed tests. I can help debug or test the code.

 Did 171 checks.
    Pass: 150 (87%)
    Skip: 0 ( 0%)
    Fail: 21 (12%)

 Failure Details:
 --------------------------------
 ASET-REPLACE []: 
      
A

 evaluated to 

#2A((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0))

 which is not 

EQUALP

 to 

#2A((0 0 0 0) (0 0 1 0) (0 1 0 0) (0 0 0 0))

..
 --------------------------------
 --------------------------------
 ASET-REPLACE []: 
      
A

 evaluated to 

#3A(((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)))

 which is not 

EQUALP

 to 

#3A(((0 0 0 0) (0 0 1 0) (0 1 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 1 0) (0 1 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 1 0) (0 1 0 0) (0 0 0 0)))

..
 --------------------------------
 --------------------------------
 ASET-REPLACE []: 
      
A

 evaluated to 

#3A(((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)))

 which is not 

EQUALP

 to 

#3A(((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 1 0) (0 1 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)))

..
 --------------------------------
 --------------------------------
 ASET-REPLACE []: 
      
(AREF A 1 '(1 3) '(1 3))

 evaluated to 

#2A((0 0) (0 0))

 which is not 

EQUALP

 to 

#2A((0 1) (1 0))

..
 --------------------------------
 --------------------------------
 ASET-REPLACE []: 
      
(AREF A '(0 2) '(1 3) 1)

 evaluated to 

#2A((0 0) (0 0))

 which is not 

EQUALP

 to 

#2A((0 1) (1 0))

..
 --------------------------------
 --------------------------------
 ASET-REPLACE []: 
      
A

 evaluated to 

#3A(((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)))

 which is not 

EQUALP

 to 

#3A(((0 0 0 0) (0 0 0 0) (0 1 0 0) (0 0 0 0)) ((0 0 0 0) (0 1 0 0) (0 0 0 0) (0 0 0 0)) ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#(0 1 2 3 4 0 1 2 3 4)

 evaluated to 

#(0 1 2 3 4 0 1 2 3 4)

 which is not 

EQUALP

 to 

#(0 0 0 0 0 0 0 0 0 0)

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#2A((0 1) (2 3) (0 1) (2 3))

 evaluated to 

#2A((0 1) (2 3) (0 1) (2 3))

 which is not 

EQUALP

 to 

#2A((0 0) (0 0) (0 0) (0 0))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#2A((0 1) (2 3) (0 1) (2 3))

 evaluated to 

#2A((0 1) (2 3) (0 1) (2 3))

 which is not 

EQUALP

 to 

#2A((0 0) (0 0) (0 0) (0 0))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#2A((0 1 0 1) (2 3 2 3))

 evaluated to 

#2A((0 1 0 1) (2 3 2 3))

 which is not 

EQUALP

 to 

#2A((0 0 0 0) (0 0 0 0))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#2A((0 1) (2 3) (0 1) (2 3))

 evaluated to 

#2A((0 1) (2 3) (0 1) (2 3))

 which is not 

EQUALP

 to 

#2A((0 0) (0 0) (0 0) (0 0))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#2A((0 1 0 1) (2 3 2 3))

 evaluated to 

#2A((0 1 0 1) (2 3 2 3))

 which is not 

EQUALP

 to 

#2A((0 0 0 0) (0 0 0 0))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#(0 1 2 3 4 0 1 2 3 4)

 evaluated to 

#(0 1 2 3 4 0 1 2 3 4)

 which is not 

EQUALP

 to 

#(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#2A((0 1 2 3 4) (0 1 2 3 4))

 evaluated to 

#2A((0 1 2 3 4) (0 1 2 3 4))

 which is not 

EQUALP

 to 

#2A((0 0 0 0 0) (0 0 0 0 0))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 1) (2 3)) ((0 1) (2 3)))

 evaluated to 

#3A(((0 1) (2 3)) ((0 1) (2 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 1) (2 3)) ((0 1) (2 3)))

 evaluated to 

#3A(((0 1) (2 3)) ((0 1) (2 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 1) (0 1)) ((2 3) (2 3)))

 evaluated to 

#3A(((0 1) (0 1)) ((2 3) (2 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 0) (1 1)) ((2 2) (3 3)))

 evaluated to 

#3A(((0 0) (1 1)) ((2 2) (3 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 1) (2 3)) ((0 1) (2 3)))

 evaluated to 

#3A(((0 1) (2 3)) ((0 1) (2 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 1) (0 1)) ((2 3) (2 3)))

 evaluated to 

#3A(((0 1) (0 1)) ((2 3) (2 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------
 --------------------------------
 CONCATENATE []: 
      
#3A(((0 0) (1 1)) ((2 2) (3 3)))

 evaluated to 

#3A(((0 0) (1 1)) ((2 2) (3 3)))

 which is not 

EQUALP

 to 

#3A(((0 0) (0 0)) ((0 0) (0 0)))

..
 --------------------------------

T

Docstring example does not work.

Examples about specifying :type '(array fixnum (*)) signals an error.
Other examples are fine in my environment.

* (lisp-implementation-type)

"SBCL"
* (lisp-implementation-version)

"2.0.5"
* (numcl:numcl-version)

"6cec166b198b6a024a63b4f36d366fc19b1de283"
* (numcl:asarray #(#(1 2) #(3 4))   :type '(array fixnum (*)))

debugger invoked on a SIMPLE-TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {1000898083}>:
  1 can't be converted to type (ARRAY FIXNUM (*)).

* (dribble)

static-vectors for certain arrays

  • Intermediate arrays for matmul* could be allocated/deallocated with static-vectors without impacting GC @thrashdin
  • options to %make-array and other functions

Suggested improvement to 1version.lisp

Loading numcl on Windows10+CCL failed on 1version.lisp at the
(uiop:run-program (format nil "cd ~a ; git rev-parse HEAD" (asdf:system-source-directory :numcl)) :output '(:string :stripped t))

I fixed it by replacing the semi-colon with the double ampersand like so
(uiop:run-program (format nil "cd ~a && git rev-parse HEAD" (asdf:system-source-directory :numcl)) :output '(:string :stripped t))

I do not understand why ; was failing. Possibly the c:/Users/... was causing the problem.

I am submitting this as an FYI - I am not using numcl at the moment, so this is not a show stopper.

Bug: aref with negative indices

As I understand, the current semantics for aref are that the subscript can either be

  • a s-expression evaluating to a valid index
  • a list of two elements: (a b) ;=> a:b
  • a list of three elements: (a b c) ;=> a:b:c
    with t being equivalent to an absence of argument.

However, there seem to be a few examples that work in numpy but not yet in numcl include (or work incorrectly):

(defparameter a (asarray '((1 2 3) (4 5 6))))
(aref a '(t -1)) ;=> #2A((1 2 3) (4 5 6)) ; a[:-1] in numpy returns array[[1,2,3]]
(aref a t '(t -1)) ;=> #2A((1 2 3) (4 5 6)) ; a[:, :-1] in numpy returns array([[1, 2], [4, 5]])
;;; Though
(numcl:aref a t '(t -2)) ;=> #2A((1 2) (4 5)) ; seems to be an off by one error - or is it as expected?

example.lisp crashes

Hi
After installing numcl in sbcl 2.0.5 running on Linux Mint (ubunt-ish), I attempted to run example.lisp which after considerable
work crashed with a diagnostic error:

Compile-time error:
during macroexpansion of
(NUMCL.IMPL::LET (#)
(DECLARE #)
...).
The value
SYMBOL
is not of type
(TYPE-R:ARRAY-SUBTYPE TYPE-R::ELEMENT-TYPE TYPE-R::DIMENSIONS)

My sbcl has 6Gb of dynamic memory.

Tom

Semantics for some functions do not match with CL exactly

For instance, (numcl:+) raises an invalid number of arguments error, while (cl:+) happily evaluates to 0. Is that intended or is this a bug?

This seems to be readily remedied by adding an :initial-value argument, changing

(defun numcl:+   (&rest args) (reduce (lambda (x y) (broadcast '+ x y)) args))

to

(defun numcl:+   (&rest args) (reduce (lambda (x y) (broadcast '+ x y)) args :initial-value 0))

Rewrite broadcast and other operations in einsum

I am going toward representing everything in an extended Einsum, and use it as a sort of compiler IR for performing the operator fusion. The idea is similar to Einsum.jl

Advantage:

  • future improvements to einsum will automatically improve their performance
  • Will enable fusion between the operators

Some systems failed to build for Quicklisp dist

Building with SBCL 2.1.6 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id b4cdb25

numcl.test fails to build with the following error:

Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BE8103}>: The value * is not of type LIST

numcl fails to build with the following error:

Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001BE8103}>: The value * is not of type LIST

Full log here

aref for selecting arbitrary elements

Basically, this

a = np.array([[1,2,3,4],[5,6,7,8]])
a[:, [0, 2,3]] # returns array([[1,3,4], [5,7,8]])

Is there a numcl equivalent? Because (aref a t '(0 2 3)) has a different semantics translating to a[:, 0:2:3]. I find needing the above slicing. There is the select:select, but this returns a simple-array.

May be a configuration variable may be included to let users choose between the two notations.

PS: I raised quite a few issues today. Lastly, thank you for all the work!

single operand subtraction does nothing

numcl> (uniform 0 10 10 'fixnum)
#(4 2 1 4 2 8 7 4 3 2)
#(4 2 1 4 2 8 7 4 3 2 2 8 2 7 6 8)
numcl> (- (uniform 0 10 10 'fixnum))
#(9 0 4 8 0 0 2 8 8 8)

should be all minus

transpose not working

I have installed numcl with Quicklisp and am going through the example.lisp file and see that functions such as zeros, ones, arange, and reshape all work as expected. However, when I skip down to the linear algebra section I am unable to use transpose. Here is my SBCL output:

* (ql:quickload :numcl) 
To load "numcl":
  Load 1 ASDF system:
    numcl
; Loading "numcl"
.
Switching to the BALLAND2006 optimizer
....
(:NUMCL)
* (in-package :numcl)
#<PACKAGE "NUMCL">
* (transpose #2A((0 1) (2 3)))
; in:
;      LAMBDA (NUMCL.IMPL::I0 NUMCL.IMPL::O0 #:W592 #:W593 NUMCL.IMPL::?1
;          NUMCL.IMPL::?0 #:O-TYPES594 #:W595 #:W596)
;     (NUMCL.IMPL::LET* ((NUMCL.IMPL::@1 (AREF NUMCL.IMPL::O0 NUMCL.IMPL::@IDX0))
;                        (NUMCL.IMPL::$1 (AREF NUMCL.IMPL::I0 NUMCL.IMPL::$IDX0)))
;       (DECLARE
;        (NUMCL.IMPL::DERIVE NUMCL.IMPL::O0 TYPE
;         (TYPE-R:ARRAY-SUBTYPE-ELEMENT-TYPE TYPE) NUMCL.IMPL::@1)
;        (NUMCL.IMPL::DERIVE NUMCL.IMPL::I0 TYPE
;         (TYPE-R:ARRAY-SUBTYPE-ELEMENT-TYPE TYPE) NUMCL.IMPL::$1))
;       (PROGN (SETF NUMCL.IMPL::@1 (NUMCL.IMPL::%COERCE # #)))
;       (SETF (AREF NUMCL.IMPL::O0 NUMCL.IMPL::@IDX0) NUMCL.IMPL::@1))
; 
; caught ERROR:
;   during macroexpansion of
;   (NUMCL.IMPL::LET* (# #)
;     (DECLARE #
;              #)
;     ...).
;   Use *BREAK-ON-SIGNALS* to intercept.
;   
;    The value
;      SYMBOL
;    is not of type
;      (TYPE-R:ARRAY-SUBTYPE TYPE-R::ELEMENT-TYPE TYPE-R::DIMENSIONS)

;     (+ NUMCL.IMPL::@IDX0 (* 1))
; 
; note: deleting unreachable code

;     (1+ NUMCL.IMPL::&0)
; --> + 
; ==>
;   NUMCL.IMPL::&0
; 
; note: deleting unreachable code

;     (LAMBDA
;         (NUMCL.IMPL::I0 NUMCL.IMPL::O0 #:W592 #:W593 NUMCL.IMPL::?1
;          NUMCL.IMPL::?0 #:O-TYPES594 #:W595 #:W596)
;       (DECLARE
;        (IGNORABLE #:W592 #:W593 NUMCL.IMPL::?1 NUMCL.IMPL::?0 #:O-TYPES594 #:W595
;         #:W596))
;       (DECLARE (TYPE SYMBOL NUMCL.IMPL::I0))
;       (DECLARE (TYPE (SIMPLE-ARRAY T 1) NUMCL.IMPL::O0))
;       (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0) (DEBUG 0)))
;       (DECLARE (TYPE NUMCL.IMPL::INDEX NUMCL.IMPL::?1 NUMCL.IMPL::?0))
;       (NUMCL.IMPL::DO* ((NUMCL.IMPL::&1 0 (1+ NUMCL.IMPL::&1))
;                         (NUMCL.IMPL::@IDX0 (+ 0 #) (+ NUMCL.IMPL::@IDX0 #))
;                         (NUMCL.IMPL::$IDX0 (+ 0 #) (+ NUMCL.IMPL::$IDX0 #)))
;           ((<= NUMCL.IMPL::?1 NUMCL.IMPL::&1))
;         (DECLARE
;          (NUMCL.IMPL::INDEX NUMCL.IMPL::&1 NUMCL.IMPL::$IDX0 NUMCL.IMPL::@IDX0))
;         (NUMCL.IMPL::DO* ((NUMCL.IMPL::&0 0 #) (NUMCL.IMPL::@IDX0 # #)
;                           (NUMCL.IMPL::$IDX0 # #))
;             ((<= NUMCL.IMPL::?0 NUMCL.IMPL::&0))
;           (DECLARE
;            (NUMCL.IMPL::INDEX NUMCL.IMPL::&0 NUMCL.IMPL::$IDX0 NUMCL.IMPL::@IDX0))
;           (NUMCL.IMPL::LET* (# #)
;             (DECLARE #
;                      #)
;             (PROGN #)
;             (SETF #)))))
; 
; caught STYLE-WARNING:
;   The variable NUMCL.IMPL::I0 is defined but never used.
; 
; caught STYLE-WARNING:
;   The variable NUMCL.IMPL::O0 is defined but never used.
; 
; compilation unit finished
;   caught 1 ERROR condition
;   caught 2 STYLE-WARNING conditions
;   printed 2 notes

debugger invoked on a SB-INT:COMPILED-PROGRAM-ERROR in thread
#<THREAD "main thread" RUNNING {1001578143}>:
  Execution of a form compiled with errors.
Form:
  (NUMCL.IMPL::LET* ((NUMCL.IMPL::@1
                    (COMMON-LISP:AREF NUMCL.IMPL::O0 NUMCL.IMPL::@IDX0))
                   (NUMCL.IMPL::$1
                    (COMMON-LISP:AREF NUMCL.IMPL::I0 NUMCL.IMPL::$IDX0)))
  (DECLARE
   (NUMCL.IMPL::DERIVE NUMCL.IMPL::O0 TYPE
    #1=(TYPE-R:ARRAY-SUBTYPE-ELEMENT-TYPE TYPE) NUMCL.IMPL::@1)
   (NUMCL.IMPL::DERIVE NUMCL.IMPL::I0 TYPE #1# NUMCL.IMPL::$1))
  (PROGN
   (SETF NUMCL.IMPL::@1
           (NUMCL.IMPL::%COERCE (COMMON-LISP:+ NUMCL.IMPL::@1 #)
                                (NUMCL.IMPL::COMPILE-TIME-TYPE-OF
                                 NUMCL.IMPL::@1))))
  (SETF (COMMON-LISP:AREF NUMCL.IMPL::O0 NUMCL.IMPL::@IDX0) NUMCL.IMPL::@1))
Compile-time error:
  during macroexpansion of
(NUMCL.IMPL::LET* (# #)
  (DECLARE #
           #)
  ...).
Use *BREAK-ON-SIGNALS* to intercept.

 The value
   SYMBOL
 is not of type
   (TYPE-R:ARRAY-SUBTYPE TYPE-R::ELEMENT-TYPE TYPE-R::DIMENSIONS)

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.

((LAMBDA (NUMCL.IMPL::I0 NUMCL.IMPL::O0 #:W592 #:W593 NUMCL.IMPL::?1 NUMCL.IMPL::?0 #:O-TYPES594 #:W595 #:W596)) #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument> #<unavailable argument>)

I am running SBCL 2.0.9 on macOS 10.15.2.

cannot run (matmul ....)

Hey,

Thanks for the effort, your project will be exactly what I need, a pure lisp numerical library :-)

I installed it today and I got this however:

an attempt to evaluate
(in-package :numcl)
(matmul '#2A((0.0 1.0) (2.0 3.0)) '#2A((5.0 6.0) (7.0 8.0)))

causes an error pasted below and also available here: https://pastebin.com/Pjk4aK2R

I tried various versions of SBCL, including 1.5.1 and 1.5.6
Fresh quicklisp as of 2019/09/14
libraries downloaded from git directly as master on 2019/09/14 linked as local-projects in quicklisp (so taking precedence over quicklisp):
numcl
specialized-function
trivia
type-i
type-r

Pattern: (((T NUMCL.IMPL::) T) ((NUMCL.IMPL:: T) T)
((NIL NUMCL.IMPL::) NIL) ((NUMCL.IMPL:: NIL) NIL)
(((TYPE-R:COMPLEX-TYPE NUMCL.IMPL::PREV)
(TYPE-R:COMPLEX-TYPE NUMCL.IMPL::NOW))
(COMPLEX ,#1=(NUMCL.IMPL::FN NUMCL.IMPL::PREV NUMCL.IMPL::NOW))) (((TYPE-R:COMPLEX-TYPE NUMCL.IMPL::PREV) NUMCL.IMPL::_) (COMPLEX ,#1#))
((NUMCL.IMPL::_ (TYPE-R:COMPLEX-TYPE NUMCL.IMPL::NOW))
(COMPLEX ,#1#)) (((TYPE-R:OR-TYPE NUMCL.IMPL::TYPES1) (TYPE-R:OR-TYPE NUMCL.IMPL::TYPES2)) (NUMCL.IMPL::SIMPLIFY-OR-TYPES (ALEXANDRIA.1.0.0:MAP-PRODUCT #'NUMCL.IMPL::FN NUMCL.IMPL::TYPES1 NUMCL.IMPL::TYPES2))) (((TYPE-R:OR-TYPE NUMCL.IMPL::TYPES1) NUMCL.IMPL::_) (NUMCL.IMPL::SIMPLIFY-OR-TYPES (MAPCAR (LAMBDA (TYPE) (NUMCL.IMPL::FN TYPE NUMCL.IMPL::NOW)) NUMCL.IMPL::TYPES1))) ((NUMCL.IMPL::_ (TYPE-R:OR-TYPE NUMCL.IMPL::TYPES2)) (NUMCL.IMPL::SIMPLIFY-OR-TYPES (MAPCAR (LAMBDA (TYPE) (NUMCL.IMPL::FN NUMCL.IMPL::PREV TYPE)) NUMCL.IMPL::TYPES2))) (((TYPE-R:REAL-SUBTYPE NUMCL.IMPL::L1 NUMCL.IMPL::H1) (TYPE-R:REAL-SUBTYPE NUMCL.IMPL::L2 NUMCL.IMPL::H2)) (NUMCL.IMPL::LET ((TYPE (NUMCL.IMPL::FLOAT-CONTAGION NUMCL.IMPL::PREV NUMCL.IMPL::NOW :INT-INT-RESULT NUMCL.IMPL::INT-INT-RESULT))) (FLET ((NUMCL.IMPL::C (NUMCL.IMPL::VALUE) (NUMCL.IMPL::%INTERVAL-COERCE NUMCL.IMPL::VALUE TYPE))) (TRIVIA.LEVEL2:EMATCH (FUNCALL NUMCL.IMPL::INTERVAL-OP NUMCL.IMPL::L1 NUMCL.IMPL::H1 NUMCL.IMPL::L2 NUMCL.IMPL::H2) ((LIST NUMCL.IMPL::LOW NUMCL.IMPL::HIGH) (IF (OR (EQ NUMCL.IMPL::LOW 'COMMON-LISP:*) (EQ NUMCL.IMPL::HIGH 'COMMON-LISP:*) (COMMON-LISP:<= NUMCL.IMPL::LOW NUMCL.IMPL::HIGH)) (IF (EQ TYPE 'INTEGER) (PROGN (CHECK-TYPE NUMCL.IMPL::LOW (OR INTEGER (EQL COMMON-LISP:*))) (CHECK-TYPE NUMCL.IMPL::HIGH (OR INTEGER (EQL COMMON-LISP:*))) (INTEGER
,@(NUMCL.IMPL::INTERVAL-INTERSECTION
NUMCL.IMPL::LOW NUMCL.IMPL::HIGH
MOST-NEGATIVE-FIXNUM
MOST-POSITIVE-FIXNUM)))
`(,TYPE
,(NUMCL.IMPL::C NUMCL.IMPL::LOW)
,(NUMCL.IMPL::C NUMCL.IMPL::HIGH)))
NIL)))))))
Values: (COMMON-LISP:* COMMON-LISP:*)
[Condition of type TRIVIA.LEVEL2:MATCH-ERROR]

Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1023F39DE3}>)

Backtrace:
0: ((LABELS NUMCL.IMPL::FN :IN NUMCL.IMPL::INFER-RATIONAL-ARITHMETIC-RESULT) COMMON-LISP:* COMMON-LISP:)
1: ((FLET "FN419" :IN NUMCL.IMPL::INFER-RATIONAL-ARITHMETIC-RESULT) COMMON-LISP:
)
2: ((FLET "FN383" :IN NUMCL.IMPL::INFER-RATIONAL-ARITHMETIC-RESULT) COMMON-LISP:)
3: ((LABELS NUMCL.IMPL::FN :IN NUMCL.IMPL::INFER-RATIONAL-ARITHMETIC-RESULT) COMPLEX COMPLEX)
4: (REDUCE #<CLOSURE (LABELS NUMCL.IMPL::FN :IN NUMCL.IMPL::INFER-RATIONAL-ARITHMETIC-RESULT) {1013BFFBFB}> (COMPLEX COMPLEX))
5: (NUMCL.IMPL::INFER-RATIONAL-ARITHMETIC-RESULT # (COMPLEX COMPLEX) INTEGER)
6: (NUMCL.IMPL::MUL-TO-FLOAT-TYPE COMPLEX COMPLEX)
7: (NUMCL.IMPL::INFER-TYPE COMMON-LISP:
COMPLEX COMPLEX)
8: (NUMCL.IMPL::INTERPRET-TYPE (COMMON-LISP:* T T))
9: (NUMCL.IMPL::INTERPRET-TYPE (COMMON-LISP:+ (INTEGER 0 0) (COMMON-LISP:* T T)))
10: (NUMCL.IMPL::EINSUM-OUTPUT-TYPES ((COMMON-LISP:+ NUMCL.IMPL::@1 (COMMON-LISP:* NUMCL.IMPL::$1 NUMCL.IMPL::$2))) (NUMCL.IMPL::$1 NUMCL.IMPL::$2) (NUMCL.IMPL::@1) #2A((0.0 1.0) (2.0 3.0)) #2A((5.0 6.0) ..
11: (MATMUL #2A((0.0 1.0) (2.0 3.0)) #2A((5.0 6.0) (7.0 8.0)) NIL)
12: (SB-INT:SIMPLE-EVAL-IN-LEXENV (MATMUL #2A((0.0 1.0) (2.0 3.0)) #2A((5.0 6.0) (7.0 8.0))) #)
13: (EVAL (MATMUL #2A((0.0 1.0) (2.0 3.0)) #2A((5.0 6.0) (7.0 8.0))))
--more--

Cheers,
Piotr (puchacz)

Heap exhausted during garbage collection

SBCL 2.1.4

* (room)
Dynamic space usage is:   24,942,560 bytes.
Immobile space usage is:  12,681,216 bytes (20,064 bytes overhead).
Read-only space usage is:          0 bytes.
Static space usage is:           736 bytes.
Control stack usage is:        2,016 bytes.
Binding stack usage is:          640 bytes.
Control and binding stack usage is for the current thread only.
Garbage collection is currently enabled.

Breakdown for dynamic space:
   7,236,496 bytes for  54,760 simple-vector objects
   5,712,064 bytes for  95,594 instance objects
   4,165,664 bytes for 260,354 cons objects
   2,330,544 bytes for  25,854 simple-array-unsigned-byte-8 objects
   1,587,664 bytes for  31,660 simple-base-string objects
   1,428,192 bytes for  43,659 bignum objects
   2,535,504 bytes for  36,158 other objects

  24,996,128 bytes for 548,039 dynamic objects (space total)

Breakdown for immobile space:
  10,829,568 bytes for 17,190 code objects
   1,232,464 bytes for 25,663 symbol objects
     598,864 bytes for 16,609 other objects

  12,660,896 bytes for 59,462 immobile objects (space total)
 Running test EINSUM ................
Heap exhausted during garbage collection: 0 bytes available, 32 requested.
Gen  Boxed   Code    Raw  LgBox LgCode  LgRaw  Pin       Alloc     Waste        Trig      WP GCs Mem-age
 1    8672      0  23608      0      0      0    9   966860496  90890544    32212254   32280   0  0.9999
 2   21544      2  13429     94      0     45  123  1115988688  34626864    64102110   35114   1  0.2814
 3       0      0      0      0      0      0    0           0         0     2000000       0   0  0.0000
 4       0      0      0      0      0      0    0           0         0     2000000       0   0  0.0000
 5       0      0      0      0      0      0    0           0         0     2000000       0   0  0.0000
 6     493      2    220     55      0     10    0    24886032    673008     2000000     780   0  0.0000
 7    8654      0  21475      0      0      0    0   896566048  90701024     2000000   30129   0  0.0000
           Total bytes allocated    =    3004301264
           Dynamic-space-size bytes =    3221225472
GC control variables:
   *GC-INHIBIT* = true
   *GC-PENDING* = true
   *STOP-FOR-GC-PENDING* = false
fatal error encountered in SBCL pid 31 tid 31:
Heap exhausted, game over.

   0: fp=0x7ffff7935c20 pc=0x52dfb8d9 SB-REGALLOC::GROW-SC
   1: fp=0x7ffff7935cd0 pc=0x52b03461 SB-REGALLOC::PACK-TN
   2: fp=0x7ffff7935d80 pc=0x52b03803 (FLET SB-REGALLOC::PACK-TNS :IN SB-REGALLOC::PACK)
   3: fp=0x7ffff7935e30 pc=0x52b028f4 SB-REGALLOC::PACK
   4: fp=0x7ffff7935eb8 pc=0x52c105b5 SB-C::%COMPILE-COMPONENT
   5: fp=0x7ffff7935f20 pc=0x52b2f7f1 SB-C::COMPILE-COMPONENT
   6: fp=0x7ffff7935f90 pc=0x52c12683 SB-C::%COMPILE
   7: fp=0x7ffff7936068 pc=0x52af5b93 (FLET "LAMBDA0" :IN "SYS:SRC;COMPILER;TARGET-MAIN.LISP")
   8: fp=0x7ffff7936110 pc=0x52b75b85 (FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT)
   9: fp=0x7ffff7936238 pc=0x52af66b0 SB-C::COMPILE-IN-LEXENV
  10: fp=0x7ffff7936270 pc=0x52a6c72c COMPILE
  11: fp=0x7ffff7936290 pc=0x53ac1956 (LABELS NUMCL.TEST::%TEST-EINSUM-STRIDE :IN "/gnu/store/95h2ys1n60hpyhljgd8qv7pls9b8crp3-sbcl-numcl-0.2.0-2.3dcdb0e/lib/common-lisp/sbcl/numcl/t/package.fasl")
  12: fp=0x7ffff7936578 pc=0x53abad4c (LABELS IT.BESE.FIVEAM::RUN-IT :IN IT.BESE.FIVEAM::RUN-TEST-LAMBDA)
  13: fp=0x7ffff79366e0 pc=0x53ab9ebe (SB-PCL::FAST-METHOD IT.BESE.FIVEAM::RUN-TEST-LAMBDA (IT.BESE.FIVEAM::TEST-CASE))
  14: fp=0x7ffff7936750 pc=0x53ab87a2 (SB-PCL::FAST-METHOD IT.BESE.FIVEAM::RUN-RESOLVING-DEPENDENCIES (IT.BESE.FIVEAM::TEST-CASE))
  15: fp=0x7ffff7936830 pc=0x53abbc11 (FLET IT.BESE.FIVEAM::RUN-TESTS :IN IT.BESE.FIVEAM::%RUN)
  16: fp=0x7ffff7936910 pc=0x53abb72f (SB-PCL::FAST-METHOD IT.BESE.FIVEAM::%RUN (IT.BESE.FIVEAM::TEST-SUITE))
  17: fp=0x7ffff7936a08 pc=0x53abcda0 (LAMBDA () :IN IT.BESE.FIVEAM::RUN)
  18: fp=0x7ffff7936a98 pc=0x53abc986 IT.BESE.FIVEAM::RUN
  19: fp=0x7ffff7936ae0 pc=0x53abbfb8 IT.BESE.FIVEAM::RUN!
  20: fp=0x7ffff7936ba8 pc=0x52b41006 SB-INT::SIMPLE-EVAL-IN-LEXENV
  21: fp=0x7ffff7936bc0 pc=0x52a3d6e3 EVAL
  22: fp=0x7ffff7936c10 pc=0x534f5852 (SB-PCL::EMF ASDF/ACTION::PERFORM)
  23: fp=0x7ffff7936c90 pc=0x534b3053 (LAMBDA () :IN ASDF/ACTION::CALL-WHILE-VISITING-ACTION)
  24: fp=0x7ffff7936e00 pc=0x534ba1d0 (SB-PCL::FAST-METHOD ASDF/ACTION::PERFORM-WITH-RESTARTS :AROUND (T T))
  25: fp=0x7ffff7936e40 pc=0x534cc555 (SB-PCL::FAST-METHOD ASDF/PLAN::PERFORM-PLAN (T))
  26: fp=0x7ffff7936f20 pc=0x52b759bf (FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT)
  27: fp=0x7ffff7936f90 pc=0x534cc168 (SB-PCL::FAST-METHOD ASDF/PLAN::PERFORM-PLAN :AROUND (T))
  28: fp=0x7ffff7936fe0 pc=0x534ce55a (SB-PCL::FAST-METHOD ASDF/OPERATE::OPERATE (ASDF/OPERATION::OPERATION ASDF/COMPONENT::COMPONENT))
  29: fp=0x7ffff7937040 pc=0x534f282c (SB-PCL::EMF ASDF/OPERATE::OPERATE)
  30: fp=0x7ffff7937108 pc=0x534cdc32 (LAMBDA () :IN ASDF/OPERATE::OPERATE)
  31: fp=0x7ffff79371d0 pc=0x534cd4bc (SB-PCL::FAST-METHOD ASDF/OPERATE::OPERATE :AROUND (T T))
  32: fp=0x7ffff7937230 pc=0x534f282c (SB-PCL::EMF ASDF/OPERATE::OPERATE)
  33: fp=0x7ffff79372f8 pc=0x534cdc32 (LAMBDA () :IN ASDF/OPERATE::OPERATE)
  34: fp=0x7ffff79373c0 pc=0x534cd4bc (SB-PCL::FAST-METHOD ASDF/OPERATE::OPERATE :AROUND (T T))
  35: fp=0x7ffff79375b8 pc=0x534a6a9b ASDF/SESSION::CALL-WITH-ASDF-SESSION
  36: fp=0x7ffff7937680 pc=0x534cddf1 (LAMBDA () :IN ASDF/OPERATE::OPERATE)
  37: fp=0x7ffff7937880 pc=0x534a6a9b ASDF/SESSION::CALL-WITH-ASDF-SESSION
  38: fp=0x7ffff7937948 pc=0x534cd4bc (SB-PCL::FAST-METHOD ASDF/OPERATE::OPERATE :AROUND (T T))
  39: fp=0x7ffff7937980 pc=0x534d01d3 ASDF/OPERATE::TEST-SYSTEM
  40: fp=0x7ffff7937a48 pc=0x52b41006 SB-INT::SIMPLE-EVAL-IN-LEXENV
  41: fp=0x7ffff7937a60 pc=0x52a3d6e3 EVAL
  42: fp=0x7ffff7937c10 pc=0x52c0110d SB-IMPL::PROCESS-EVAL/LOAD-OPTIONS
  43: fp=0x7ffff7937dd8 pc=0x52b6f33e SB-IMPL::TOPLEVEL-INIT
  44: fp=0x7ffff7937e70 pc=0x52f22ca5 (FLET SB-UNIX::BODY :IN SB-IMPL::START-LISP)
  45: fp=0x7ffff7937f30 pc=0x52f22a76 (FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-IMPL::START-LISP)
  46: fp=0x7ffff7937fc8 pc=0x52f22899 SB-IMPL::START-LISP
command "/gnu/store/i8wj59i9x3p8k253jmhxn5hi2iw0x4hw-sbcl-2.1.4/bin/sbcl" "--non-interactive" "--eval" "(require :asdf)" "--eval" "(asdf:load-asd (truename \"/gnu/store/95h2ys1n60hpyhljgd8qv7pls9b8crp3-sbcl-numcl-0.2.0-2.3dcdb0e/share/common-lisp/sbcl/numcl/numcl.asd\"))" "--eval" "(asdf:load-asd (truename \"/gnu/store/95h2ys1n60hpyhljgd8qv7pls9b8crp3-sbcl-numcl-0.2.0-2.3dcdb0e/share/common-lisp/sbcl/numcl/numcl.test.asd\"))" "--eval" "(asdf:test-system \"numcl\")" failed with status 1
builder for `/gnu/store/b0zxyyqclr53psxiwhh79w74czmwj7mm-sbcl-numcl-0.2.0-2.3dcdb0e.drv' failed with exit code 1

WARNING: Missing type inference function for 1+, defaults to T

Hello!

I'm having this warning when using map-array:

(numcl:map-array 'cl:1+ (numcl:asarray '(2 2)))
;; WARNING: Missing type inference function for 1+, defaults to T
;; => #(3 3)

I don't understand how I can implement an inference function. I read the docs and the source, but I couldn't find anything related to that.

vander function error

Hi, in the file example.lisp
(vander (asarray #(1 2 3 5) :n) 3)
result is error.
then I enter:
(vander (asarray #(1 2 3 5)))
the error is :
The value
27
is not of type
(UNSIGNED-BYTE 4)
when setting an element of (ARRAY (UNSIGNED-BYTE 4))
[Condition of type TYPE-ERROR]

Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1001514103}>)

Backtrace:
0: ((SB-VM::OPTIMIZED-DATA-VECTOR-SET (UNSIGNED-BYTE 4)) # # #)
1: (VANDER #(1 2 3 5) :N NIL :INCREASING NIL)
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (VANDER (ASARRAY #(1 2 3 5))) #)
3: (EVAL (VANDER (ASARRAY #(1 2 3 5))))
--more--

Quickloading hangs.

I tried to reproduce the issue with matmul returning 0 1 0 1 matrix for every input, and stumbled upon this:

CL-USER> (ql:quickload 'numcl)
To load "numcl":
  Load 1 ASDF system:
    numcl
; Loading "numcl"
.
Switching to the BALLAND2006 optimizer
.................................................
[package numcl.exported].................
; Discarding the grounding result with 322 clauses; more than 300 clauses.
....
; Discarding the grounding result with 551 clauses; more than 300 clauses.
..
; Discarding the grounding result with 551 clauses; more than 300 clauses.
.
; Discarding the grounding result with 570 clauses; more than 300 clauses.
..
.
; Discarding the grounding result with 570 clauses; more than 300 clauses.
.................................................
.......................................
; inlining (MATMUL ACC M)..
; inlining (MATMUL (PROCESS-TREE (FIRST TREE)) (PROCESS-TREE (SECOND TREE)))..
; inlining (MATMUL (REC I K) (REC (1+ K) J)).......
..................................................
..................................................
..............

and this is where it hangs forever.

However, if I just kill sbcl and retry it, it load now, and here's matmul output:

CL-USER> (in-package numcl)
#<PACKAGE "NUMCL">
NUMCL> (matmul* (asarray #2A((10 1.0) (2.0 3.0))) (asarray #2A((0.0 1.0) (2.0 3.0))))
; in:
;      LAMBDA (NUMCL.IMPL::I0 NUMCL.IMPL::I1 NUMCL.IMPL::O0 NUMCL.IMPL::A
;          NUMCL.IMPL::B NUMCL.IMPL::RESULT #:W120 #:W121 #:W122 #:W123
;          NUMCL.IMPL::?2 NUMCL.IMPL::?1 ...)
;     (* NUMCL.IMPL::$1 NUMCL.IMPL::$2)
; 
; note: unable to
;   convert x*2^k to shift
; due to type uncertainty:
;   The first argument is a NUMBER, not a INTEGER.
;   The second argument is a NUMBER, not a INTEGER.
; 
; note: forced to do GENERIC-* (cost 30)
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a FIXNUM.
;       The second argument is a NUMBER, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &REST T).
;       unable to do inline float arithmetic (cost 4) because:
;       The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;       The second argument is a NUMBER, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (COMPLEX SINGLE-FLOAT)
;                                                         &REST T).
;       etc.

;     (+ NUMCL.IMPL::@1 (* NUMCL.IMPL::$1 NUMCL.IMPL::$2))
; 
; note: forced to do GENERIC-+ (cost 10)
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a DOUBLE-FLOAT.
;       The second argument is a NUMBER, not a DOUBLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES DOUBLE-FLOAT
;                                                                &REST T).
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a SINGLE-FLOAT.
;       The second argument is a NUMBER, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
;                                                                &REST T).
;       etc.

;     (NUMCL.IMPL::%COERCE (+ NUMCL.IMPL::@1 (* NUMCL.IMPL::$1 NUMCL.IMPL::$2))
;                          (NUMCL.IMPL::COMPILE-TIME-TYPE-OF NUMCL.IMPL::@1))
; --> BLOCK COND IF NUMCL.IMPL::UB ROUND ROUND LET 
; ==>
;   (SB-KERNEL:%UNARY-ROUND SB-C::X)
; 
; note: forced to do full call
;       unable to do inline float truncate (cost 5) because:
;       The first argument is a REAL, not a SINGLE-FLOAT.
;       The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES
;                                                          (SIGNED-BYTE 64) &REST
;                                                          T).
;       unable to do inline float truncate (cost 5) because:
;       The first argument is a REAL, not a DOUBLE-FLOAT.
;       The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES
;                                                          (SIGNED-BYTE 64) &REST
;                                                          T).
; 
; compilation unit finished
;   printed 4 notes
#2A((0 1) (0 1))
NUMCL> (matmul (asarray #2A((10 1.0) (2.0 3.0))) (asarray #2A((0.0 1.0) (2.0 3.0))))
; in:
;      LAMBDA (NUMCL.IMPL::I0 NUMCL.IMPL::I1 NUMCL.IMPL::O0 NUMCL.IMPL::A
;          NUMCL.IMPL::B NUMCL.IMPL::RESULT #:W864 #:W865 #:W866 #:W867
;          NUMCL.IMPL::?2 NUMCL.IMPL::?1 ...)
;     (* NUMCL.IMPL::$1 NUMCL.IMPL::$2)
; 
; note: unable to
;   convert x*2^k to shift
; due to type uncertainty:
;   The first argument is a NUMBER, not a INTEGER.
;   The second argument is a NUMBER, not a INTEGER.
; 
; note: forced to do GENERIC-* (cost 30)
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a FIXNUM.
;       The second argument is a NUMBER, not a FIXNUM.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &REST T).
;       unable to do inline float arithmetic (cost 4) because:
;       The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;       The second argument is a NUMBER, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES
;                                                         (COMPLEX SINGLE-FLOAT)
;                                                         &REST T).
;       etc.

;     (+ NUMCL.IMPL::@1 (* NUMCL.IMPL::$1 NUMCL.IMPL::$2))
; 
; note: forced to do GENERIC-+ (cost 10)
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a DOUBLE-FLOAT.
;       The second argument is a NUMBER, not a DOUBLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES DOUBLE-FLOAT
;                                                                &REST T).
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a SINGLE-FLOAT.
;       The second argument is a NUMBER, not a SINGLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
;                                                                &REST T).
;       etc.

;     (NUMCL.IMPL::%COERCE (+ NUMCL.IMPL::@1 (* NUMCL.IMPL::$1 NUMCL.IMPL::$2))
;                          (NUMCL.IMPL::COMPILE-TIME-TYPE-OF NUMCL.IMPL::@1))
; --> BLOCK COND IF NUMCL.IMPL::UB ROUND ROUND LET 
; ==>
;   (SB-KERNEL:%UNARY-ROUND SB-C::X)
; 
; note: forced to do full call
;       unable to do inline float truncate (cost 5) because:
;       The first argument is a REAL, not a SINGLE-FLOAT.
;       The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES
;                                                          (SIGNED-BYTE 64) &REST
;                                                          T).
;       unable to do inline float truncate (cost 5) because:
;       The first argument is a REAL, not a DOUBLE-FLOAT.
;       The result is a (VALUES INTEGER &OPTIONAL), not a (VALUES
;                                                          (SIGNED-BYTE 64) &REST
;                                                          T).
; 
; compilation unit finished
;   printed 4 notes
#2A((0 1) (0 1))

Can't assign values to string array slice.

Hello and thank you for your work on this awesome project!

Running the following code:

(defparameter *a* (numcl:full '(3 3) "a" :type 'string))
(numcl:setf (numcl:aref *a* 0 t) #("b" "b" "b")))

results in this error:

The shape of the array of new elements:
(3)
The shape of the range specified by the subscript:
(3 1)
The tails of the subscripts do not match; broadcasting failed.
[Condition of type SIMPLE-ERROR].

Both (numcl:shape (numcl:aref *a* 0 t)) and (numcl:shape #("b" "b" "b")) return (3).

Trying to do the same thing but with integers instead of strings works just fine. Am I doing something wrong or is this a bug?

linspace->float-substitution fails with complex numbers

When running

(numcl:linspace #C(1d0 1d0) #C(1d0 4d0) :num 4)

, I get the following error from sly,

Pattern: ((T T) (NIL NIL)
          ((TYPE-R:FLOAT-TYPE)
           NUMCL.IMPL::*NUMCL-DEFAULT-FLOAT-FORMAT*)
          ((TYPE-R:LONG-FLOAT-TYPE) 'LONG-FLOAT)
          ((TYPE-R:DOUBLE-FLOAT-TYPE) 'DOUBLE-FLOAT)
          ((TYPE-R:SINGLE-FLOAT-TYPE) 'SINGLE-FLOAT)
          ((TYPE-R:SHORT-FLOAT-TYPE) 'SHORT-FLOAT)
          ((TYPE-R:INTEGER-SUBTYPE) NUMCL.IMPL::INT-RESULT)
          ((TYPE-R:RATIO-TYPE)
           NUMCL.IMPL::*NUMCL-DEFAULT-FLOAT-FORMAT*)
          ((TYPE-R:REAL-SUBTYPE)
           (ERROR "this should not happen"))
          ((TYPE-R:COMPLEX-TYPE NUMCL.IMPL::ELEMENT-TYPE)
           `(COMPLEX
             ,(NUMCL.IMPL::FLOAT-SUBSTITUTION
               NUMCL.IMPL::ELEMENT-TYPE :INT-RESULT
               NUMCL.IMPL::*NUMCL-DEFAULT-FLOAT-FORMAT*)))
          ((TYPE-R:OR-TYPE NUMCL.IMPL::TYPES)
           `(OR
             ,@(REMOVE-DUPLICATES
                (REMOVE NIL
                        #1=(MAPCAR #'NUMCL.IMPL::REC
                                   NUMCL.IMPL::TYPES)))))
          ((TYPE-R:AND-TYPE NUMCL.IMPL::TYPES)
           (TRIVIA.LEVEL2:MATCH #1#
             ((LIST* FIRST REST)
              (IF (EVERY (ALEXANDRIA:CURRY #'EQ FIRST) REST)
                  FIRST
                  NIL))))) 
 Values: ((TYPE-R:COMPLEX-TYPE DOUBLE-FLOAT))
   [Condition of type TRIVIA.LEVEL2:MATCH-ERROR]

. It fails with double and single float inputs.

numcl, meet cl-ana

Hello, and thank you for the project! After an exhaustive search for something like numpy a few weeks ago, I came across cl-ana, and I've been hacking with it for the past few weeks. I thought I would make the projects aware of each other in case there is some functionality that is common, and if there is a potential for collaboration. cl-ana is GPL 3.

cc ghollisjr/cl-ana#30

factorial ?

Hello, I wonder how to apply a factorial.
Is it possible? Can I otherwise add it, if yes: how?

Thank you.

Not-yet-numcl symbols: work in progress?

I was trying to use (expt (asarray '(1 2)) 2). But that doesn't seem to work.

In fact, from the CLHS, we have (double-check if formal-check required!):

(defparameter math-functions
  '(= /= < > <= >=
    max min
    minusp plusp
    zerop
    floor ffloor ceiling fceiling truncate ftruncate round fround
    sin cos tan
    asin acos atan
    sinh cosh tanh asinh acosh atanh
    *
    +
    -
    /
    1+
    1-
    abs
    evenp oddp
    exp expt
    gcd
    incf decf
    lcm
    log
    mod rem
    signum
    sqrt isqrt
                                   ;; random-state skipped ; ; ;
    numberp
    cis
    complex
    complexp
    phase
    realpart imagpart
    upgraded-complex-part-type
    realp
    numerator denominator
    rational rationalize
    rationalp
    ash
    integer-length
    integerp
    parse-integer
    boole
    logand logandc1 logandc2 logeqv logior lognand lognor lognot logorc1 logorc2 logxor
    logbitp
    logcount
    logtest
    byte byte-size byte-position
    deposit-field
    dpb
    ldb
    ldb-test
    mask-field
    decode-float scale-float float-radix float-sign float-digits float-precision integer-decode-float
    float
    floatp
                                   ;; ignored: arithmetic-error ; ; ;
    ))

and

(defparameter numcl-exported
  (iter (for symbol in-package :numcl.exported external-only t)
        (collect symbol)))
(set-difference math-functions numcl-exported
                :test (lambda (sym1 sym2)
                        (string= (symbol-name sym1) (symbol-name sym2))))
;;; (floatp float integer-decode-float float-precision float-digits float-sign
;;;         float-radix scale-float decode-float mask-field ldb-test ldb dpb
;;;         deposit-field byte-position byte-size byte logtest logbitp boole
;;;         parse-integer integerp ash rationalp rationalize rational realp
;;;         upgraded-complex-part-type complexp complex numberp isqrt lcm decf incf
;;;         gcd oddp evenp atanh acosh asinh zerop plusp minusp)

Some symbols like (rationalp rationalize rational) do not seem needed as per the documentation. Such symbols could be dumped into another list blacklisted-math-symbols and then, the check may be made.

I wonder if these are a work in progress; in any case, hope to see them soon!

Macro expansion error in `'compile-bundle-op` on the current version

Loading the current version (commit 3c39fc4064dad9d3f1f000abfe69066aecc79ff2) into SBCL 2.0.2 under Linux fails with a macro expansion error:

; compiling (DEFUN MATMUL*-NAIVE ...)

; file: /gnu/store/dzi30n09h603ahwa2bafgzzal89v89qc-sbcl-numcl-0.1.0-1.3c39fc4/share/common-lisp/sbcl-source/numcl/src/4linear-algebra3.lisp
; in: DEFUN MATMUL*-NAIVE
;     (NUMCL.EXPORTED:MATMUL NUMCL.IMPL::ACC NUMCL.IMPL::M)
; 
; caught WARNING:
;   Error during compiler-macroexpansion of (MATMUL ACC M). Use *BREAK-ON-SIGNALS*
;   to intercept.
;   
;    The variable #:ARGS-VAR1 is unbound.

There are a few more such errors for other applications of matmul.

map-outer: map over the outer dimensions of arrays or vectors or lists

A few of the things I liked about numcl more than numpy was the presence of map-array. While map-array seems to want all its arguments to have the same dimension, I'd also like to have something like map-outer that iterates over the outer dimension of its arguments:

(defun cost (x y θ cost-fn) ; x could be 2-dim, while y could be 1-dim
  (reduce '+ (map-outer cost-fn x y)))

PS: While this is a very wrong way to do things in the ML community, it seems rather clearer in its intention, and at least useful for pedagogical purposes.

Test suite lands in debugger at `EINSUM-STRIDE`

Hello,

On Linux/SBCL2.0.7 running the test suite drops me into the debugger when evaluating the EINSUM-STRIDE tests.

Environment:

CL-USER> (lisp-implementation-type)

"SBCL"
CL-USER> (lisp-implementation-version)
"2.0.7"
CL-USER> (numcl:numcl-version)
"numcl-20200715-git"

The debugger output:

Heap exhausted during garbage collection: 0 bytes available, 64 requested.
Gen  Boxed   Code    Raw  LgBox LgCode  LgRaw  Pin       Alloc     Waste        Trig      WP GCs Mem-age
 1    7611      0   4886      0      0      0   10   384479984  25021712   278126746   12497   1  1.6704
 2    9480      1   4272     14      0      0   49   412981280  38135776    10737418   13767   0  0.4161
 3    4447      3   1264     63      0     36  211   188207216   2273168     2000000    5813   0  0.5042
 4       0      0      0      0      0      0    0           0         0     2000000       0   0  0.0000
 5       0      0      0      0      0      0    0           0         0     2000000       0   0  0.0000
 6     432      2    184     55      0     10    0    21690768    689776     2000000     683   0  0.0000
           Total bytes allocated    =    1007359248
           Dynamic-space-size bytes =    1073741824
GC control variables:
   *GC-INHIBIT* = true
   *GC-PENDING* = true
   *STOP-FOR-GC-PENDING* = false
fatal error encountered in SBCL pid 423464(tid 0x2af8fdc77700):
Heap exhausted, game over.

Error opening /dev/tty: No such device or address
Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb> 

My own DOT function.

For my own use, I wrote DOT function.

I am poor about linear algebra, so the code may incorrect.
Additionally I am poor about python and numpy, I could not find enough test codes.
I wrote this just referring documentation and its example.

Anyway, if you like it, please free to copy and modify :)

numcl:/ Control stack exhausted.

  • (lisp-implementation-type)

"SBCL"

  • (lisp-implementation-version)

"2.0.2"

  • (numcl:numcl-version)

"numcl-20200427-git"

  • (numcl:/ (numcl:asarray '(1.0 2.0 3.0)) (numcl:asarray '(2.0 4.0 6.0)))
    Control stack guard page temporarily disabled: proceed with caution

debugger invoked on a SB-KERNEL::CONTROL-STACK-EXHAUSTED in thread
#<THREAD "main thread" RUNNING {1000518083}>:
Control stack exhausted (no more space for function call frames).
This is probably due to heavily nested or infinitely recursive function
calls, or a tail call that SBCL cannot or has not optimized away.

PROCEED WITH CAUTION.

  • (dribble)

Should I specify heap size?

symcl?

I was explaining some stuff to some new lisp guys about linear recurrences and ~ while also implementing it for fun, and the next second I found myself writing a small symbolics library. So far I've only done some pretty fast linear recurrences calculations (such as nth, sums, hadamar products) and also some operations on (integer) polynomials.

I'm lazy, so this is in a very dirty state -- no comments, not-the-best-naming, etc. (this is why I don't provide a link, I'm ashamed)
But if you think this is something that can go alongside numcl, I'll be glad to refactor it and show.

Option to turn off optimization: compile-speed matters

While working in slime, and using small data and examples (or even large!), I don't think run-time for very large arrays is anything of concern; rather compile-time feels like a big concern. For example, check the difference in the compile times of:

(defun foo (a b) (- a b))
(defun foo (a b) (numcl:- a b))

The second takes significantly longer to compile. And it would be great if an option is included to turn off such optimization. I don't want this to be the julia's time to first plot issue!

Thanks!

Some systems failed to build for Quicklisp dist

Building with SBCL 2.1.10 / ASDF 3.3.5 for quicklisp dist creation.

Trying to build commit id b4cdb25

numcl.test fails to build because of a failure in numcl.

numcl fails to build with the following error:

; caught WARNING:
;   * is not permitted as a type specifier
...
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING {1001C08103}>: COMPILE-FILE-ERROR while compiling #<CL-SOURCE-FILE "numcl" "src" "1type">

Full log here

linspace output from numcl is different to numpy

In numcl I get the following output from linspace:

(linspace 2.0 3.0 5)
#(2.0 2.2 2.4 2.6000001 2.8000002)
(linspace 2.0 3.0 5 :endpoint t)
#(2.0 2.1666667 2.3333335 2.5000002 2.666667 2.8333337)

which does not include the endpoints, whereas in numpy I get (note that endpoint=True is the default):

np.linspace(2.0, 3.0, 5)
array([2.  , 2.25, 2.5 , 2.75, 3.  ])
np.linspace(2.0, 3.0, 5, endpoint=True)
array([2.  , 2.25, 2.5 , 2.75, 3.  ])

Is this a bug in numcl?

The numpy documentation suggests using linspace instead of arange to ensure that endpoints are included but numcl uses arange inside the linspace function:

numcl/src/3arange.lisp

Lines 250 to 251 in 9ca804a

(arange start stop step :type type)
(arange start stop step))))

so there does not appear to be any benefit of using linspace over arange in numcl.

Adding two matrices together

Hello, thank you for this awesome project!

I was failing to find a way to add two matrices together like in pynum.
Can you please tell me how I would do that, if possible?

INFER-TYPE returns NIL

Probably this is similar about #42

* (lisp-implementation-type)

"SBCL"
* (lisp-implementation-version)

"2.0.5"
* (numcl:numcl-version)

"6cec166b198b6a024a63b4f36d366fc19b1de283"
* (numcl:* (numcl:asarray '(0.5 0.5)) (numcl:asarray '(0 1)))
Control stack guard page temporarily disabled: proceed with caution

debugger invoked on a SB-KERNEL::CONTROL-STACK-EXHAUSTED in thread
#<THREAD "main thread" RUNNING {1000898083}>:
  Control stack exhausted (no more space for function call frames).
This is probably due to heavily nested or infinitely recursive function
calls, or a tail call that SBCL cannot or has not optimized away.

PROCEED WITH CAUTION.

* (numcl.impl::infer-type '* 'single-float 'bit)

NIL
* (dribble)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.