diff --git a/src/physics/color.nim b/src/physics/color.nim index 91dc40d..5d697c4 100644 --- a/src/physics/color.nim +++ b/src/physics/color.nim @@ -1,289 +1,5 @@ -import base/basicOps -import base/wrapperTypes -export wrapperTypes -import maths/types -import maths -import simd/simdWrap +import colorOld +export colorOld -makeWrapperType(Color): - ## wrapper type for colored objects - -type - Color2*[T] = Color[T] - Color3*[T] = Color[T] - Color4*[T] = Color[T] - -template asVarWrapper*(x: Color, y: typed): untyped = - #static: echo "asVarWrapper Color" - #var cy = asColor(y) - #cy - asVar(asColor(y)) - -template index*[T,I](x: typedesc[Color[T]], i: typedesc[I]): typedesc = - when I is Color: - index(T.type, I.type[]) - elif I.isWrapper: - Color[index(T.type, I.type)] - else: - index(T.type, I.type) - -template `[]`*[T](x: Color, i: T): untyped = - when T is Color: - x[][i[]] - elif T.isWrapper: - #indexed(x, i) - var tColorBracket = asColor(x[][i]) - tColorBracket - else: - x[][i] -template `[]`*(x: Color, i,j: SomeInteger): auto = x[][i,j] - -#[ -template `[]=`*[T](x: Color, i:T, y: typed): untyped = - when T.isWrapper and T isnot Color: - x[][asScalar(i)] = y - else: - x[][i] = y -]# -template `[]=`*[T](x: Color, i: T; y: auto) = - when T is Color2: - x[][i[]] = y - elif T.isWrapper: - #indexed(x, i) - var tColorBracket = asColor(x[][i]) - tColorBracket := y - else: - x[][i] = y -template `[]=`*(x: Color, i,j: SomeInteger, y: auto) = - x[][i,j] = y - -# forward from value to value -template forwardVV(f: untyped) {.dirty.} = - template f*(x: Color): auto = - mixin f - f(x[]) -# forward from value to type -#template forwardVT(f: untyped) {.dirty.} = -# template f*[T](x: Color[T]): untyped = -# mixin f -# f(type T) -# forward from type to type -template forwardTT(f: untyped) {.dirty.} = - template f*[T](x: typedesc[Color[T]]): auto = - mixin f - f(type T) -# forward from type to type and wrap -template forwardTTW(f: untyped) {.dirty.} = - template f*[T](x: typedesc[Color[T]]): auto = - mixin f - Color[f(type T)] - -forwardVV(len) -forwardVV(nrows) -forwardVV(ncols) -forwardVV(nVectors) -forwardVV(simdType) -#forwardVV(simdLength) -forwardVV(getNs) -forwardVV(numNumbers) - -forwardTT(len) -forwardTT(nrows) -forwardTT(ncols) -forwardTT(nVectors) -forwardTT(simdType) -forwardTT(simdLength) -forwardTT(getNs) -forwardTT(numberType) - -forwardTTW(toSingle) -forwardTTW(toDouble) - -#template eval*[T](x: typedesc[Color[T]]): typedesc = asColor(eval(type T)) -template eval*[T:Color](x: typedesc[T]): typedesc = asColor(eval((type T)[])) - -template has*[T:Color](x: typedesc[T], y: typedesc): bool = - mixin has - when y is Color: true - else: has(T.type[], y) - -template row*(x: Color, i: untyped): untyped = - mixin row - asColor(row(x[],i)) -template setRow*(r: Color; x: Color2; i: untyped): untyped = - setRow(r[], x[], i) - -template getNc*[T](x: Color[T]): untyped = - when T is Mat1: - x[].nrows - elif T is Vec1: - x[].len - else: - static: - echo "error: unknown Nc" - echo x.repr - echo type(x).name - qexExit 1 - 0 - -template binDDRet(fn,wr,T1,T2) = - template fn*(x: T1, y: T2): untyped = - wr(fn(x[], y[])) - #template fn*(x: T1, y: T2): auto = - # var tmp {.noInit.}: wr(evalType(fn(x[],y[])) - # wr(fn(x[], y[])) - -#binDDRet(`+`, asColor, Color, Color2) -binDDRet(`-`, asColor, Color, Color2) -#binDDRet(`*`, asColor, Color, Color2) -binDDRet(`/`, asColor, Color, Color2) - -setBinop(`+`, add, Color, Color2, asColor(evalType(x[]+y[]))) -setBinop(`*`, mul, Color, Color2, asColor(evalType(x[]*y[]))) - -template load1*(x: Color): untyped = asColor(load1(x[])) -template `-`*(x: Color): untyped = asColor(-(x[])) -template assign*(r: var Color, x: SomeNumber) = - assign(r[], x) -template assign*(r: var Color, x: AsComplex) = - assign(r[], x) -template assign*(r: var Color, x: Color2) = - assign(r[], x[]) -template `:=`*(r: var Color, x: SomeNumber) = - r[] := x -template `:=`*(r: var Color, x: AsComplex) = - r[] := x -template `:=`*(r: var Color, x: Color2) = - r[] := x[] -template `+=`*(r: var Color, x: Color2) = - r[] += x[] -template `-=`*(r: var Color, x: Color2) = - r[] -= x[] -template `*=`*(r: var Color, x: SomeNumber) = - r[] *= x -template iadd*(r: var Color, x: SomeNumber) = - iadd(r[], x) -template iadd*(r: var Color, x: AsComplex) = - iadd(r[], x) -template iadd*(r: var Color, x: Color2) = - iadd(r[], x[]) -template isub*(r: var Color, x: SomeNumber) = - isub(r[], x) -template isub*(r: var Color, x: Color2) = - isub(r[], x[]) -template imul*(r: var Color, x: SomeNumber) = - imul(r[], x) -template imadd*(r: var Color, x: Color2, y: Color3) = - imadd(r[], x[], y[]) -template imadd*(r: var Color, x: AsComplex, y: Color3) = - imadd(r[], x, y[]) -template imsub*(r: var Color, x: Color2, y: Color3) = - imsub(r[], x[], y[]) -template peqOuter*(r: var Color, x: Color2, y: Color3) = - peqOuter(r[], x[], y[]) -template meqOuter*(r: var Color, x: Color2, y: Color3) = - meqOuter(r[], x[], y[]) -template `+`*(r: Color, x: SomeNumber): untyped = - asColor(r[] + x) -template `+`*(r: SomeNumber, x: Color): untyped = - asColor(r + x[]) -template `-`*(r: Color, x: SomeNumber): untyped = - asColor(r[] - x) -template `+`*(r: Color, x: AsComplex): untyped = - asColor(r[] + x) -template `-`*(r: Color, x: AsComplex): untyped = - asColor(r[] - x) -template add*(r: var Color, x: Color2, y: Color3) = - add(r[], x[], y[]) -template sub*(r: var Color, x: Color2, y: Color3) = - sub(r[], x[], y[]) -template `*`*(x: Color, y: SomeNumber): untyped = - asColor(x[] * y) -#template `*`*(x: SomeNumber, y: Color): auto = - #asColor(x * y[]) -template `*`*[X:SomeNumber,Y:Color](x: X, y: Y): auto = - #static: echo "SomeNumber * Color" - #var tmp {.noInit.}: asColor(type(X)*type(Y)[]) - var tmp {.noInit.}: asColor(evalType(x*y[])) - #static: echo $type(tmp) - mul(tmp[], x, y[]) - tmp -template `*`*(x: Simd, y: Color2): untyped = - asColor(x * y[]) -#template `*`*(x: AsReal, y: Color2): untyped = -# asColor(x * y[]) -template `*`*[X:AsReal,Y:Color](x: X, y: Y): auto = - #var tmp {.noInit.}: asColor(type(X)*type(Y)[]) - var tmp {.noInit.}: asColor(evalType(x*y[])) - mul(tmp[], x, y[]) - tmp -template `*`*(x: AsImag, y: Color2): untyped = - asColor(x * y[]) -template `*`*(x: AsComplex, y: Color2): untyped = - asColor(x * y[]) -template `*`*(x: Color, y: AsComplex): untyped = - asColor(x[] * y) -#template mul*(x: SomeNumber, y: Color2): untyped = -# asColor(`*`(x, y[])) -template mul*[X:SomeNumber,Y:Color](x: X, y: Y): auto = - #var tmp {.noInit.}: asColor(type(X)*type(Y)[]) - var tmp {.noInit.}: asColor(evalType(x*y[])) - mul(tmp[], x, y[]) - tmp -template mul*(x: Color, y: Color2): untyped = - asColor(`*`(x[], y[])) -template mul*(r: var Color, x: Color2, y: Color3) = - mul(r[], x[], y[]) -template mul*(r: var Color, x: SomeNumber, y: Color3) = - mul(r[], x, y[]) -template mul*(r: var Color, x: Color2, y: SomeNumber) = - mul(r[], x[], y) -template mul*(r: var Color, x: AsComplex, y: Color3) = - mul(r[], x, y[]) -template mul*(x: AsComplex, y: Color2): untyped = - asColor(mul(x, y[])) -template random*(x: var Color) = - gaussian(x[], r) -template gaussian*(x: Color, r: untyped) = - gaussian(x[], r) -template uniform*(x: var Color, r: var untyped) = - uniform(x[], r) -template z4*(x: var Color, r: var untyped) = - z4(x[], r) -template z2*(x: var Color, r: var untyped) = - z2(x[], r) -template u1*(x: var Color, r: var untyped) = - u1(x[], r) -template projectU*(r: var Color) = - projectU(r[]) -template projectU*(r: var Color, x: Color2) = - projectU(r[], x[]) -template projectUderiv*(r: var Color, u: Color2, x: Color3, chain: Color4) = - projectUderiv(r[], u[], x[], chain[]) -template projectUderiv*(r: var Color, x: Color3, chain: Color4) = - projectUderiv(r[], x[], chain[]) -template projectSU*(r: var Color) = - projectSU(r[]) -template projectSU*(r: var Color, x: Color2) = - projectSU(r[], x[]) -template projectTAH*(r: var Color) = - projectTAH(r[]) -template projectTAH*(r: var Color, x: Color2) = - projectTAH(r[], x[]) -template checkU*(x: Color):untyped = checkU(x[]) -template checkSU*(x: Color):untyped = checkSU(x[]) -template norm2*(x: Color): untyped = norm2(x[]) -template norm2*(r: var auto, x: Color): untyped = norm2(r, x[]) -template inorm2*(r: var auto, x: Color2) = inorm2(r, x[]) -template dot*(x: Color, y: Color2): untyped = - dot(x[], y[]) -template idot*(r: var auto, x: Color2, y: Color3) = idot(r, x[], y[]) -template redot*(x: Color, y: Color2): untyped = - redot(x[], y[]) -template trace*(x: Color): untyped = trace(x[]) -template simdSum*(x: Color): untyped = asColor(simdSum(x[])) -template re*(x: Color): untyped = asColor(re(x[])) -template im*(x: Color): untyped = asColor(im(x[])) -template exp*(x: Color): untyped = asColor(exp(x[])) -template expDeriv*(x: Color, c: Color2): untyped = asColor(expDeriv(x[], c[])) -template ln*(x: Color): untyped = asColor(ln(x[])) +#import colorTensor +#export colorTensor diff --git a/src/physics/colorOld.nim b/src/physics/colorOld.nim new file mode 100644 index 0000000..91dc40d --- /dev/null +++ b/src/physics/colorOld.nim @@ -0,0 +1,289 @@ +import base/basicOps +import base/wrapperTypes +export wrapperTypes +import maths/types +import maths +import simd/simdWrap + +makeWrapperType(Color): + ## wrapper type for colored objects + +type + Color2*[T] = Color[T] + Color3*[T] = Color[T] + Color4*[T] = Color[T] + +template asVarWrapper*(x: Color, y: typed): untyped = + #static: echo "asVarWrapper Color" + #var cy = asColor(y) + #cy + asVar(asColor(y)) + +template index*[T,I](x: typedesc[Color[T]], i: typedesc[I]): typedesc = + when I is Color: + index(T.type, I.type[]) + elif I.isWrapper: + Color[index(T.type, I.type)] + else: + index(T.type, I.type) + +template `[]`*[T](x: Color, i: T): untyped = + when T is Color: + x[][i[]] + elif T.isWrapper: + #indexed(x, i) + var tColorBracket = asColor(x[][i]) + tColorBracket + else: + x[][i] +template `[]`*(x: Color, i,j: SomeInteger): auto = x[][i,j] + +#[ +template `[]=`*[T](x: Color, i:T, y: typed): untyped = + when T.isWrapper and T isnot Color: + x[][asScalar(i)] = y + else: + x[][i] = y +]# +template `[]=`*[T](x: Color, i: T; y: auto) = + when T is Color2: + x[][i[]] = y + elif T.isWrapper: + #indexed(x, i) + var tColorBracket = asColor(x[][i]) + tColorBracket := y + else: + x[][i] = y +template `[]=`*(x: Color, i,j: SomeInteger, y: auto) = + x[][i,j] = y + +# forward from value to value +template forwardVV(f: untyped) {.dirty.} = + template f*(x: Color): auto = + mixin f + f(x[]) +# forward from value to type +#template forwardVT(f: untyped) {.dirty.} = +# template f*[T](x: Color[T]): untyped = +# mixin f +# f(type T) +# forward from type to type +template forwardTT(f: untyped) {.dirty.} = + template f*[T](x: typedesc[Color[T]]): auto = + mixin f + f(type T) +# forward from type to type and wrap +template forwardTTW(f: untyped) {.dirty.} = + template f*[T](x: typedesc[Color[T]]): auto = + mixin f + Color[f(type T)] + +forwardVV(len) +forwardVV(nrows) +forwardVV(ncols) +forwardVV(nVectors) +forwardVV(simdType) +#forwardVV(simdLength) +forwardVV(getNs) +forwardVV(numNumbers) + +forwardTT(len) +forwardTT(nrows) +forwardTT(ncols) +forwardTT(nVectors) +forwardTT(simdType) +forwardTT(simdLength) +forwardTT(getNs) +forwardTT(numberType) + +forwardTTW(toSingle) +forwardTTW(toDouble) + +#template eval*[T](x: typedesc[Color[T]]): typedesc = asColor(eval(type T)) +template eval*[T:Color](x: typedesc[T]): typedesc = asColor(eval((type T)[])) + +template has*[T:Color](x: typedesc[T], y: typedesc): bool = + mixin has + when y is Color: true + else: has(T.type[], y) + +template row*(x: Color, i: untyped): untyped = + mixin row + asColor(row(x[],i)) +template setRow*(r: Color; x: Color2; i: untyped): untyped = + setRow(r[], x[], i) + +template getNc*[T](x: Color[T]): untyped = + when T is Mat1: + x[].nrows + elif T is Vec1: + x[].len + else: + static: + echo "error: unknown Nc" + echo x.repr + echo type(x).name + qexExit 1 + 0 + +template binDDRet(fn,wr,T1,T2) = + template fn*(x: T1, y: T2): untyped = + wr(fn(x[], y[])) + #template fn*(x: T1, y: T2): auto = + # var tmp {.noInit.}: wr(evalType(fn(x[],y[])) + # wr(fn(x[], y[])) + +#binDDRet(`+`, asColor, Color, Color2) +binDDRet(`-`, asColor, Color, Color2) +#binDDRet(`*`, asColor, Color, Color2) +binDDRet(`/`, asColor, Color, Color2) + +setBinop(`+`, add, Color, Color2, asColor(evalType(x[]+y[]))) +setBinop(`*`, mul, Color, Color2, asColor(evalType(x[]*y[]))) + +template load1*(x: Color): untyped = asColor(load1(x[])) +template `-`*(x: Color): untyped = asColor(-(x[])) +template assign*(r: var Color, x: SomeNumber) = + assign(r[], x) +template assign*(r: var Color, x: AsComplex) = + assign(r[], x) +template assign*(r: var Color, x: Color2) = + assign(r[], x[]) +template `:=`*(r: var Color, x: SomeNumber) = + r[] := x +template `:=`*(r: var Color, x: AsComplex) = + r[] := x +template `:=`*(r: var Color, x: Color2) = + r[] := x[] +template `+=`*(r: var Color, x: Color2) = + r[] += x[] +template `-=`*(r: var Color, x: Color2) = + r[] -= x[] +template `*=`*(r: var Color, x: SomeNumber) = + r[] *= x +template iadd*(r: var Color, x: SomeNumber) = + iadd(r[], x) +template iadd*(r: var Color, x: AsComplex) = + iadd(r[], x) +template iadd*(r: var Color, x: Color2) = + iadd(r[], x[]) +template isub*(r: var Color, x: SomeNumber) = + isub(r[], x) +template isub*(r: var Color, x: Color2) = + isub(r[], x[]) +template imul*(r: var Color, x: SomeNumber) = + imul(r[], x) +template imadd*(r: var Color, x: Color2, y: Color3) = + imadd(r[], x[], y[]) +template imadd*(r: var Color, x: AsComplex, y: Color3) = + imadd(r[], x, y[]) +template imsub*(r: var Color, x: Color2, y: Color3) = + imsub(r[], x[], y[]) +template peqOuter*(r: var Color, x: Color2, y: Color3) = + peqOuter(r[], x[], y[]) +template meqOuter*(r: var Color, x: Color2, y: Color3) = + meqOuter(r[], x[], y[]) +template `+`*(r: Color, x: SomeNumber): untyped = + asColor(r[] + x) +template `+`*(r: SomeNumber, x: Color): untyped = + asColor(r + x[]) +template `-`*(r: Color, x: SomeNumber): untyped = + asColor(r[] - x) +template `+`*(r: Color, x: AsComplex): untyped = + asColor(r[] + x) +template `-`*(r: Color, x: AsComplex): untyped = + asColor(r[] - x) +template add*(r: var Color, x: Color2, y: Color3) = + add(r[], x[], y[]) +template sub*(r: var Color, x: Color2, y: Color3) = + sub(r[], x[], y[]) +template `*`*(x: Color, y: SomeNumber): untyped = + asColor(x[] * y) +#template `*`*(x: SomeNumber, y: Color): auto = + #asColor(x * y[]) +template `*`*[X:SomeNumber,Y:Color](x: X, y: Y): auto = + #static: echo "SomeNumber * Color" + #var tmp {.noInit.}: asColor(type(X)*type(Y)[]) + var tmp {.noInit.}: asColor(evalType(x*y[])) + #static: echo $type(tmp) + mul(tmp[], x, y[]) + tmp +template `*`*(x: Simd, y: Color2): untyped = + asColor(x * y[]) +#template `*`*(x: AsReal, y: Color2): untyped = +# asColor(x * y[]) +template `*`*[X:AsReal,Y:Color](x: X, y: Y): auto = + #var tmp {.noInit.}: asColor(type(X)*type(Y)[]) + var tmp {.noInit.}: asColor(evalType(x*y[])) + mul(tmp[], x, y[]) + tmp +template `*`*(x: AsImag, y: Color2): untyped = + asColor(x * y[]) +template `*`*(x: AsComplex, y: Color2): untyped = + asColor(x * y[]) +template `*`*(x: Color, y: AsComplex): untyped = + asColor(x[] * y) +#template mul*(x: SomeNumber, y: Color2): untyped = +# asColor(`*`(x, y[])) +template mul*[X:SomeNumber,Y:Color](x: X, y: Y): auto = + #var tmp {.noInit.}: asColor(type(X)*type(Y)[]) + var tmp {.noInit.}: asColor(evalType(x*y[])) + mul(tmp[], x, y[]) + tmp +template mul*(x: Color, y: Color2): untyped = + asColor(`*`(x[], y[])) +template mul*(r: var Color, x: Color2, y: Color3) = + mul(r[], x[], y[]) +template mul*(r: var Color, x: SomeNumber, y: Color3) = + mul(r[], x, y[]) +template mul*(r: var Color, x: Color2, y: SomeNumber) = + mul(r[], x[], y) +template mul*(r: var Color, x: AsComplex, y: Color3) = + mul(r[], x, y[]) +template mul*(x: AsComplex, y: Color2): untyped = + asColor(mul(x, y[])) +template random*(x: var Color) = + gaussian(x[], r) +template gaussian*(x: Color, r: untyped) = + gaussian(x[], r) +template uniform*(x: var Color, r: var untyped) = + uniform(x[], r) +template z4*(x: var Color, r: var untyped) = + z4(x[], r) +template z2*(x: var Color, r: var untyped) = + z2(x[], r) +template u1*(x: var Color, r: var untyped) = + u1(x[], r) +template projectU*(r: var Color) = + projectU(r[]) +template projectU*(r: var Color, x: Color2) = + projectU(r[], x[]) +template projectUderiv*(r: var Color, u: Color2, x: Color3, chain: Color4) = + projectUderiv(r[], u[], x[], chain[]) +template projectUderiv*(r: var Color, x: Color3, chain: Color4) = + projectUderiv(r[], x[], chain[]) +template projectSU*(r: var Color) = + projectSU(r[]) +template projectSU*(r: var Color, x: Color2) = + projectSU(r[], x[]) +template projectTAH*(r: var Color) = + projectTAH(r[]) +template projectTAH*(r: var Color, x: Color2) = + projectTAH(r[], x[]) +template checkU*(x: Color):untyped = checkU(x[]) +template checkSU*(x: Color):untyped = checkSU(x[]) +template norm2*(x: Color): untyped = norm2(x[]) +template norm2*(r: var auto, x: Color): untyped = norm2(r, x[]) +template inorm2*(r: var auto, x: Color2) = inorm2(r, x[]) +template dot*(x: Color, y: Color2): untyped = + dot(x[], y[]) +template idot*(r: var auto, x: Color2, y: Color3) = idot(r, x[], y[]) +template redot*(x: Color, y: Color2): untyped = + redot(x[], y[]) +template trace*(x: Color): untyped = trace(x[]) +template simdSum*(x: Color): untyped = asColor(simdSum(x[])) +template re*(x: Color): untyped = asColor(re(x[])) +template im*(x: Color): untyped = asColor(im(x[])) +template exp*(x: Color): untyped = asColor(exp(x[])) +template expDeriv*(x: Color, c: Color2): untyped = asColor(expDeriv(x[], c[])) +template ln*(x: Color): untyped = asColor(ln(x[])) diff --git a/src/physics/spin.nim b/src/physics/spin.nim index 2798cd9..2a07f1b 100644 --- a/src/physics/spin.nim +++ b/src/physics/spin.nim @@ -1,489 +1,5 @@ -import base/wrapperTypes -import maths/types -import maths +import spinOld +export spinOld -makeWrapperType(Spin): - ## wrapper type for spin objects - -type - #Spin*[T] = object - # v*: T - Spin2*[T] = Spin[T] - Spin3*[T] = Spin[T] - #SpinMatrix[I,J:static[int],T] = Spin[MatrixArray[I,J,T]] - -#template asSpin*(xx: typed): untyped = -# #staticTraceBegin: asSpin -# let x_asSpin = xx -# #staticTraceEnd: asSpin -# Spin[type(x_asSpin)](v: x_asSpin) - -#template isWrapper*(x: Spin): untyped = true -#template asWrapper*(x: Spin, y: typed): untyped = -# asSpin(y) -template asVarWrapper*(x: Spin, y: typed): untyped = - asVar(asSpin(y)) - -template index*[T,I](x: typedesc[Spin[T]], i: typedesc[I]): typedesc = - when I is Spin: - index(T.type, I.type[]) - elif I.isWrapper: - Spin[index(T.type, I.type)] - else: - index(T.type, I.type) - -template `[]`*[T](x: Spin, i: T): untyped = - when T is Spin2: - x[][i[]] - elif T.isWrapper: - #indexed(x, i) - var tSpinBracket = asSpin(x[][i]) - tSpinBracket - else: - x[][i] -template `[]`*(x: Spin, i,j: typed): untyped = x[][i,j] -#template `[]=`*[T](x: Spin, i: T; y: typed) = -proc `[]=`*[T](x: var Spin, i: T; y: auto) = - when T is Spin2: - x[][i[]] = y - elif T.isWrapper: - #indexed(x, i) - var tSpinBracket = asSpin(x[][i]) - tSpinBracket := y - else: - x[][i] = y -template `[]=`*(x: Spin, i,j,y: typed) = - x[][i,j] = y - -# forward from type to type -template forwardTT(f: untyped) {.dirty.} = - template f*[T](x: typedesc[Spin[T]]): auto = - mixin f - f(type T) -# forward from type to type and wrap -template forwardTTW(f: untyped) {.dirty.} = - template f*[T](x: typedesc[Spin[T]]): auto = - mixin f - Spin[f(type T)] - -forwardFunc(Spin, len) -forwardFunc(Spin, nrows) -forwardFunc(Spin, ncols) -forwardFunc(Spin, getNc) -forwardFunc(Spin, numberType) -forwardFunc(Spin, numNumbers) -forwardFunc(Spin, nVectors) -forwardFunc(Spin, simdType) -forwardFunc(Spin, simdLength) - -forwardTT(len) -forwardTT(nrows) -forwardTT(ncols) -forwardTT(nVectors) -forwardTT(simdType) -forwardTT(simdLength) -forwardTT(getNc) -forwardTT(numberType) - -forwardTTW(toSingle) -forwardTTW(toDouble) - -template eval*[T](x: typedesc[Spin[T]]): typedesc = asSpin(eval(type T)) - -template has*[T](x: typedesc[Spin[T]], y: typedesc): bool = - mixin has - when y is Spin2: - true - else: - has(type T, y) - -template row*(x: Spin, i: typed): untyped = - mixin row - asSpin(row(x[],i)) -template setRow*(r: Spin; x: Spin2; i: int): untyped = - setRow(r[], x[], i) - -template getNs*[T](x: Spin[T]): auto = - when T is Mat1: - x[].nrows - elif T is Vec1: - x[].len - else: - static: - echo "error: unknown Nc" - echo x.repr - echo type(x).name - qexExit 1 - 0 - -template binDDRet(fn,wr,T1,T2) = - template fn*(x: T1, y: T2): untyped = - #echoUntyped: fn - wr(fn(x[], y[])) - -binDDRet(`+`, asSpin, Spin, Spin2) -binDDRet(`-`, asSpin, Spin, Spin2) -binDDRet(`*`, asSpin, Spin, Spin2) -binDDRet(`/`, asSpin, Spin, Spin2) - -#template numberType*[T](x: typedesc[Spin[T]]): untyped = numberType(type(T)) -#template numNumbers*[T](x: typedesc[Spin[T]]): untyped = numberType(T) -#template numNumbers*(x: Spin): untyped = numNumbers(x[]) -#template toSingle*[T](x: typedesc[Spin[T]]): untyped = Spin[toSingle(type(T))] -template load1*(x: Spin): untyped = asSpin(load1(x[])) -template assign*(r: var Spin, x: SomeNumber) = - assign(r[], x) -template assign*(r: var Spin, x: AsComplex) = - assign(r[], x) -template assign*(r: var Spin, x: Spin2) = - assign(r[], x[]) -template `:=`*(r: var Spin, x: SomeNumber) = - `:=`(r[], x) -template `:=`*(r: var Spin, x: Spin2) = - r[] := x[] -template `+=`*(r: var Spin, x: Spin2) = - staticTraceBegin: peqSpinSpin - r[] += x[] - staticTraceEnd: peqSpinSpin -template `-=`*(r: var Spin, x: Spin2) = - r[] -= x[] -template `*=`*(r: var Spin, x: SomeNumber) = - `*=`(r[], x) -template iadd*(r: var Spin, x: AsComplex) = - iadd(r[], x) -template iadd*(r: var Spin, x: Spin2) = - iadd(r[], x[]) -template isub*(r: var Spin, x: Spin2) = - isub(r[], x[]) -template imul*(r: var Spin, x: SomeNumber) = - imul(r[], x) -template imadd*(r: var Spin, x: Spin2, y: Spin3) = - imadd(r[], x[], y[]) -template imsub*(r: var Spin, x: Spin2, y: Spin3) = - imsub(r[], x[], y[]) -template `*`*(x: Spin, y: SomeNumber): untyped = - asSpin(x[] * y) -template `*`*(x: SomeNumber, y: Spin2): untyped = - asSpin(x * y[]) -template `*`*(x: AsComplex, y: Spin2): untyped = - asSpin(x * y[]) -template sub*(r: var Spin, x: Spin2, y: Spin3) = - sub(r[], x[], y[]) -template mul*(r: var Spin, x: Spin2, y: Spin3) = - mul(r[], x[], y[]) -template random*(x: var Spin) = - gaussian(x[], r) -template gaussian*(x: var Spin, r: var untyped) = - gaussian(x[], r) -template uniform*(x: var Spin, r: var untyped) = - uniform(x[], r) -template z4*(x: var Spin, r: var untyped) = - z4(x[], r) -template z2*(x: var Spin, r: var untyped) = - z2(x[], r) -template u1*(x: var Spin, r: var untyped) = - u1(x[], r) -template projectU*(r: var Spin, x: Spin2) = - projectU(r[], x[]) -template norm2*(x: Spin): untyped = norm2(x[]) -template inorm2*(r: var typed, x: Spin2) = inorm2(r, x[]) -template dot*(x: Spin, y: Spin2): untyped = - dot(x[], y[]) -template idot*(r: var typed, x: Spin2, y: Spin3) = idot(r, x[], y[]) -template redot*(x: Spin, y: Spin2): untyped = - redot(x[], y[]) -template trace*(x: Spin): untyped = trace(x[]) - -template spinVector*(x: static[int], a: untyped): untyped = - #const - # I:int = x - #type - # E = T - # VA = VectorArray[I,E] - # VAO = VectorArrayObj[I,E] - #Spin[VA](v: VA(v: a)) - #Spin[VA](v: VA(v: VAO(vec: a))) - #asSpin(VA(v: a)) - #static: echo "spinVector" - asSpin(asVectorArray(a)) - #let t1 = asVectorArray(a) - #static: echo "spinVector1" - #let t = asSpin(t1) - #static: echo "spinVector2" - #t -template spinVector*[T](x: static[int], a: typedesc[T]): untyped = - asSpin(asVectorArray(x, type T)) -template spinMatrix*[T](x,y:static[int], a: untyped): untyped = - const - I:int = x - J:int = y - type - E = T - #MA = MatrixArray[I,J,E] - MAO = MatrixArrayObj[I,J,E] - asSpin(asMatrix(MAO(mat: a))) -#template spinMatrix*[I,J:static[int],T](a: untyped): untyped = -# Spin[MatrixArray[I,J,T]](v: MatrixArray[I,J,T](v: MatrixArrayObj[I,J,T](mat: a))) -#template spinMatrix*(I,J,T,a: untyped): untyped = -# Spin[MatrixArray[I,J,T]](v: MatrixArray[I,J,T](v: MatrixArrayObj[I,J,T](mat: a))) - -const z0 = newComplex( 0.0, 0.0) -const z1 = newComplex( 1.0, 0.0) -const zi = newComplex( 0.0, 1.0) -const n1 = newComplex(-1.0, 0.0) -const ni = newComplex( 0.0, -1.0) - -template s(r,c,x: untyped): untyped = - spinMatrix[ComplexType[float]](r,c,x) -template g(x: untyped): untyped = s(4,4,x) -template p(x: untyped): untyped = s(2,4,x) -template r(x: untyped): untyped = s(4,2,x) - -const - gamma0* = g([[ z1, z0, z0, z0 ], - [ z0, z1, z0, z0 ], - [ z0, z0, z1, z0 ], - [ z0, z0, z0, z1 ]]) - gamma1* = g([[ z0, z0, z0, zi ], - [ z0, z0, zi, z0 ], - [ z0, ni, z0, z0 ], - [ ni, z0, z0, z0 ]]) - gamma2* = g([[ z0, z0, z0, n1 ], - [ z0, z0, z1, z0 ], - [ z0, z1, z0, z0 ], - [ n1, z0, z0, z0 ]]) - gamma3* = g([[ z0, z0, zi, z0 ], - [ z0, z0, z0, ni ], - [ ni, z0, z0, z0 ], - [ z0, zi, z0, z0 ]]) - gamma4* = g([[ z0, z0, z1, z0 ], - [ z0, z0, z0, z1 ], - [ z1, z0, z0, z0 ], - [ z0, z1, z0, z0 ]]) - gamma5* = g([[ z1, z0, z0, z0 ], - [ z0, z1, z0, z0 ], - [ z0, z0, n1, z0 ], - [ z0, z0, z0, n1 ]]) - - spprojmat1p* = p([[ z1, z0, z0, zi ], - [ z0, z1, zi, z0 ]]) - spprojmat1m* = p([[ z1, z0, z0, ni ], - [ z0, z1, ni, z0 ]]) - spprojmat2p* = p([[ z1, z0, z0, n1 ], - [ z0, z1, z1, z0 ]]) - spprojmat2m* = p([[ z1, z0, z0, z1 ], - [ z0, z1, n1, z0 ]]) - spprojmat3p* = p([[ z1, z0, zi, z0 ], - [ z0, z1, z0, ni ]]) - spprojmat3m* = p([[ z1, z0, ni, z0 ], - [ z0, z1, z0, zi ]]) - spprojmat4p* = p([[ z1, z0, z1, z0 ], - [ z0, z1, z0, z1 ]]) - spprojmat4m* = p([[ z1, z0, n1, z0 ], - [ z0, z1, z0, n1 ]]) - - spreconmat1p* = r([[ z1, z0 ], - [ z0, z1 ], - [ z0, ni ], - [ ni, z0 ]]) - spreconmat1m* = r([[ z1, z0 ], - [ z0, z1 ], - [ z0, zi ], - [ zi, z0 ]]) - spreconmat2p* = r([[ z1, z0 ], - [ z0, z1 ], - [ z0, z1 ], - [ n1, z0 ]]) - spreconmat2m* = r([[ z1, z0 ], - [ z0, z1 ], - [ z0, n1 ], - [ z1, z0 ]]) - spreconmat3p* = r([[ z1, z0 ], - [ z0, z1 ], - [ ni, z0 ], - [ z0, zi ]]) - spreconmat3m* = r([[ z1, z0 ], - [ z0, z1 ], - [ zi, z0 ], - [ z0, ni ]]) - spreconmat4p* = r([[ z1, z0 ], - [ z0, z1 ], - [ z1, z0 ], - [ z0, z1 ]]) - spreconmat4m* = r([[ z1, z0 ], - [ z0, z1 ], - [ n1, z0 ], - [ z0, n1 ]]) - -template I(x: typed): untyped = - newImag(1)*x -template mI(x: typed): untyped = - newImag(-1)*x - -proc spproj1p*(r: var auto, x: auto) = - ## r: HalfFermion - ## x: DiracFermion - #let nc = x[0].len - #for i in 0..P: + bind map110 + map110(T, L, F, F) + else: + proc F*(r:var T; x:T) {.inline.} = + const b = (P div N0) and (L-1) + bind forStatic + forStatic i, 0, L-1: + assign(r[][i], x[][i xor b]) +template makePerm(P,T,L,N0) {.dirty.} = + bind evalBacktic, makePermX + evalBacktic: + makePermX(`"perm" P`,P,T,L,N0) +template makePackPX(F,P,T,L,N0) {.dirty.} = + # P: perm, T: vector type, L: outer vec len, N0: inner vec len + when N0>P: + proc F*(r:var openArray[SomeNumber], x:T, + l:var openarray[SomeNumber]) {.inline.} = + const N02 = N0 div 2 + let ra = cast[ptr array[L,array[N02,type(r[0])]]](r[0].addr) + let la = cast[ptr array[L,array[N02,type(l[0])]]](l[0].addr) + bind forStatic + forStatic i, 0, L-1: + F(ra[][i], x[][i], la[][i]) + else: + proc F*(r:var openArray[SomeNumber], x:T, + l:var openarray[SomeNumber]) {.inline.} = + const L2 = L div 2 + let ra = cast[ptr array[L2,array[N0,type(r[0])]]](r[0].addr) + let la = cast[ptr array[L2,array[N0,type(l[0])]]](l[0].addr) + const b = (P div N0) and (L-1) + var ir,il = 0 + bind forStatic + forStatic i, 0, L-1: + if (i and b) == 0: + when N0==1: + la[][il][0] = x[][i] + else: + assign(la[][il], x[][i]) + inc il + else: + when N0==1: + ra[][ir][0] = x[][i] + else: + assign(ra[][ir], x[][i]) + inc ir +template makePackMX(F,P,T,L,N0) {.dirty.} = + # P: perm, T: vector type, L: outer vec len, N0: inner vec len + when N0>P: + proc F*(r:var openArray[SomeNumber], x:T, + l:var openarray[SomeNumber]) {.inline.} = + const N02 = N0 div 2 + let ra = cast[ptr array[L,array[N02,type(r[0])]]](r[0].addr) + let la = cast[ptr array[L,array[N02,type(l[0])]]](l[0].addr) + bind forStatic + forStatic i, 0, L-1: + F(ra[][i], x[][i], la[][i]) + else: + proc F*(r:var openArray[SomeNumber], x:T, + l:var openarray[SomeNumber]) {.inline.} = + const L2 = L div 2 + let ra = cast[ptr array[L2,array[N0,type(r[0])]]](r[0].addr) + let la = cast[ptr array[L2,array[N0,type(l[0])]]](l[0].addr) + const b = (P div N0) and (L-1) + var ir,il = 0 + bind forStatic + forStatic i, 0, L-1: + if (i and b) == 0: + when N0==1: + ra[][ir][0] = x[][i] + else: + assign(ra[][ir], x[][i]) + inc ir + else: + when N0==1: + la[][il][0] = x[][i] + else: + assign(la[][il], x[][i]) + inc il +template makePackP(P,T,L,N0) {.dirty.} = + bind evalBacktic, makePackPX + evalBacktic: + makePackPX(`"packp" P`,P,T,L,N0) +template makePackM(P,T,L,N0) {.dirty.} = + bind evalBacktic, makePackMX + evalBacktic: + makePackMX(`"packm" P`,P,T,L,N0) +template makeBlendPX(F,P,T,L,N0) {.dirty.} = + when N0>P: + proc F*(x:var T; r:openArray[SomeNumber]; + l:openArray[SomeNumber]) {.inline.} = + const N02 = N0 div 2 + let ra = cast[ptr array[L,array[N02,type(r[0])]]](unsafeAddr(r[0])) + let la = cast[ptr array[L,array[N02,type(l[0])]]](unsafeAddr(l[0])) + forStatic i, 0, L-1: + F(x[][i], ra[][i], la[][i]) + else: + proc F*(x:var T; r:openArray[SomeNumber]; + l:openArray[SomeNumber]) {.inline.} = + const L2 = L div 2 + let ra = cast[ptr array[L2,array[N0,type(r[0])]]](unsafeAddr(r[0])) + let la = cast[ptr array[L2,array[N0,type(l[0])]]](unsafeAddr(l[0])) + const b = (P div N0) and (L-1) + var ir,il = 0 + bind forStatic + forStatic i, 0, L-1: + if (i and b) == 0: + when N0==1: + x[][i] = la[][il][0] + else: + assign(x[][i], la[][il]) + inc il + else: + when N0==1: + x[][i] = ra[][ir][0] + else: + assign(x[][i], ra[][ir]) + inc ir +template makeBlendMX(F,P,T,L,N0) {.dirty.} = + when N0>P: + proc F*(x:var T; r:openArray[SomeNumber]; + l:openArray[SomeNumber]) {.inline.} = + const N02 = N0 div 2 + let ra = cast[ptr array[L,array[N02,type(r[0])]]](unsafeAddr(r[0])) + let la = cast[ptr array[L,array[N02,type(l[0])]]](unsafeAddr(l[0])) + bind forStatic + forStatic i, 0, L-1: + F(x[][i], ra[][i], la[][i]) + else: + proc F*(x:var T; r:openArray[SomeNumber]; + l:openArray[SomeNumber]) {.inline.} = + const L2 = L div 2 + let ra = cast[ptr array[L2,array[N0,type(r[0])]]](unsafeAddr(r[0])) + let la = cast[ptr array[L2,array[N0,type(l[0])]]](unsafeAddr(l[0])) + const b = (P div N0) and (L-1) + var ir,il = 0 + bind forStatic + forStatic i, 0, L-1: + if (i and b) == 0: + when N0==1: + x[][i] = ra[][ir][0] + else: + assign(x[][i], ra[][ir]) + inc ir + else: + when N0==1: + x[][i] = la[][il][0] + else: + assign(x[][i], la[][il]) + inc il +template makeBlendP(P,T,L,N0) {.dirty.} = + bind evalBacktic, makeBlendPX + evalBacktic: + makeBlendPX(`"blendp" P`,P,T,L,N0) +template makeBlendM(P,T,L,N0) {.dirty.} = + bind evalBacktic, makeBlendMX + evalBacktic: + makeBlendMX(`"blendm" P`,P,T,L,N0) + +discard """ + proc op*(x:var T; r:openArray[SomeNumber]; + l:openArray[SomeNumber]) {.inline.} = + let ra = cast[ptr array[2,type(r[0])]](unsafeAddr(r[2])) + let la = cast[ptr array[2,type(l[0])]](unsafeAddr(l[2])) + op(x[][0], r, l) + op(x[][1], ra[], la[]) +""" + +#type SimdArrayObj*[L,B] = object +# v*: array[L,B] + +template arrayType[T](N: typed, x: typedesc[T]): untyped = + type B {.gensym.} = T.type + #static: echo "arrayType: ", N, " ", B + array[N,B] +# T = Simd{S,D}{L} = array[L,B] +# B ~ array[N0,F] +template makeSimdArray*(T:untyped;L:typed;B:typedesc):untyped {.dirty.} = +#template makeSimdArray*(L:typed;B:typedesc;T:untyped) {.dirty.} = + #static: echo "makeSimdArray: ", L, " ", $B.type + #makeSimdArray2(T, L, type B, numberType(B), numNumbers(B), L*numNumbers(B)) + makeSimdArray2(L, B, numberType(B), numNumbers(B), L*numNumbers(B), T) +#template makeSimdArray2*(T:untyped;L,B,F,N0,N:typed):untyped {.dirty.} = +#template makeSimdArray2*(T:untyped;L:typed;BB,F:typedesc;N0,N:typed):untyped {.dirty.} = +template makeSimdArray2*(L:typed;B,F:typedesc;N0,N:typed,T:untyped) {.dirty.} = + getOptimPragmas() + #static: echo "makeSimdArray2: ", L, " ", $B + bind map011, map021, map021x, map110, map120, map120x, map130, arrayType + bind makePerm, makePackP, makePackM, makeBlendP, makeBlendM + #type B {.gensym.} = typeof(BB) + #type T* = distinct array[L,B] + type T* = object + #v*: array[L,B.type] + v*: arrayType(L,B) + #v* {.align(L*sizeof(B)).}: arrayType(L,B) + #type T* = SimdArrayObj[L,B] + template isWrapper*(x:typedesc[T]): bool = false + template isWrapper*(x:T): bool = false + template numberType*(x:typedesc[T]):typedesc = F + template numberType*(x:T):typedesc = F + template numNumbers*(x:typedesc[T]):untyped = N + template numNumbers*(x:T):untyped = N + template simdType*(x:typedesc[T]):typedesc = T + template simdType*(x:T):typedesc = T + template simdLength*(x:T):untyped = N + template simdLength*(x:typedesc[T]):untyped = N + template eval*(x:T): untyped = x + template eval*(x:typedesc[T]): typedesc = T + #template `[]`*(x:T):untyped = (array[L,B])(x) + template `[]`*(x:T):untyped = x.v + template `[]=`*(x: T; y: typed) = x.v = y + when B is SomeNumber: + template `[]`*(x:T; i:SomeInteger):untyped = x[][i div N0] + template `[]=`*(x:T; i:SomeInteger; y:auto) = x[][i div N0] := y + else: + template `[]`*(x:T; i:SomeInteger):untyped = x[][i div N0][i mod N0] + template `[]=`*(x:T; i:SomeInteger; y:auto) = x[][i div N0][i mod N0] = y + template load1*(x:T):untyped = x + proc to*(x:SomeNumber; y:typedesc[T]):T {.alwaysInline,noInit.} = + bind forStatic + forStatic i, 0, L-1: + assign(result[][i], x) + #echoAst: F + #static: echo F.treerepr + #when not(F is float32): + # should be handled in simd.nim now + #when F is float64: + # template toDoubleImpl*(x: T): untyped = x + #else: + # template toSingleImpl*(x: T): untyped = x + proc simdReduce*(r: var SomeNumber; x: T) {.inline.} = + #mixin add + var y = x[][0] + forStatic i, 1, L-1: + iadd(y, x[][i]) + r = (type(r))(simdReduce(y)) + proc simdReduce*(x:T):F {.noInit,inline.} = simdReduce(result, x) + template simdSum*(r:var SomeNumber; x:T) = simdReduce(r, x) + template simdSum*(x:T):untyped = simdReduce(x) + proc simdMaxReduce*(r:var SomeNumber; x:T) {.inline.} = + mixin simdMaxReduce + var y = x[][0] + forStatic i, 1, L-1: + let c = x[][i] + y = max(y, c) + r = (type(r))(simdMaxReduce(y)) + proc simdMaxReduce*(x:T):F {.noinit,inline.} = simdMaxReduce(result, x) + template simdMax*(r:var SomeNumber; x:T) = simdMaxReduce(r, x) + template simdMax*(x:T):untyped = simdMaxReduce(x) + proc simdMinReduce*(r:var SomeNumber; x:T) {.inline.} = + mixin simdMinReduce + var y = x[][0] + forStatic i, 1, L-1: + let c = x[][i] + y = min(y, c) + r = (type(r))(simdMinReduce(y)) + proc simdMinReduce*(x:T):F {.noinit,inline.} = simdMinReduce(result, x) + template simdMin*(r:var SomeNumber; x:T) = simdMinReduce(r, x) + template simdMin*(x:T):untyped = simdMinReduce(x) + proc `-`*(x:T):T {.inline,noInit.} = + forStatic i, 0, L-1: + neg(result[][i], x[][i]) + + map011(T, L, abs, abs) + map011(T, L, trace, trace) + map011(T, L, norm2, norm2) + map011(T, L, sqrt, sqrt) + map011(T, L, rsqrt, rsqrt) + map011(T, L, inv, inv) + map011(T, L, sin, sin) + map011(T, L, cos, cos) + map011(T, L, acos, acos) + + map021(T, L, atan2, atan2) + map021(T, L, min, min) + map021(T, L, max, max) + map021(T, L, add, `+`) + map021(T, L, sub, `-`) + map021(T, L, mul, `*`) + map021(T, L, divd, `/`) + map021(T, L, `+`, `+`) + map021(T, L, `-`, `-`) + map021(T, L, `*`, `*`) + map021(T, L, `/`, `/`) + #map021(T, L, `<`, `<`) + map021(T, L, copySign, copySign) + + map110(T, L, assign, assign) + map110(T, L, neg, neg) + map110(T, L, iadd, iadd) + map110(T, L, isub, isub) + map110(T, L, imul, imul) + map110(T, L, idiv, idiv) + map110(T, L, norm2, norm2) + map110(T, L, inorm2, inorm2) + map110(T, L, rsqrt, rsqrt) + map110(T, L, `+=`, iadd) + map110(T, L, `-=`, isub) + map110(T, L, `*=`, imul) + map110(T, L, `/=`, idiv) + + map120(T, L, add, add) + map120(T, L, sub, sub) + map120(T, L, mul, mul) + map120(T, L, divd, divd) + map120(T, L, imadd, imadd) + map120(T, L, imsub, imsub) + + map130(T, L, msub, msub) + + template `:=`*(r: T; x: T): untyped = assign(r, x) + template `:=`*(r: T; x: array[L,B]) = + let xx = x + forStatic i, 0, L-1: + r[][i] = xx[i] + when N==1: + template assign*(r: SomeNumber, x: T): untyped = r = x[0] + proc assign*(r: var T; x: SomeNumber) {.alwaysInline.} = + #assign(r, x.to(T)) + forStatic i, 0, L-1: + assign(r[][i], x) + template `:=`*(r: T, x: SomeNumber) = assign(r, x) + proc assign*(r:var T; x:array[N,SomeNumber]) {.inline.} = + when compiles(assign(r[][0], unsafeAddr(x[0]))): + forStatic i, 0, L-1: + assign(r[][i], unsafeAddr(x[i*N0])) + else: + var y = x + forStatic i, 0, L-1: + assign(r[][i], unsafeAddr(y[i*N0])) + proc assign*(r:var array[N,SomeNumber], x:T) {.inline.} = + bind forStatic + when B is SomeNumber: + forStatic i, 0, L-1: + r[i] = x[][i] + else: + forStatic i, 0, L-1: + assign(addr(r[i*N0]), x[][i]) + proc assign*(m: Masked[T], x: SomeNumber) = + #static: echo "a mask" + var i = 0 + var b = m.mask + while b != 0: + if (b and 1) != 0: + m.pobj[][i] = x + b = b shr 1 + i.inc + #static: echo "end a mask" + template add*(r:var T; x:SomeNumber; y:T) = add(r, x.to(type(T)), y) + template add*(r:var T; x:T; y:SomeNumber) = add(r, x, y.to(type(T))) + template sub*(r:var T; x:SomeNumber; y:T) = sub(r, x.to(type(T)), y) + template sub*(r:var T; x:T; y:SomeNumber) = sub(r, x, y.to(type(T))) + template mul*(r:var T; x:SomeNumber; y:T) = mul(r, x.to(type(T)), y) + #map120x(SomeNumber,T,T,L,mul,mul) + template mul*(r:var T; x:T; y:SomeNumber) = mul(r, x, y.to(type(T))) + template iadd*(r:var T; x:SomeNumber) = iadd(r, x.to(type(T))) + template isub*(r:var T; x:SomeNumber) = isub(r, x.to(type(T))) + template imadd*(r:var T; x:SomeNumber; y:T) = imadd(r, x.to(type(T)), y) + template imsub*(r:var T; x:SomeNumber; y:T) = imsub(r, x.to(type(T)), y) + template divd*(r:var T; x:SomeNumber; y:T) = divd(r, x.to(type(T)), y) + template imadd*(r:var T; x:T; y:SomeNumber) = imadd(r, x, y.to(type(T))) + template imsub*(r:var T; x:T; y:SomeNumber) = imsub(r, x, y.to(type(T))) + template divd*(r:var T; x:T; y:SomeNumber) = divd(r, x, y.to(type(T))) + template imul*(r:var T; x:SomeNumber) = imul(r, x.to(type(T))) + template idiv*(r:var T; x:SomeNumber) = idiv(r, x.to(type(T))) + template msub*(r:var T; x:SomeNumber; y,z:T) = msub(r, x.to(type(T)), y, z) + template `:=`*(r:var T; x:array[N,SomeNumber]) = assign(r, x) + template `+`*(x:SomeNumber; y:T):T = add(x.to(type(T)), y) + template `+`*(x:T; y:SomeNumber):T = add(x, y.to(type(T))) + template `-`*(x:SomeNumber; y:T):T = sub(x.to(type(T)), y) + template `-`*(x:T; y:SomeNumber):T = sub(x, y.to(type(T))) + template `*`*(x:SomeNumber; y:T):T = mul(x.to(type(T)), y) + #map021x(SomeNumber,T,T,L,`*`,`*`) + template `*`*(x:T; y:SomeNumber):T = mul(x, y.to(type(T))) + template `/`*(x:SomeNumber; y:T):T = divd(x.to(type(T)), y) + template `/`*(x:T; y:SomeNumber):T = divd(x, y.to(type(T))) + template `<`*(x:T; y:SomeNumber):T = `<`(x, y.to(type(T))) + template `+=`*(r:var T; x:SomeNumber) = iadd(r, x.to(type(T))) + template `-=`*(r:var T; x:SomeNumber) = isub(r, x.to(type(T))) + template `*=`*(r:var T; x:SomeNumber) = imul(r, x.to(type(T))) + template `/=`*(r:var T; x:SomeNumber) = idiv(r, x.to(type(T))) + + proc `$`*(x:T):string = + result = "[" & $x[0] + for i in 1..