Skip to content

Commit

Permalink
update matrix exp
Browse files Browse the repository at this point in the history
  • Loading branch information
jcosborn committed Dec 12, 2022
1 parent 0c0bb94 commit 149678e
Show file tree
Hide file tree
Showing 9 changed files with 759 additions and 114 deletions.
92 changes: 54 additions & 38 deletions src/base/basicOps.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import macros

{.passL:"-lm".}

template getOptimPragmas* =
{.pragma: alwaysInline, inline,
codegenDecl: "inline __attribute__((always_inline)) $# $#$#".}
getOptimPragmas()

type
SomeInteger2* = int|int8|int16|int32|int64
SomeInteger3* = int|int8|int16|int32|int64
Expand All @@ -27,7 +32,9 @@ type
var FLT_EPSILON*{.importC,header:"<float.h>".}:float32
var DBL_EPSILON*{.importC,header:"<float.h>".}:float64
template epsilon*(x:float32):untyped = FLT_EPSILON
template epsilon*(x:typedesc[float32]):untyped = FLT_EPSILON
template epsilon*(x:float64):untyped = DBL_EPSILON
template epsilon*(x:typedesc[float64]):untyped = DBL_EPSILON
template basicNumberDefines(T,N,F) {.dirty.} =
template numberType*(x:T):untyped = F
template numberType*(x:typedesc[T]):untyped = F
Expand All @@ -46,6 +53,10 @@ template `[]`*[T](x:typedesc[ptr T]):untyped = T
template `[]`*(x:SomeNumber; i:SomeInteger):untyped = x
template isWrapper*(x: SomeNumber): untyped = false
template isWrapper*(x: typedesc[SomeNumber]): untyped = false
template eval*[T:SomeNumber](x: typedesc[T]): typedesc = typeof(T)
template evalType*[T](x: T): typedesc =
mixin eval
eval(typeof T)

template cnvrt(r,x):untyped = ((type(r))(x))
template to*(x:auto; t:typedesc[SomeNumber]):untyped =
Expand All @@ -67,16 +78,25 @@ template toDoubleImpl*(x:SomeNumber):untyped =
else:
float64(x)

template assign*(r: SomeNumber; x: ptr SomeNumber2) =
r = cnvrt(r,x[])
template assign*(r: SomeNumber, x: SomeNumber2) =
r = cnvrt(r,x)
template assign*[R,X:SomeNumber](r: R; x: ptr X) =
r = R(x[])
template assign*[R,X:SomeNumber](r: R, x: X) =
r = R(x)
template `:=`*[R,X:SomeNumber](r: R; x: X) =
r = R(x)
template `:=`*[R,X:SomeNumber](r: R; x: ptr X) =
r = R(x[])
#proc `+=`*[R,X:SomeNumber](r: var R; x: X) {.alwaysInline.} =
# r = r + R(x)
#proc `-=`*[R,X:SomeNumber](r: var R; x: X) {.alwaysInline.} =
# r = r - R(x)

template adj*(x: SomeNumber): untyped = x
template transpose*(x: SomeNumber): untyped = x
template inv*[T:SomeNumber](x: T): untyped = (T(1))/x

