Hi Everyone!
first i’d like to say that i’m really enjoying using Julia, i’m using it in my PhD with increasing success!
lately i’ve been developing a MeanShift algorithm and i managed to make the code dimension generic but still not fully type generic
using StaticArrays,LinearAlgebra
@inline function Kern(x,h)
max(zero(h),1-norm(x./h)^2)
end
function circledim(M,c,i)
mod(c-1,size(M,i))+1
end
function makerange(p,h,i)
round(Int,p[i]-h-1):round(Int,p[i]+h+1)
end
@generated function genms(M::Array{T,N},v,h::T) where {T,N}
quote
@inbounds begin
p=SVector{$N}(v)
c=SVector{$N}(v.*0)
W=zero(T)
xsq=zero(T)
ls=1/(π*h^2)
Base.Cartesian.@nexprs $N i -> R_i = makerange(p,h,i)
Base.Cartesian.@nloops $N i i->R_i begin
cp=SVector(Base.Cartesian.@ntuple $N k->i_k)
sW=Kern(p.-cp,h)*((Base.Cartesian.@nref $N M k->circledim(M,i_k,k)) + ls)
xsq+=norm(p.-cp)^2*sW
c+=cp*sW
W+=sW
end
c/=W
xsq/=W
c=2*c-p
return SVector(Base.Cartesian.@ntuple $N k->circledim(M,c[k],k)),sqrt(3*xsq),W/xsq,norm(c.-p)
end
end
end
function MWE()
T=[(x,y) for x in -5:0.1:5, y in -5:0.1:5]
M=[exp(-(x-1)^2/2)* exp(-(y-2)^2/2) for x in -5:0.1:5, y in -5:0.1:5]
v=@SVector [50.0,50.0]
h=5.0
del=1.0
while del>1e-5
v,h,W,del=genms(M,v,h)
end
M[round.(Int,v)...],T[round.(Int,v)...],h
end
MWE()
I struggled a lot to use the macro magic contained in Base.Cartesian, could someone help me with making the code fully generic?
the result of MWE() is (1.0, (1.0, 2.0), 3.3222927225309373)