Merge pull request #795 from zackmdavis/infix_matrix_multiplication

add support for Python 3.5 infix matrix multiplication
This commit is contained in:
Berker Peksag 2015-04-26 12:21:56 +03:00
commit 5106789f17
4 changed files with 68 additions and 2 deletions

View File

@ -42,6 +42,7 @@ PY27 = sys.version_info >= (2, 7)
PY3 = sys.version_info[0] >= 3 PY3 = sys.version_info[0] >= 3
PY33 = sys.version_info >= (3, 3) PY33 = sys.version_info >= (3, 3)
PY34 = sys.version_info >= (3, 4) PY34 = sys.version_info >= (3, 4)
PY35 = sys.version_info >= (3, 5)
if PY3: if PY3:
str_type = str str_type = str

View File

@ -38,7 +38,8 @@ from hy.models.cons import HyCons
from hy.errors import HyCompileError, HyTypeError from hy.errors import HyCompileError, HyTypeError
import hy.macros import hy.macros
from hy._compat import str_type, long_type, PY27, PY33, PY3, PY34, raise_empty from hy._compat import (
str_type, long_type, PY27, PY33, PY3, PY34, PY35, raise_empty)
from hy.macros import require, macroexpand, reader_macroexpand from hy.macros import require, macroexpand, reader_macroexpand
import hy.importer import hy.importer
@ -121,6 +122,13 @@ def builds(_type):
return _dec return _dec
def builds_if(_type, condition):
if condition:
return builds(_type)
else:
return lambda fn: fn
class Result(object): class Result(object):
""" """
Smart representation of the result of a hy->AST compilation Smart representation of the result of a hy->AST compilation
@ -1638,6 +1646,7 @@ class HyASTCompiler(object):
@builds("|") @builds("|")
@builds("^") @builds("^")
@builds("&") @builds("&")
@builds_if("@", PY35)
@checkargs(min=2) @checkargs(min=2)
def compile_maths_expression(self, expression): def compile_maths_expression(self, expression):
ops = {"+": ast.Add, ops = {"+": ast.Add,
@ -1652,6 +1661,8 @@ class HyASTCompiler(object):
"|": ast.BitOr, "|": ast.BitOr,
"^": ast.BitXor, "^": ast.BitXor,
"&": ast.BitAnd} "&": ast.BitAnd}
if PY35:
ops.update({"@": ast.MatMult})
inv = expression.pop(0) inv = expression.pop(0)
op = ops[inv] op = ops[inv]
@ -1711,6 +1722,7 @@ class HyASTCompiler(object):
@builds("|=") @builds("|=")
@builds("^=") @builds("^=")
@builds("&=") @builds("&=")
@builds_if("@=", PY35)
@checkargs(2) @checkargs(2)
def compile_augassign_expression(self, expression): def compile_augassign_expression(self, expression):
ops = {"+=": ast.Add, ops = {"+=": ast.Add,
@ -1725,6 +1737,8 @@ class HyASTCompiler(object):
"|=": ast.BitOr, "|=": ast.BitOr,
"^=": ast.BitXor, "^=": ast.BitXor,
"&=": ast.BitAnd} "&=": ast.BitAnd}
if PY35:
ops.update({"@=": ast.MatMult})
op = ops[expression[0]] op = ops[expression[0]]

View File

@ -45,7 +45,7 @@ long_description = """Hy is a Python <--> Lisp layer. It helps
make things work nicer, and lets Python and the Hy lisp variant play make things work nicer, and lets Python and the Hy lisp variant play
nice together. """ nice together. """
install_requires = ['rply>=0.7.0', 'astor>=0.3', 'clint>=0.4'] install_requires = ['rply>=0.7.0', 'astor>=0.5', 'clint>=0.4']
if sys.version_info[:2] < (2, 7): if sys.version_info[:2] < (2, 7):
install_requires.append('argparse>=1.2.1') install_requires.append('argparse>=1.2.1')
install_requires.append('importlib>=1.0.2') install_requires.append('importlib>=1.0.2')

View File

@ -1,3 +1,5 @@
(import [hy._compat [PY35]])
(setv square (fn [x] (setv square (fn [x]
(* x x))) (* x x)))
@ -140,3 +142,52 @@
(defn overflow-int-to-long [] (defn overflow-int-to-long []
"NATIVE: test if int does not raise an overflow exception" "NATIVE: test if int does not raise an overflow exception"
(assert (integer? (+ 1 1000000000000000000000000)))) (assert (integer? (+ 1 1000000000000000000000000))))
(defclass HyTestMatrix [list]
[[--matmul--
(fn [self other]
(let [[n (len self)]
[m (len (. other [0]))]
[result []]]
(for [i (range m)]
(let [[result-row []]]
(for [j (range n)]
(let [[dot-product 0]]
(for [k (range (len (. self [0])))]
(+= dot-product (* (. self [i] [k])
(. other [k] [j]))))
(.append result-row dot-product)))
(.append result result-row)))
result))]])
(def first-test-matrix (HyTestMatrix [[1 2 3]
[4 5 6]
[7 8 9]]))
(def second-test-matrix (HyTestMatrix [[2 0 0]
[0 2 0]
[0 0 2]]))
(def product-of-test-matrices (HyTestMatrix [[ 2 4 6]
[ 8 10 12]
[14 16 18]]))
(defn test-matmul []
"NATIVE: test matrix multiplication"
(if PY35
(assert (= (@ first-test-matrix second-test-matrix)
product-of-test-matrices))
;; Python <= 3.4
(let [[matmul-attempt (try (@ first-test-matrix second-test-matrix)
(catch [e [Exception]] e))]]
(assert (isinstance matmul-attempt NameError)))))
(defn test-augassign-matmul []
"NATIVE: test augmented-assignment matrix multiplication"
(let [[matrix first-test-matrix]
[matmul-attempt (try (@= matrix second-test-matrix)
(catch [e [Exception]] e))]]
(if PY35
(assert (= product-of-test-matrices matrix))
(assert (isinstance matmul-attempt NameError)))))