template neg*(r:var SomeNumber, x:SomeNumber2):untyped =
r = cnvrt(r,-x)
template neg*[R,X:SomeNumber](r: R, x: X) =
r := -x
template iadd*(r:var SomeNumber, x:SomeNumber2):untyped =
r += cnvrt(r,x)
template isub*(r:var SomeNumber, x:SomeNumber2):untyped =
Expand Down Expand Up @@ -129,14 +149,17 @@ template idot*(r:var SomeNumber; x:SomeNumber2;y:SomeNumber3):untyped =
template redot*(x:SomeNumber; y:SomeNumber2):untyped = x*y
template redotinc*(r:var SomeNumber; x:SomeNumber2; y:SomeNumber3):untyped =
r += x*y
#template simdLength*(x:SomeNumber):untyped = 1
template simdLength*(x:SomeNumber):untyped = 1
template simdLength*(x:typedesc[SomeNumber]):untyped = 1
template simdSum*(x:SomeNumber):untyped = x
template simdSum*[T:SomeNumber](r:var T; x:SomeNumber2):untyped =
r = T(x)
template simdMax*(x:SomeNumber):untyped = x
template simdReduce*(x:SomeNumber):untyped = x
template simdReduce*[T,X:SomeNumber](r:var T; x:X) =
r = T(x)
template simdMaxReduce*(x:SomeNumber):untyped = x
template simdMinReduce*(x:SomeNumber):untyped = x
template simdSum*(x:SomeNumber):untyped = simdReduce(x)
template simdSum*[T,X:SomeNumber](r:var T; x:X) = simdReduce(r,x)
template simdMax*(x:SomeNumber):untyped = simdMaxReduce(x)
template simdMin*(x:SomeNumber):untyped = simdMinReduce(x)
template perm1*(r:var SomeNumber; x:SomeNumber2):untyped =
r = (type(r))(x)
template perm2*(r:var SomeNumber; x:SomeNumber2):untyped =
Expand All @@ -150,19 +173,21 @@ template perm8*(r:var SomeNumber; x:SomeNumber2):untyped =
proc acos*(x:float64):float64 {.importC:"acos",header:"math.h".}
proc atan2*(x,y:float64):float64 {.importC:"atan2",header:"math.h".}
proc atan2*(x,y:float32):float32 {.importC:"atan2f",header:"math.h".}
template rsqrt*(r:var SomeNumber; x:SomeNumber) =
r = cnvrt(r,1)/sqrt(cnvrt(r,x))
template rsqrt*[T](x: T): untyped = 1/sqrt(x)
template rsqrt*[R,X:SomeNumber](r:var R; x:X) =
r = R(1)/sqrt(R(x))
template rsqrt*(x: SomeNumber): untyped = 1/sqrt(x)
template select*(c: bool, a,b: typed): untyped =
if c: a else: b

template load1*(x:SomeNumber):untyped = x

template tmpvar*(r:untyped; x:untyped):untyped =
mixin load1
var r{.noInit.}:type(load1(x))
var r{.noInit.}:evalType(load1(x))
template load2*(r:untyped, x:untyped):untyped =
mixin load1,assign
#tmpvar(r, x)
var r{.noInit.}:type(load1(x))
var r{.noInit.}:evalType(load1(x))
assign(r, x)
template store*(r:var untyped, x:untyped):untyped =
mixin assign
Expand All @@ -175,7 +200,6 @@ template load*(r:untyped, x:untyped):untyped =
mixin load2
load2(r, x)

template `:=`*(x: SomeNumber; y: SomeNumber2) = assign(x,y)
template `+`*(x:SomeFloat; y:SomeInteger):auto = x + cnvrt(x,y)
template `+`*(x:SomeInteger; y:SomeFloat):auto = cnvrt(y,x) + y
template `-`*(x:SomeFloat; y:SomeInteger):auto = x - cnvrt(x,y)
Expand All @@ -188,39 +212,28 @@ template `/`*[T:SomeFloat](x:T,y:SomeInteger):auto = x / (T(y))
template `:=`*[T](x: SomeNumber; y: array[1,T]) = assign(x,y[0])

template setUnopP*(op,fun,t1,t2: untyped): untyped {.dirty.} =
proc op*(x: t1): auto {.inline,noInit.} =
proc op*(x: t1): auto {.alwaysInline,noInit.} =
var r{.noInit.}: t2
fun(r, x)
r
template setUnopT*(op,fun,t1,t2: untyped): untyped {.dirty.} =
template op*(x: t1): untyped =
#subst(xt,xx,r,_):
# lets(x,xt):
#subst(r,_):
# lets(x,xx):
var r_setUnopT{.noInit.}: t2
fun(r_setUnopT, x)
r_setUnopT
var rSetUnopT{.noInit.}: t2
fun(rSetUnopT, x)
rSetUnopT

template setBinopP*(op,fun,t1,t2,t3: untyped): untyped {.dirty.} =
proc op*(x: t1; y: t2): auto {.inline,noInit.} =
#template op*(x: typedesc[t1]; y: typedesc[t2]): typedesc = t3
proc op*(x: t1; y: t2): auto {.alwaysInline,noInit.} =
var r{.noInit.}: t3
fun(r, x, y)
r
template setBinopT*(op,fun,t1,t2,t3: untyped) {.dirty.} =
#template op*(x: typedesc[t1]; y: typedesc[t2]): typedesc = t3
template op*(x: t1; y: t2): untyped =
#staticTraceBegin: op
#echoUntyped: setBinopT op
#echoType: xx
#echoType: yy
#echoUntyped: t3
#echoUntypedTree: t3
#let x = xx
#let y = yy
var r_setBinopT{.noInit.}: t3
fun(r_setBinopT, x, y)
#staticTraceEnd: op
r_setBinopT
var rSetBinopT{.noInit.}: t3
fun(rSetBinopT, x, y)
rSetBinopT

when forceInline:
template setUnop*(op,fun,t1,t2: untyped): untyped {.dirty.} =
Expand All @@ -233,6 +246,9 @@ else:
template setBinop*(op,fun,t1,t2,t3: untyped): untyped {.dirty.} =
setBinopP(op, fun, t1, t2, t3)

import numberWrap
export numberWrap

when isMainModule:
var d1,d2:float
var s1,s2:float32
Expand Down
69 changes: 69 additions & 0 deletions src/base/numberWrap.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
type
AsFloat32*[T] = distinct T
Float32* = float32 | AsFloat32
AsFloat64*[T] = distinct T
Float64* = float64 | AsFloat64
AsFloat* = AsFloat32 | AsFloat64
Float* = SomeFloat | AsFloat
AsNumber* = AsFloat
Number* = SomeNumber | AsNumber

template asFloat32*[T](x: T): untyped = AsFloat32[type T](x)
template `[]`*[T](x: AsFloat32[T]): untyped = (type T)(x)
template asWrapper*(x: typedesc[float32], y: typed): untyped = asFloat32(y)
template eval*(x: typedesc[AsFloat32]): typedesc = float32
template eval*(x: AsFloat32): untyped =
mixin `:=`
var r: float32
r := x[]
r
#converter toFloat32*(x: AsFloat32): float32 {.inline.} = eval(x)

template asFloat64*[T](x: T): untyped = AsFloat64[type T](x)
template `[]`*[T](x: AsFloat64[T]): untyped = (type T)(x)
template asWrapper*(x: typedesc[float64], y: typed): untyped = asFloat64(y)
template eval*(x: typedesc[AsFloat64]): typedesc = float64
template eval*(x: AsFloat64): untyped =
mixin `:=`
var r: float64
r := x[]
r

template liftUnary(fn: untyped) =
template fn*(x: AsNumber): untyped =
mixin fn
fn(eval(x))

liftUnary(exp)
liftUnary(ln)
liftUnary(norm2)

template liftBinary(fn: untyped) =
template fn*(x: AsNumber, y: SomeNumber): untyped =
mixin fn
fn(eval(x), y)
template fn*(x: SomeNumber, y: AsNumber): untyped =
mixin fn
fn(x, eval(y))
template fn*[X,Y:AsNumber](x: X, y: Y): untyped =
mixin fn
fn(eval(x), eval(y))

liftBinary(`+`)
liftBinary(`*`)

template liftBinaryInplace(fn: untyped) =
template fn*(x: AsNumber, y: SomeNumber) =
mixin fn
fn(x[], y)
template fn*(x: SomeNumber, y: AsNumber) =
mixin fn
fn(x, eval(y))
template fn*[X,Y:AsNumber](x: X, y: Y) =
mixin fn
fn(x[], eval(y))

liftBinaryInplace(`:=`)
liftBinaryInplace(assign)
liftBinaryInplace(`+=`)
liftBinaryInplace(`*=`)
2 changes: 2 additions & 0 deletions src/base/wrapperTypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ template makeWrapperTypeX(name,fName,asName,tasName: untyped) =
#name[type(tasName)](fName: tasName)
#Color[type(x_asColor)](x_asColor)
#Color(x_asColor)
template asName*[T](x: typedesc[T]): typedesc =
name[typeof T]
# flattenCallArgs(tasName, x)
#proc asName*[T](x: T): name[T] {.inline,noInit.} =
# result.fName = x
Expand Down
17 changes: 14 additions & 3 deletions src/maths/complexProxy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ type
# let yi = y.im
# newComplexP(xr*yr-xi*yi,xr*yi+xi*yr)

template asRealProxy*[T](x: T): auto = RealProxy[type T](v: x)
template asRealProxy*[T](x: typedesc[T]): typedesc = RealProxy[type T]
template asImagProxy*[T](x: T): auto = ImagProxy[type T](v: x)
template asImagProxy*[T](x: typedesc[T]): typedesc = ImagProxy[type T]
template asComplexProxy*[T](x: T): auto = ComplexProxy[type T](v: x)
template asComplexProxy*[T](x: typedesc[T]): typedesc = ComplexProxy[type T]

template `[]`*(x: RealProxy): untyped = x.v
macro `[]`*(x: RealProxy{nkObjConstr}): auto =
#echo x.treerepr
Expand All @@ -55,23 +62,27 @@ macro `[]`*(x: ComplexProxy{nkStmtListExpr}): untyped =
result.add x[i]
result.add newCall(ident"[]", x[^1])

template `[]=`*(x: RealProxy, y: typed): untyped =
template `[]=`*(x: RealProxy, y: typed) =
#when x.T is type(y):
# x.v = y
#else:
mixin `:=`
x.v := y
template `[]=`*(x: ImagProxy, y: typed): untyped =
template `[]=`*(x: ImagProxy, y: typed) =
#when x.T is type(y):
# x.v = y
#else:
x.v := y
template `[]=`*(x: ComplexProxy, y: typed): untyped =
template `[]=`*(x: ComplexProxy, y: typed) =
#when x.T is type(y):
# x.v = y
#else:
x.v := y

template eval*[T](x: typedesc[ComplexProxy[T]]): typedesc =
mixin eval
asComplexProxy(eval typeof T)

proc `$`*(x: RealProxy): string =
result = $x[]
proc `$`*(x: ImagProxy): string =
Expand Down
10 changes: 8 additions & 2 deletions src/maths/complexType.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ type
ComplexT*[T] = ComplexTT[T,T]
ComplexType*[T] = ComplexT[T]

template newComplexObj*[TR,TI](x: TR, y: TI): untyped =
ComplexObj[type(TR),type(TI)](reX: x, imX: y)
template complexObj*[TR,TI](x: TR, y: TI): untyped =
ComplexObj[typeof(TR),typeof(TI)](reX: x, imX: y)
template complexObj*[TR,TI](x: typedesc[TR], y: typedesc[TI]): typedesc =
ComplexObj[typeof(TR),typeof(TI)]
template newComplexObj*[TR,TI](x: TR, y: TI): untyped = complexObj(x, y)

template newRealImpl*(x: typed): untyped = x
template newImagImpl*(x: typed): untyped = newImagProxy(x)
Expand Down Expand Up @@ -139,6 +142,9 @@ template load1*(x: ImagProxy): untyped = x
template eval*(xx: ComplexProxy): untyped =
let x = xx[]
newComplex(eval(x.re),eval(x.im))
template eval*[TR,TI](x: typedesc[ComplexObj[TR,TI]]): typedesc =
mixin eval
complexObj(eval(typeof TR), eval(typeof TI))

template map*(xx: ComplexProxy; f: untyped): untyped =
#let fr = f(x.re)
Expand Down
Loading

0 comments on commit 149678e

Please sign in to comment.