text:
# Julia wrapper for header: /usr/local/include/arrayfire.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

function af_sum(out,_in,dim)
    checkerror(ccall((:af_sum,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_sum_nan(out,_in,dim,nanval)
    checkerror(ccall((:af_sum_nan,libaf),af_err,(Ptr{af_array},af_array,Cint,Cdouble),out,_in,dim,nanval))
end

function af_product(out,_in,dim)
    checkerror(ccall((:af_product,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_product_nan(out,_in,dim,nanval)
    checkerror(ccall((:af_product_nan,libaf),af_err,(Ptr{af_array},af_array,Cint,Cdouble),out,_in,dim,nanval))
end

function af_min(out,_in,dim)
    checkerror(ccall((:af_min,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_max(out,_in,dim)
    checkerror(ccall((:af_max,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_all_true(out,_in,dim)
    checkerror(ccall((:af_all_true,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_any_true(out,_in,dim)
    checkerror(ccall((:af_any_true,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_count(out,_in,dim)
    checkerror(ccall((:af_count,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_sum_all(real,imag,_in)
    checkerror(ccall((:af_sum_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_sum_nan_all(real,imag,_in,nanval)
    checkerror(ccall((:af_sum_nan_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array,Cdouble),real,imag,_in,nanval))
end

function af_product_all(real,imag,_in)
    checkerror(ccall((:af_product_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_product_nan_all(real,imag,_in,nanval)
    checkerror(ccall((:af_product_nan_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array,Cdouble),real,imag,_in,nanval))
end

function af_min_all(real,imag,_in)
    checkerror(ccall((:af_min_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_max_all(real,imag,_in)
    checkerror(ccall((:af_max_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_all_true_all(real,imag,_in)
    checkerror(ccall((:af_all_true_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_any_true_all(real,imag,_in)
    checkerror(ccall((:af_any_true_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_count_all(real,imag,_in)
    checkerror(ccall((:af_count_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_imin(out,idx,_in,dim)
    checkerror(ccall((:af_imin,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,Cint),out,idx,_in,dim))
end

function af_imax(out,idx,_in,dim)
    checkerror(ccall((:af_imax,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,Cint),out,idx,_in,dim))
end

function af_imin_all(real,imag,idx,_in)
    checkerror(ccall((:af_imin_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},Ptr{UInt32},af_array),real,imag,idx,_in))
end

function af_imax_all(real,imag,idx,_in)
    checkerror(ccall((:af_imax_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},Ptr{UInt32},af_array),real,imag,idx,_in))
end

function af_accum(out,_in,dim)
    checkerror(ccall((:af_accum,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_where(idx,_in)
    checkerror(ccall((:af_where,libaf),af_err,(Ptr{af_array},af_array),idx,_in))
end

function af_diff1(out,_in,dim)
    checkerror(ccall((:af_diff1,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_diff2(out,_in,dim)
    checkerror(ccall((:af_diff2,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,dim))
end

function af_sort(out,_in,dim,isAscending)
    checkerror(ccall((:af_sort,libaf),af_err,(Ptr{af_array},af_array,UInt32,Bool),out,_in,dim,isAscending))
end

function af_sort_index(out,indices,_in,dim,isAscending)
    checkerror(ccall((:af_sort_index,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,UInt32,Bool),out,indices,_in,dim,isAscending))
end

function af_sort_by_key(out_keys,out_values,keys,values,dim,isAscending)
    checkerror(ccall((:af_sort_by_key,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,af_array,UInt32,Bool),out_keys,out_values,keys,values,dim,isAscending))
end

function af_set_unique(out,_in,is_sorted)
    checkerror(ccall((:af_set_unique,libaf),af_err,(Ptr{af_array},af_array,Bool),out,_in,is_sorted))
end

function af_set_union(out,first,second,is_unique)
    checkerror(ccall((:af_set_union,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,first,second,is_unique))
end

function af_set_intersect(out,first,second,is_unique)
    checkerror(ccall((:af_set_intersect,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,first,second,is_unique))
end

function af_add(out,lhs,rhs,batch)
    checkerror(ccall((:af_add,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_sub(out,lhs,rhs,batch)
    checkerror(ccall((:af_sub,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_mul(out,lhs,rhs,batch)
    checkerror(ccall((:af_mul,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_div(out,lhs,rhs,batch)
    checkerror(ccall((:af_div,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_lt(out,lhs,rhs,batch)
    checkerror(ccall((:af_lt,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_gt(out,lhs,rhs,batch)
    checkerror(ccall((:af_gt,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_le(out,lhs,rhs,batch)
    checkerror(ccall((:af_le,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_ge(out,lhs,rhs,batch)
    checkerror(ccall((:af_ge,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_eq(out,lhs,rhs,batch)
    checkerror(ccall((:af_eq,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_neq(out,lhs,rhs,batch)
    checkerror(ccall((:af_neq,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_and(out,lhs,rhs,batch)
    checkerror(ccall((:af_and,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_or(out,lhs,rhs,batch)
    checkerror(ccall((:af_or,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_not(out,_in)
    checkerror(ccall((:af_not,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_bitand(out,lhs,rhs,batch)
    checkerror(ccall((:af_bitand,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_bitor(out,lhs,rhs,batch)
    checkerror(ccall((:af_bitor,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_bitxor(out,lhs,rhs,batch)
    checkerror(ccall((:af_bitxor,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_bitshiftl(out,lhs,rhs,batch)
    checkerror(ccall((:af_bitshiftl,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_bitshiftr(out,lhs,rhs,batch)
    checkerror(ccall((:af_bitshiftr,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_cast(out,_in,_type)
    checkerror(ccall((:af_cast,libaf),af_err,(Ptr{af_array},af_array,af_dtype),out,_in,_type))
end

function af_minof(out,lhs,rhs,batch)
    checkerror(ccall((:af_minof,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_maxof(out,lhs,rhs,batch)
    checkerror(ccall((:af_maxof,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_rem(out,lhs,rhs,batch)
    checkerror(ccall((:af_rem,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_mod(out,lhs,rhs,batch)
    checkerror(ccall((:af_mod,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_abs(out,_in)
    checkerror(ccall((:af_abs,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_arg(out,_in)
    checkerror(ccall((:af_arg,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_sign(out,_in)
    checkerror(ccall((:af_sign,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_round(out,_in)
    checkerror(ccall((:af_round,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_trunc(out,_in)
    checkerror(ccall((:af_trunc,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_floor(out,_in)
    checkerror(ccall((:af_floor,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_ceil(out,_in)
    checkerror(ccall((:af_ceil,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_hypot(out,lhs,rhs,batch)
    checkerror(ccall((:af_hypot,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_sin(out,_in)
    checkerror(ccall((:af_sin,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_cos(out,_in)
    checkerror(ccall((:af_cos,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_tan(out,_in)
    checkerror(ccall((:af_tan,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_asin(out,_in)
    checkerror(ccall((:af_asin,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_acos(out,_in)
    checkerror(ccall((:af_acos,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_atan(out,_in)
    checkerror(ccall((:af_atan,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_atan2(out,lhs,rhs,batch)
    checkerror(ccall((:af_atan2,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_cplx2(out,lhs,rhs,batch)
    checkerror(ccall((:af_cplx2,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_cplx(out,_in)
    checkerror(ccall((:af_cplx,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_real(out,_in)
    checkerror(ccall((:af_real,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_imag(out,_in)
    checkerror(ccall((:af_imag,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_conjg(out,_in)
    checkerror(ccall((:af_conjg,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_sinh(out,_in)
    checkerror(ccall((:af_sinh,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_cosh(out,_in)
    checkerror(ccall((:af_cosh,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_tanh(out,_in)
    checkerror(ccall((:af_tanh,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_asinh(out,_in)
    checkerror(ccall((:af_asinh,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_acosh(out,_in)
    checkerror(ccall((:af_acosh,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_atanh(out,_in)
    checkerror(ccall((:af_atanh,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_root(out,lhs,rhs,batch)
    checkerror(ccall((:af_root,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_pow(out,lhs,rhs,batch)
    checkerror(ccall((:af_pow,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,lhs,rhs,batch))
end

function af_pow2(out,_in)
    checkerror(ccall((:af_pow2,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_exp(out,_in)
    checkerror(ccall((:af_exp,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_sigmoid(out,_in)
    checkerror(ccall((:af_sigmoid,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_expm1(out,_in)
    checkerror(ccall((:af_expm1,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_erf(out,_in)
    checkerror(ccall((:af_erf,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_erfc(out,_in)
    checkerror(ccall((:af_erfc,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_log(out,_in)
    checkerror(ccall((:af_log,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_log1p(out,_in)
    checkerror(ccall((:af_log1p,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_log10(out,_in)
    checkerror(ccall((:af_log10,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_log2(out,_in)
    checkerror(ccall((:af_log2,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_sqrt(out,_in)
    checkerror(ccall((:af_sqrt,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_cbrt(out,_in)
    checkerror(ccall((:af_cbrt,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_factorial(out,_in)
    checkerror(ccall((:af_factorial,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_tgamma(out,_in)
    checkerror(ccall((:af_tgamma,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_lgamma(out,_in)
    checkerror(ccall((:af_lgamma,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_iszero(out,_in)
    checkerror(ccall((:af_iszero,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_isinf(out,_in)
    checkerror(ccall((:af_isinf,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_isnan(out,_in)
    checkerror(ccall((:af_isnan,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_make_seq(_begin,_end,step)
    ccall((:af_make_seq,libaf),af_seq,(Cdouble,Cdouble,Cdouble),_begin,_end,step)
end

function af_print_array(arr)
    checkerror(ccall((:af_print_array,libaf),af_err,(af_array,),arr))
end

function af_print_array_gen(exp,arr,precision)
    checkerror(ccall((:af_print_array_gen,libaf),af_err,(Ptr{UInt8},af_array,Cint),exp,arr,precision))
end

function af_save_array(index,key,arr,filename,append)
    checkerror(ccall((:af_save_array,libaf),af_err,(Ptr{Cint},Ptr{UInt8},af_array,Ptr{UInt8},Bool),index,key,arr,filename,append))
end

function af_read_array_index(out,filename,index)
    checkerror(ccall((:af_read_array_index,libaf),af_err,(Ptr{af_array},Ptr{UInt8},UInt32),out,filename,index))
end

function af_read_array_key(out,filename,key)
    checkerror(ccall((:af_read_array_key,libaf),af_err,(Ptr{af_array},Ptr{UInt8},Ptr{UInt8}),out,filename,key))
end

function af_read_array_key_check(index,filename,key)
    checkerror(ccall((:af_read_array_key_check,libaf),af_err,(Ptr{Cint},Ptr{UInt8},Ptr{UInt8}),index,filename,key))
end

function af_array_to_string(output,exp,arr,precision,transpose)
    checkerror(ccall((:af_array_to_string,libaf),af_err,(Ptr{Ptr{UInt8}},Ptr{UInt8},af_array,Cint,Bool),output,exp,arr,precision,transpose))
end

function af_example_function(out,_in,param)
    checkerror(ccall((:af_example_function,libaf),af_err,(Ptr{af_array},af_array,af_someenum_t),out,_in,param))
end

function af_get_version(major,minor,patch)
    checkerror(ccall((:af_get_version,libaf),af_err,(Ptr{Cint},Ptr{Cint},Ptr{Cint}),major,minor,patch))
end

function af_index(out,_in,ndims,index)
    checkerror(ccall((:af_index,libaf),af_err,(Ptr{af_array},af_array,UInt32,Ptr{af_seq}),out,_in,ndims,index))
end

function af_lookup(out,_in,indices,dim)
    checkerror(ccall((:af_lookup,libaf),af_err,(Ptr{af_array},af_array,af_array,UInt32),out,_in,indices,dim))
end

function af_assign_seq(out,lhs,ndims,indices,rhs)
    checkerror(ccall((:af_assign_seq,libaf),af_err,(Ptr{af_array},af_array,UInt32,Ptr{af_seq},af_array),out,lhs,ndims,indices,rhs))
end

function af_index_gen(out,_in,ndims,indices)
    checkerror(ccall((:af_index_gen,libaf),af_err,(Ptr{af_array},af_array,dim_t,Ptr{af_index_t}),out,_in,ndims,indices))
end

function af_assign_gen(out,lhs,ndims,indices,rhs)
    checkerror(ccall((:af_assign_gen,libaf),af_err,(Ptr{af_array},af_array,dim_t,Ptr{af_index_t},af_array),out,lhs,ndims,indices,rhs))
end

function af_create_indexers(indexers)
    checkerror(ccall((:af_create_indexers,libaf),af_err,(Ptr{Ptr{af_index_t}},),indexers))
end

function af_set_array_indexer(indexer,idx,dim)
    checkerror(ccall((:af_set_array_indexer,libaf),af_err,(Ptr{af_index_t},af_array,dim_t),indexer,idx,dim))
end

function af_set_seq_indexer(indexer,idx,dim,is_batch)
    checkerror(ccall((:af_set_seq_indexer,libaf),af_err,(Ptr{af_index_t},Ptr{af_seq},dim_t,Bool),indexer,idx,dim,is_batch))
end

function af_set_seq_param_indexer(indexer,_begin,_end,step,dim,is_batch)
    checkerror(ccall((:af_set_seq_param_indexer,libaf),af_err,(Ptr{af_index_t},Cdouble,Cdouble,Cdouble,dim_t,Bool),indexer,_begin,_end,step,dim,is_batch))
end

function af_release_indexers(indexers)
    checkerror(ccall((:af_release_indexers,libaf),af_err,(Ptr{af_index_t},),indexers))
end

function af_create_array(arr,data,ndims,dims,_type)
    checkerror(ccall((:af_create_array,libaf),af_err,(Ptr{af_array},Ptr{Void},UInt32,Ptr{dim_t},af_dtype),arr,data,ndims,dims,_type))
end

function af_create_handle(arr,ndims,dims,_type)
    checkerror(ccall((:af_create_handle,libaf),af_err,(Ptr{af_array},UInt32,Ptr{dim_t},af_dtype),arr,ndims,dims,_type))
end

function af_copy_array(arr,_in)
    checkerror(ccall((:af_copy_array,libaf),af_err,(Ptr{af_array},af_array),arr,_in))
end

function af_write_array(arr,data,bytes,src)
    checkerror(ccall((:af_write_array,libaf),af_err,(af_array,Ptr{Void},Csize_t,af_source),arr,data,bytes,src))
end

function af_get_data_ptr(data,arr)
    checkerror(ccall((:af_get_data_ptr,libaf),af_err,(Ptr{Void},af_array),data,arr))
end

function af_release_array(arr)
    checkerror(ccall((:af_release_array,libaf),af_err,(af_array,),arr))
end

function af_retain_array(out,_in)
    checkerror(ccall((:af_retain_array,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_get_data_ref_count(use_count,_in)
    checkerror(ccall((:af_get_data_ref_count,libaf),af_err,(Ptr{Cint},af_array),use_count,_in))
end

function af_eval(_in)
    checkerror(ccall((:af_eval,libaf),af_err,(af_array,),_in))
end

function af_get_elements(elems,arr)
    checkerror(ccall((:af_get_elements,libaf),af_err,(Ptr{dim_t},af_array),elems,arr))
end

function af_get_type(_type,arr)
    checkerror(ccall((:af_get_type,libaf),af_err,(Ptr{af_dtype},af_array),_type,arr))
end

function af_get_dims(d0,d1,d2,d3,arr)
    checkerror(ccall((:af_get_dims,libaf),af_err,(Ptr{dim_t},Ptr{dim_t},Ptr{dim_t},Ptr{dim_t},af_array),d0,d1,d2,d3,arr))
end

function af_get_numdims(result,arr)
    checkerror(ccall((:af_get_numdims,libaf),af_err,(Ptr{UInt32},af_array),result,arr))
end

function af_is_empty(result,arr)
    checkerror(ccall((:af_is_empty,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_scalar(result,arr)
    checkerror(ccall((:af_is_scalar,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_row(result,arr)
    checkerror(ccall((:af_is_row,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_column(result,arr)
    checkerror(ccall((:af_is_column,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_vector(result,arr)
    checkerror(ccall((:af_is_vector,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_complex(result,arr)
    checkerror(ccall((:af_is_complex,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_real(result,arr)
    checkerror(ccall((:af_is_real,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_double(result,arr)
    checkerror(ccall((:af_is_double,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_single(result,arr)
    checkerror(ccall((:af_is_single,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_realfloating(result,arr)
    checkerror(ccall((:af_is_realfloating,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_floating(result,arr)
    checkerror(ccall((:af_is_floating,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_integer(result,arr)
    checkerror(ccall((:af_is_integer,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_is_bool(result,arr)
    checkerror(ccall((:af_is_bool,libaf),af_err,(Ptr{Bool},af_array),result,arr))
end

function af_set_backend(bknd)
    checkerror(ccall((:af_set_backend,libaf),af_err,(af_backend,),bknd))
end

function af_get_backend_count(num_backends)
    checkerror(ccall((:af_get_backend_count,libaf),af_err,(Ptr{UInt32},),num_backends))
end

function af_get_available_backends(backends)
    checkerror(ccall((:af_get_available_backends,libaf),af_err,(Ptr{Cint},),backends))
end

function af_get_backend_id(backend,_in)
    checkerror(ccall((:af_get_backend_id,libaf),af_err,(Ptr{af_backend},af_array),backend,_in))
end

function af_matmul(out,lhs,rhs,optLhs,optRhs)
    checkerror(ccall((:af_matmul,libaf),af_err,(Ptr{af_array},af_array,af_array,af_mat_prop,af_mat_prop),out,lhs,rhs,optLhs,optRhs))
end

function af_dot(out,lhs,rhs,optLhs,optRhs)
    checkerror(ccall((:af_dot,libaf),af_err,(Ptr{af_array},af_array,af_array,af_mat_prop,af_mat_prop),out,lhs,rhs,optLhs,optRhs))
end

function af_transpose(out,_in,conjugate)
    checkerror(ccall((:af_transpose,libaf),af_err,(Ptr{af_array},af_array,Bool),out,_in,conjugate))
end

function af_transpose_inplace(_in,conjugate)
    checkerror(ccall((:af_transpose_inplace,libaf),af_err,(af_array,Bool),_in,conjugate))
end

function af_constant(arr,val,ndims,dims,_type)
    checkerror(ccall((:af_constant,libaf),af_err,(Ptr{af_array},Cdouble,UInt32,Ptr{dim_t},af_dtype),arr,val,ndims,dims,_type))
end

function af_constant_complex(arr,real,imag,ndims,dims,_type)
    checkerror(ccall((:af_constant_complex,libaf),af_err,(Ptr{af_array},Cdouble,Cdouble,UInt32,Ptr{dim_t},af_dtype),arr,real,imag,ndims,dims,_type))
end

function af_constant_long(arr,val,ndims,dims)
    checkerror(ccall((:af_constant_long,libaf),af_err,(Ptr{af_array},intl,UInt32,Ptr{dim_t}),arr,val,ndims,dims))
end

function af_constant_ulong(arr,val,ndims,dims)
    checkerror(ccall((:af_constant_ulong,libaf),af_err,(Ptr{af_array},uintl,UInt32,Ptr{dim_t}),arr,val,ndims,dims))
end

function af_range(out,ndims,dims,seq_dim,_type)
    checkerror(ccall((:af_range,libaf),af_err,(Ptr{af_array},UInt32,Ptr{dim_t},Cint,af_dtype),out,ndims,dims,seq_dim,_type))
end

function af_iota(out,ndims,dims,t_ndims,tdims,_type)
    checkerror(ccall((:af_iota,libaf),af_err,(Ptr{af_array},UInt32,Ptr{dim_t},UInt32,Ptr{dim_t},af_dtype),out,ndims,dims,t_ndims,tdims,_type))
end

function af_randu(out,ndims,dims,_type)
    checkerror(ccall((:af_randu,libaf),af_err,(Ptr{af_array},UInt32,Ptr{dim_t},af_dtype),out,ndims,dims,_type))
end

function af_randn(out,ndims,dims,_type)
    checkerror(ccall((:af_randn,libaf),af_err,(Ptr{af_array},UInt32,Ptr{dim_t},af_dtype),out,ndims,dims,_type))
end

function af_set_seed(seed)
    checkerror(ccall((:af_set_seed,libaf),af_err,(uintl,),seed))
end

function af_get_seed(seed)
    checkerror(ccall((:af_get_seed,libaf),af_err,(Ptr{uintl},),seed))
end

function af_identity(out,ndims,dims,_type)
    checkerror(ccall((:af_identity,libaf),af_err,(Ptr{af_array},UInt32,Ptr{dim_t},af_dtype),out,ndims,dims,_type))
end

function af_diag_create(out,_in,num)
    checkerror(ccall((:af_diag_create,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,num))
end

function af_diag_extract(out,_in,num)
    checkerror(ccall((:af_diag_extract,libaf),af_err,(Ptr{af_array},af_array,Cint),out,_in,num))
end

function af_join(out,dim,first,second)
    checkerror(ccall((:af_join,libaf),af_err,(Ptr{af_array},Cint,af_array,af_array),out,dim,first,second))
end

function af_join_many(out,dim,n_arrays,inputs)
    checkerror(ccall((:af_join_many,libaf),af_err,(Ptr{af_array},Cint,UInt32,Ptr{af_array}),out,dim,n_arrays,inputs))
end

function af_tile(out,_in,x,y,z,w)
    checkerror(ccall((:af_tile,libaf),af_err,(Ptr{af_array},af_array,UInt32,UInt32,UInt32,UInt32),out,_in,x,y,z,w))
end

function af_reorder(out,_in,x,y,z,w)
    checkerror(ccall((:af_reorder,libaf),af_err,(Ptr{af_array},af_array,UInt32,UInt32,UInt32,UInt32),out,_in,x,y,z,w))
end

function af_shift(out,_in,x,y,z,w)
    checkerror(ccall((:af_shift,libaf),af_err,(Ptr{af_array},af_array,Cint,Cint,Cint,Cint),out,_in,x,y,z,w))
end

function af_moddims(out,_in,ndims,dims)
    checkerror(ccall((:af_moddims,libaf),af_err,(Ptr{af_array},af_array,UInt32,Ptr{dim_t}),out,_in,ndims,dims))
end

function af_flat(out,_in)
    checkerror(ccall((:af_flat,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_flip(out,_in,dim)
    checkerror(ccall((:af_flip,libaf),af_err,(Ptr{af_array},af_array,UInt32),out,_in,dim))
end

function af_lower(out,_in,is_unit_diag)
    checkerror(ccall((:af_lower,libaf),af_err,(Ptr{af_array},af_array,Bool),out,_in,is_unit_diag))
end

function af_upper(out,_in,is_unit_diag)
    checkerror(ccall((:af_upper,libaf),af_err,(Ptr{af_array},af_array,Bool),out,_in,is_unit_diag))
end

function af_select(out,cond,a,b)
    checkerror(ccall((:af_select,libaf),af_err,(Ptr{af_array},af_array,af_array,af_array),out,cond,a,b))
end

function af_select_scalar_r(out,cond,a,b)
    checkerror(ccall((:af_select_scalar_r,libaf),af_err,(Ptr{af_array},af_array,af_array,Cdouble),out,cond,a,b))
end

function af_select_scalar_l(out,cond,a,b)
    checkerror(ccall((:af_select_scalar_l,libaf),af_err,(Ptr{af_array},af_array,Cdouble,af_array),out,cond,a,b))
end

function af_replace(a,cond,b)
    checkerror(ccall((:af_replace,libaf),af_err,(af_array,af_array,af_array),a,cond,b))
end

function af_replace_scalar(a,cond,b)
    checkerror(ccall((:af_replace_scalar,libaf),af_err,(af_array,af_array,Cdouble),a,cond,b))
end

function af_info()
    checkerror(ccall((:af_info,libaf),af_err,()))
end

function af_init()
    checkerror(ccall((:af_init,libaf),af_err,()))
end

function af_device_info(d_name,d_platform,d_toolkit,d_compute)
    checkerror(ccall((:af_device_info,libaf),af_err,(Ptr{UInt8},Ptr{UInt8},Ptr{UInt8},Ptr{UInt8}),d_name,d_platform,d_toolkit,d_compute))
end

function af_get_device_count(num_of_devices)
    checkerror(ccall((:af_get_device_count,libaf),af_err,(Ptr{Cint},),num_of_devices))
end

function af_get_dbl_support(available,device)
    checkerror(ccall((:af_get_dbl_support,libaf),af_err,(Ptr{Bool},Cint),available,device))
end

function af_set_device(device)
    checkerror(ccall((:af_set_device,libaf),af_err,(Cint,),device))
end

function af_get_device(device)
    checkerror(ccall((:af_get_device,libaf),af_err,(Ptr{Cint},),device))
end

function af_sync(device)
    checkerror(ccall((:af_sync,libaf),af_err,(Cint,),device))
end

function af_alloc_device(ptr,bytes)
    checkerror(ccall((:af_alloc_device,libaf),af_err,(Ptr{Ptr{Void}},dim_t),ptr,bytes))
end

function af_alloc_pinned(ptr,bytes)
    checkerror(ccall((:af_alloc_pinned,libaf),af_err,(Ptr{Ptr{Void}},dim_t),ptr,bytes))
end

function af_free_device(ptr)
    checkerror(ccall((:af_free_device,libaf),af_err,(Ptr{Void},),ptr))
end

function af_free_pinned(ptr)
    checkerror(ccall((:af_free_pinned,libaf),af_err,(Ptr{Void},),ptr))
end

function af_device_array(arr,data,ndims,dims,_type)
    checkerror(ccall((:af_device_array,libaf),af_err,(Ptr{af_array},Ptr{Void},UInt32,Ptr{dim_t},af_dtype),arr,data,ndims,dims,_type))
end

function af_device_mem_info(alloc_bytes,alloc_buffers,lock_bytes,lock_buffers)
    checkerror(ccall((:af_device_mem_info,libaf),af_err,(Ptr{Csize_t},Ptr{Csize_t},Ptr{Csize_t},Ptr{Csize_t}),alloc_bytes,alloc_buffers,lock_bytes,lock_buffers))
end

function af_device_gc()
    checkerror(ccall((:af_device_gc,libaf),af_err,()))
end

function af_set_mem_step_size(step_bytes)
    checkerror(ccall((:af_set_mem_step_size,libaf),af_err,(Csize_t,),step_bytes))
end

function af_get_mem_step_size(step_bytes)
    checkerror(ccall((:af_get_mem_step_size,libaf),af_err,(Ptr{Csize_t},),step_bytes))
end

function af_lock_device_ptr(arr)
    checkerror(ccall((:af_lock_device_ptr,libaf),af_err,(af_array,),arr))
end

function af_unlock_device_ptr(arr)
    checkerror(ccall((:af_unlock_device_ptr,libaf),af_err,(af_array,),arr))
end

function af_get_device_ptr(ptr,arr)
    checkerror(ccall((:af_get_device_ptr,libaf),af_err,(Ptr{Ptr{Void}},af_array),ptr,arr))
end

function af_get_last_error(msg,len)
    ccall((:af_get_last_error,libaf),Void,(Ptr{Ptr{UInt8}},Ptr{dim_t}),msg,len)
end

function af_err_to_string(err)
    ccall((:af_err_to_string,libaf),Ptr{UInt8},(af_err,),err)
end

function af_create_features(feat,num)
    checkerror(ccall((:af_create_features,libaf),af_err,(Ptr{af_features},dim_t),feat,num))
end

function af_retain_features(out,feat)
    checkerror(ccall((:af_retain_features,libaf),af_err,(Ptr{af_features},af_features),out,feat))
end

function af_get_features_num(num,feat)
    checkerror(ccall((:af_get_features_num,libaf),af_err,(Ptr{dim_t},af_features),num,feat))
end

function af_get_features_xpos(out,feat)
    checkerror(ccall((:af_get_features_xpos,libaf),af_err,(Ptr{af_array},af_features),out,feat))
end

function af_get_features_ypos(out,feat)
    checkerror(ccall((:af_get_features_ypos,libaf),af_err,(Ptr{af_array},af_features),out,feat))
end

function af_get_features_score(score,feat)
    checkerror(ccall((:af_get_features_score,libaf),af_err,(Ptr{af_array},af_features),score,feat))
end

function af_get_features_orientation(orientation,feat)
    checkerror(ccall((:af_get_features_orientation,libaf),af_err,(Ptr{af_array},af_features),orientation,feat))
end

function af_get_features_size(size,feat)
    checkerror(ccall((:af_get_features_size,libaf),af_err,(Ptr{af_array},af_features),size,feat))
end

function af_release_features(feat)
    checkerror(ccall((:af_release_features,libaf),af_err,(af_features,),feat))
end

function af_create_window(out,width,height,title)
    checkerror(ccall((:af_create_window,libaf),af_err,(Ptr{af_window},Cint,Cint,Ptr{UInt8}),out,width,height,title))
end

function af_set_position(wind,x,y)
    checkerror(ccall((:af_set_position,libaf),af_err,(af_window,UInt32,UInt32),wind,x,y))
end

function af_set_title(wind,title)
    checkerror(ccall((:af_set_title,libaf),af_err,(af_window,Ptr{UInt8}),wind,title))
end

function af_set_size(wind,w,h)
    checkerror(ccall((:af_set_size,libaf),af_err,(af_window,UInt32,UInt32),wind,w,h))
end

function af_draw_image(wind,_in,props)
    checkerror(ccall((:af_draw_image,libaf),af_err,(af_window,af_array,Ptr{af_cell}),wind,_in,props))
end

function af_draw_plot(wind,X,Y,props)
    checkerror(ccall((:af_draw_plot,libaf),af_err,(af_window,af_array,af_array,Ptr{af_cell}),wind,X,Y,props))
end

function af_draw_plot3(wind,P,props)
    checkerror(ccall((:af_draw_plot3,libaf),af_err,(af_window,af_array,Ptr{af_cell}),wind,P,props))
end

function af_draw_hist(wind,X,minval,maxval,props)
    checkerror(ccall((:af_draw_hist,libaf),af_err,(af_window,af_array,Cdouble,Cdouble,Ptr{af_cell}),wind,X,minval,maxval,props))
end

function af_draw_surface(wind,xVals,yVals,S,props)
    checkerror(ccall((:af_draw_surface,libaf),af_err,(af_window,af_array,af_array,af_array,Ptr{af_cell}),wind,xVals,yVals,S,props))
end

function af_grid(wind,rows,cols)
    checkerror(ccall((:af_grid,libaf),af_err,(af_window,Cint,Cint),wind,rows,cols))
end

function af_show(wind)
    checkerror(ccall((:af_show,libaf),af_err,(af_window,),wind))
end

function af_is_window_closed(out,wind)
    checkerror(ccall((:af_is_window_closed,libaf),af_err,(Ptr{Bool},af_window),out,wind))
end

function af_destroy_window(wind)
    checkerror(ccall((:af_destroy_window,libaf),af_err,(af_window,),wind))
end

function af_gradient(dx,dy,_in)
    checkerror(ccall((:af_gradient,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array),dx,dy,_in))
end

function af_load_image(out,filename,isColor)
    checkerror(ccall((:af_load_image,libaf),af_err,(Ptr{af_array},Ptr{UInt8},Bool),out,filename,isColor))
end

function af_save_image(filename,_in)
    checkerror(ccall((:af_save_image,libaf),af_err,(Ptr{UInt8},af_array),filename,_in))
end

function af_load_image_memory(out,ptr)
    checkerror(ccall((:af_load_image_memory,libaf),af_err,(Ptr{af_array},Ptr{Void}),out,ptr))
end

function af_save_image_memory(ptr,_in,format)
    checkerror(ccall((:af_save_image_memory,libaf),af_err,(Ptr{Ptr{Void}},af_array,af_image_format),ptr,_in,format))
end

function af_delete_image_memory(ptr)
    checkerror(ccall((:af_delete_image_memory,libaf),af_err,(Ptr{Void},),ptr))
end

function af_load_image_native(out,filename)
    checkerror(ccall((:af_load_image_native,libaf),af_err,(Ptr{af_array},Ptr{UInt8}),out,filename))
end

function af_save_image_native(filename,_in)
    checkerror(ccall((:af_save_image_native,libaf),af_err,(Ptr{UInt8},af_array),filename,_in))
end

function af_resize(out,_in,odim0,odim1,method)
    checkerror(ccall((:af_resize,libaf),af_err,(Ptr{af_array},af_array,dim_t,dim_t,af_interp_type),out,_in,odim0,odim1,method))
end

function af_transform(out,_in,transform,odim0,odim1,method,inverse)
    checkerror(ccall((:af_transform,libaf),af_err,(Ptr{af_array},af_array,af_array,dim_t,dim_t,af_interp_type,Bool),out,_in,transform,odim0,odim1,method,inverse))
end

function af_rotate(out,_in,theta,crop,method)
    checkerror(ccall((:af_rotate,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Bool,af_interp_type),out,_in,theta,crop,method))
end

function af_translate(out,_in,trans0,trans1,odim0,odim1,method)
    checkerror(ccall((:af_translate,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,dim_t,dim_t,af_interp_type),out,_in,trans0,trans1,odim0,odim1,method))
end

function af_scale(out,_in,scale0,scale1,odim0,odim1,method)
    checkerror(ccall((:af_scale,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,dim_t,dim_t,af_interp_type),out,_in,scale0,scale1,odim0,odim1,method))
end

function af_skew(out,_in,skew0,skew1,odim0,odim1,method,inverse)
    checkerror(ccall((:af_skew,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,dim_t,dim_t,af_interp_type,Bool),out,_in,skew0,skew1,odim0,odim1,method,inverse))
end

function af_histogram(out,_in,nbins,minval,maxval)
    checkerror(ccall((:af_histogram,libaf),af_err,(Ptr{af_array},af_array,UInt32,Cdouble,Cdouble),out,_in,nbins,minval,maxval))
end

function af_dilate(out,_in,mask)
    checkerror(ccall((:af_dilate,libaf),af_err,(Ptr{af_array},af_array,af_array),out,_in,mask))
end

function af_dilate3(out,_in,mask)
    checkerror(ccall((:af_dilate3,libaf),af_err,(Ptr{af_array},af_array,af_array),out,_in,mask))
end

function af_erode(out,_in,mask)
    checkerror(ccall((:af_erode,libaf),af_err,(Ptr{af_array},af_array,af_array),out,_in,mask))
end

function af_erode3(out,_in,mask)
    checkerror(ccall((:af_erode3,libaf),af_err,(Ptr{af_array},af_array,af_array),out,_in,mask))
end

function af_bilateral(out,_in,spatial_sigma,chromatic_sigma,isColor)
    checkerror(ccall((:af_bilateral,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,Bool),out,_in,spatial_sigma,chromatic_sigma,isColor))
end

function af_mean_shift(out,_in,spatial_sigma,chromatic_sigma,iter,is_color)
    checkerror(ccall((:af_mean_shift,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,UInt32,Bool),out,_in,spatial_sigma,chromatic_sigma,iter,is_color))
end

function af_medfilt(out,_in,wind_length,wind_width,edge_pad)
    checkerror(ccall((:af_medfilt,libaf),af_err,(Ptr{af_array},af_array,dim_t,dim_t,af_border_type),out,_in,wind_length,wind_width,edge_pad))
end

function af_minfilt(out,_in,wind_length,wind_width,edge_pad)
    checkerror(ccall((:af_minfilt,libaf),af_err,(Ptr{af_array},af_array,dim_t,dim_t,af_border_type),out,_in,wind_length,wind_width,edge_pad))
end

function af_maxfilt(out,_in,wind_length,wind_width,edge_pad)
    checkerror(ccall((:af_maxfilt,libaf),af_err,(Ptr{af_array},af_array,dim_t,dim_t,af_border_type),out,_in,wind_length,wind_width,edge_pad))
end

function af_regions(out,_in,connectivity,ty)
    checkerror(ccall((:af_regions,libaf),af_err,(Ptr{af_array},af_array,af_connectivity,af_dtype),out,_in,connectivity,ty))
end

function af_sobel_operator(dx,dy,img,ker_size)
    checkerror(ccall((:af_sobel_operator,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,UInt32),dx,dy,img,ker_size))
end

function af_rgb2gray(out,_in,rPercent,gPercent,bPercent)
    checkerror(ccall((:af_rgb2gray,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,Cfloat),out,_in,rPercent,gPercent,bPercent))
end

function af_gray2rgb(out,_in,rFactor,gFactor,bFactor)
    checkerror(ccall((:af_gray2rgb,libaf),af_err,(Ptr{af_array},af_array,Cfloat,Cfloat,Cfloat),out,_in,rFactor,gFactor,bFactor))
end

function af_hist_equal(out,_in,hist)
    checkerror(ccall((:af_hist_equal,libaf),af_err,(Ptr{af_array},af_array,af_array),out,_in,hist))
end

function af_gaussian_kernel(out,rows,cols,sigma_r,sigma_c)
    checkerror(ccall((:af_gaussian_kernel,libaf),af_err,(Ptr{af_array},Cint,Cint,Cdouble,Cdouble),out,rows,cols,sigma_r,sigma_c))
end

function af_hsv2rgb(out,_in)
    checkerror(ccall((:af_hsv2rgb,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_rgb2hsv(out,_in)
    checkerror(ccall((:af_rgb2hsv,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_color_space(out,image,to,from)
    checkerror(ccall((:af_color_space,libaf),af_err,(Ptr{af_array},af_array,af_cspace_t,af_cspace_t),out,image,to,from))
end

function af_unwrap(out,_in,wx,wy,sx,sy,px,py,is_column)
    checkerror(ccall((:af_unwrap,libaf),af_err,(Ptr{af_array},af_array,dim_t,dim_t,dim_t,dim_t,dim_t,dim_t,Bool),out,_in,wx,wy,sx,sy,px,py,is_column))
end

function af_wrap(out,_in,ox,oy,wx,wy,sx,sy,px,py,is_column)
    checkerror(ccall((:af_wrap,libaf),af_err,(Ptr{af_array},af_array,dim_t,dim_t,dim_t,dim_t,dim_t,dim_t,dim_t,dim_t,Bool),out,_in,ox,oy,wx,wy,sx,sy,px,py,is_column))
end

function af_sat(out,_in)
    checkerror(ccall((:af_sat,libaf),af_err,(Ptr{af_array},af_array),out,_in))
end

function af_ycbcr2rgb(out,_in,standard)
    checkerror(ccall((:af_ycbcr2rgb,libaf),af_err,(Ptr{af_array},af_array,af_ycc_std),out,_in,standard))
end

function af_rgb2ycbcr(out,_in,standard)
    checkerror(ccall((:af_rgb2ycbcr,libaf),af_err,(Ptr{af_array},af_array,af_ycc_std),out,_in,standard))
end

function af_svd(u,s,vt,_in)
    checkerror(ccall((:af_svd,libaf),af_err,(Ptr{af_array},Ptr{af_array},Ptr{af_array},af_array),u,s,vt,_in))
end

function af_svd_inplace(u,s,vt,_in)
    checkerror(ccall((:af_svd_inplace,libaf),af_err,(Ptr{af_array},Ptr{af_array},Ptr{af_array},af_array),u,s,vt,_in))
end

function af_lu(lower,upper,pivot,_in)
    checkerror(ccall((:af_lu,libaf),af_err,(Ptr{af_array},Ptr{af_array},Ptr{af_array},af_array),lower,upper,pivot,_in))
end

function af_lu_inplace(pivot,_in,is_lapack_piv)
    checkerror(ccall((:af_lu_inplace,libaf),af_err,(Ptr{af_array},af_array,Bool),pivot,_in,is_lapack_piv))
end

function af_qr(q,r,tau,_in)
    checkerror(ccall((:af_qr,libaf),af_err,(Ptr{af_array},Ptr{af_array},Ptr{af_array},af_array),q,r,tau,_in))
end

function af_qr_inplace(tau,_in)
    checkerror(ccall((:af_qr_inplace,libaf),af_err,(Ptr{af_array},af_array),tau,_in))
end

function af_cholesky(out,info,_in,is_upper)
    checkerror(ccall((:af_cholesky,libaf),af_err,(Ptr{af_array},Ptr{Cint},af_array,Bool),out,info,_in,is_upper))
end

function af_cholesky_inplace(info,_in,is_upper)
    checkerror(ccall((:af_cholesky_inplace,libaf),af_err,(Ptr{Cint},af_array,Bool),info,_in,is_upper))
end

function af_solve(x,a,b,options)
    checkerror(ccall((:af_solve,libaf),af_err,(Ptr{af_array},af_array,af_array,af_mat_prop),x,a,b,options))
end

function af_solve_lu(x,a,piv,b,options)
    checkerror(ccall((:af_solve_lu,libaf),af_err,(Ptr{af_array},af_array,af_array,af_array,af_mat_prop),x,a,piv,b,options))
end

function af_inverse(out,_in,options)
    checkerror(ccall((:af_inverse,libaf),af_err,(Ptr{af_array},af_array,af_mat_prop),out,_in,options))
end

function af_rank(rank,_in,tol)
    checkerror(ccall((:af_rank,libaf),af_err,(Ptr{UInt32},af_array,Cdouble),rank,_in,tol))
end

function af_det(det_real,det_imag,_in)
    checkerror(ccall((:af_det,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),det_real,det_imag,_in))
end

function af_norm(out,_in,_type,p,q)
    checkerror(ccall((:af_norm,libaf),af_err,(Ptr{Cdouble},af_array,af_norm_type,Cdouble,Cdouble),out,_in,_type,p,q))
end

function af_approx1(out,_in,pos,method,offGrid)
    checkerror(ccall((:af_approx1,libaf),af_err,(Ptr{af_array},af_array,af_array,af_interp_type,Cfloat),out,_in,pos,method,offGrid))
end

function af_approx2(out,_in,pos0,pos1,method,offGrid)
    checkerror(ccall((:af_approx2,libaf),af_err,(Ptr{af_array},af_array,af_array,af_array,af_interp_type,Cfloat),out,_in,pos0,pos1,method,offGrid))
end

function af_fft(out,_in,norm_factor,odim0)
    checkerror(ccall((:af_fft,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t),out,_in,norm_factor,odim0))
end

function af_fft_inplace(_in,norm_factor)
    checkerror(ccall((:af_fft_inplace,libaf),af_err,(af_array,Cdouble),_in,norm_factor))
end

function af_fft2(out,_in,norm_factor,odim0,odim1)
    checkerror(ccall((:af_fft2,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t,dim_t),out,_in,norm_factor,odim0,odim1))
end

function af_fft2_inplace(_in,norm_factor)
    checkerror(ccall((:af_fft2_inplace,libaf),af_err,(af_array,Cdouble),_in,norm_factor))
end

function af_fft3(out,_in,norm_factor,odim0,odim1,odim2)
    checkerror(ccall((:af_fft3,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t,dim_t,dim_t),out,_in,norm_factor,odim0,odim1,odim2))
end

function af_fft3_inplace(_in,norm_factor)
    checkerror(ccall((:af_fft3_inplace,libaf),af_err,(af_array,Cdouble),_in,norm_factor))
end

function af_ifft(out,_in,norm_factor,odim0)
    checkerror(ccall((:af_ifft,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t),out,_in,norm_factor,odim0))
end

function af_ifft_inplace(_in,norm_factor)
    checkerror(ccall((:af_ifft_inplace,libaf),af_err,(af_array,Cdouble),_in,norm_factor))
end

function af_ifft2(out,_in,norm_factor,odim0,odim1)
    checkerror(ccall((:af_ifft2,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t,dim_t),out,_in,norm_factor,odim0,odim1))
end

function af_ifft2_inplace(_in,norm_factor)
    checkerror(ccall((:af_ifft2_inplace,libaf),af_err,(af_array,Cdouble),_in,norm_factor))
end

function af_ifft3(out,_in,norm_factor,odim0,odim1,odim2)
    checkerror(ccall((:af_ifft3,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t,dim_t,dim_t),out,_in,norm_factor,odim0,odim1,odim2))
end

function af_ifft3_inplace(_in,norm_factor)
    checkerror(ccall((:af_ifft3_inplace,libaf),af_err,(af_array,Cdouble),_in,norm_factor))
end

function af_fft_r2c(out,_in,norm_factor,pad0)
    checkerror(ccall((:af_fft_r2c,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t),out,_in,norm_factor,pad0))
end

function af_fft2_r2c(out,_in,norm_factor,pad0,pad1)
    checkerror(ccall((:af_fft2_r2c,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t,dim_t),out,_in,norm_factor,pad0,pad1))
end

function af_fft3_r2c(out,_in,norm_factor,pad0,pad1,pad2)
    checkerror(ccall((:af_fft3_r2c,libaf),af_err,(Ptr{af_array},af_array,Cdouble,dim_t,dim_t,dim_t),out,_in,norm_factor,pad0,pad1,pad2))
end

function af_fft_c2r(out,_in,norm_factor,is_odd)
    checkerror(ccall((:af_fft_c2r,libaf),af_err,(Ptr{af_array},af_array,Cdouble,Bool),out,_in,norm_factor,is_odd))
end

function af_fft2_c2r(out,_in,norm_factor,is_odd)
    checkerror(ccall((:af_fft2_c2r,libaf),af_err,(Ptr{af_array},af_array,Cdouble,Bool),out,_in,norm_factor,is_odd))
end

function af_fft3_c2r(out,_in,norm_factor,is_odd)
    checkerror(ccall((:af_fft3_c2r,libaf),af_err,(Ptr{af_array},af_array,Cdouble,Bool),out,_in,norm_factor,is_odd))
end

function af_convolve1(out,signal,filter,mode,domain)
    checkerror(ccall((:af_convolve1,libaf),af_err,(Ptr{af_array},af_array,af_array,af_conv_mode,af_conv_domain),out,signal,filter,mode,domain))
end

function af_convolve2(out,signal,filter,mode,domain)
    checkerror(ccall((:af_convolve2,libaf),af_err,(Ptr{af_array},af_array,af_array,af_conv_mode,af_conv_domain),out,signal,filter,mode,domain))
end

function af_convolve3(out,signal,filter,mode,domain)
    checkerror(ccall((:af_convolve3,libaf),af_err,(Ptr{af_array},af_array,af_array,af_conv_mode,af_conv_domain),out,signal,filter,mode,domain))
end

function af_convolve2_sep(out,col_filter,row_filter,signal,mode)
    checkerror(ccall((:af_convolve2_sep,libaf),af_err,(Ptr{af_array},af_array,af_array,af_array,af_conv_mode),out,col_filter,row_filter,signal,mode))
end

function af_fft_convolve1(out,signal,filter,mode)
    checkerror(ccall((:af_fft_convolve1,libaf),af_err,(Ptr{af_array},af_array,af_array,af_conv_mode),out,signal,filter,mode))
end

function af_fft_convolve2(out,signal,filter,mode)
    checkerror(ccall((:af_fft_convolve2,libaf),af_err,(Ptr{af_array},af_array,af_array,af_conv_mode),out,signal,filter,mode))
end

function af_fft_convolve3(out,signal,filter,mode)
    checkerror(ccall((:af_fft_convolve3,libaf),af_err,(Ptr{af_array},af_array,af_array,af_conv_mode),out,signal,filter,mode))
end

function af_fir(y,b,x)
    checkerror(ccall((:af_fir,libaf),af_err,(Ptr{af_array},af_array,af_array),y,b,x))
end

function af_iir(y,b,a,x)
    checkerror(ccall((:af_iir,libaf),af_err,(Ptr{af_array},af_array,af_array,af_array),y,b,a,x))
end

function af_mean(out,_in,dim)
    checkerror(ccall((:af_mean,libaf),af_err,(Ptr{af_array},af_array,dim_t),out,_in,dim))
end

function af_mean_weighted(out,_in,weights,dim)
    checkerror(ccall((:af_mean_weighted,libaf),af_err,(Ptr{af_array},af_array,af_array,dim_t),out,_in,weights,dim))
end

function af_var(out,_in,isbiased,dim)
    checkerror(ccall((:af_var,libaf),af_err,(Ptr{af_array},af_array,Bool,dim_t),out,_in,isbiased,dim))
end

function af_var_weighted(out,_in,weights,dim)
    checkerror(ccall((:af_var_weighted,libaf),af_err,(Ptr{af_array},af_array,af_array,dim_t),out,_in,weights,dim))
end

function af_stdev(out,_in,dim)
    checkerror(ccall((:af_stdev,libaf),af_err,(Ptr{af_array},af_array,dim_t),out,_in,dim))
end

function af_cov(out,X,Y,isbiased)
    checkerror(ccall((:af_cov,libaf),af_err,(Ptr{af_array},af_array,af_array,Bool),out,X,Y,isbiased))
end

function af_median(out,_in,dim)
    checkerror(ccall((:af_median,libaf),af_err,(Ptr{af_array},af_array,dim_t),out,_in,dim))
end

function af_mean_all(real,imag,_in)
    checkerror(ccall((:af_mean_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_mean_all_weighted(real,imag,_in,weights)
    checkerror(ccall((:af_mean_all_weighted,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array,af_array),real,imag,_in,weights))
end

function af_var_all(realVal,imagVal,_in,isbiased)
    checkerror(ccall((:af_var_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array,Bool),realVal,imagVal,_in,isbiased))
end

function af_var_all_weighted(realVal,imagVal,_in,weights)
    checkerror(ccall((:af_var_all_weighted,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array,af_array),realVal,imagVal,_in,weights))
end

function af_stdev_all(real,imag,_in)
    checkerror(ccall((:af_stdev_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),real,imag,_in))
end

function af_median_all(realVal,imagVal,_in)
    checkerror(ccall((:af_median_all,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array),realVal,imagVal,_in))
end

function af_corrcoef(realVal,imagVal,X,Y)
    checkerror(ccall((:af_corrcoef,libaf),af_err,(Ptr{Cdouble},Ptr{Cdouble},af_array,af_array),realVal,imagVal,X,Y))
end

function af_fast(out,_in,thr,arc_length,non_max,feature_ratio,edge)
    checkerror(ccall((:af_fast,libaf),af_err,(Ptr{af_features},af_array,Cfloat,UInt32,Bool,Cfloat,UInt32),out,_in,thr,arc_length,non_max,feature_ratio,edge))
end

function af_harris(out,_in,max_corners,min_response,sigma,block_size,k_thr)
    checkerror(ccall((:af_harris,libaf),af_err,(Ptr{af_features},af_array,UInt32,Cfloat,Cfloat,UInt32,Cfloat),out,_in,max_corners,min_response,sigma,block_size,k_thr))
end

function af_orb(feat,desc,_in,fast_thr,max_feat,scl_fctr,levels,blur_img)
    checkerror(ccall((:af_orb,libaf),af_err,(Ptr{af_features},Ptr{af_array},af_array,Cfloat,UInt32,Cfloat,UInt32,Bool),feat,desc,_in,fast_thr,max_feat,scl_fctr,levels,blur_img))
end

function af_sift(feat,desc,_in,n_layers,contrast_thr,edge_thr,init_sigma,double_input,intensity_scale,feature_ratio)
    checkerror(ccall((:af_sift,libaf),af_err,(Ptr{af_features},Ptr{af_array},af_array,UInt32,Cfloat,Cfloat,Cfloat,Bool,Cfloat,Cfloat),feat,desc,_in,n_layers,contrast_thr,edge_thr,init_sigma,double_input,intensity_scale,feature_ratio))
end

function af_gloh(feat,desc,_in,n_layers,contrast_thr,edge_thr,init_sigma,double_input,intensity_scale,feature_ratio)
    checkerror(ccall((:af_gloh,libaf),af_err,(Ptr{af_features},Ptr{af_array},af_array,UInt32,Cfloat,Cfloat,Cfloat,Bool,Cfloat,Cfloat),feat,desc,_in,n_layers,contrast_thr,edge_thr,init_sigma,double_input,intensity_scale,feature_ratio))
end

function af_hamming_matcher(idx,dist,query,train,dist_dim,n_dist)
    checkerror(ccall((:af_hamming_matcher,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,af_array,dim_t,UInt32),idx,dist,query,train,dist_dim,n_dist))
end

function af_nearest_neighbour(idx,dist,query,train,dist_dim,n_dist,dist_type)
    checkerror(ccall((:af_nearest_neighbour,libaf),af_err,(Ptr{af_array},Ptr{af_array},af_array,af_array,dim_t,UInt32,af_match_type),idx,dist,query,train,dist_dim,n_dist,dist_type))
end

function af_match_template(out,search_img,template_img,m_type)
    checkerror(ccall((:af_match_template,libaf),af_err,(Ptr{af_array},af_array,af_array,af_match_type),out,search_img,template_img,m_type))
end

function af_susan(out,_in,radius,diff_thr,geom_thr,feature_ratio,edge)
    checkerror(ccall((:af_susan,libaf),af_err,(Ptr{af_features},af_array,UInt32,Cfloat,Cfloat,Cfloat,UInt32),out,_in,radius,diff_thr,geom_thr,feature_ratio,edge))
end

function af_dog(out,_in,radius1,radius2)
    checkerror(ccall((:af_dog,libaf),af_err,(Ptr{af_array},af_array,Cint,Cint),out,_in,radius1,radius2))
end

function af_homography(H,inliers,x_src,y_src,x_dst,y_dst,htype,inlier_thr,iterations,otype)
    checkerror(ccall((:af_homography,libaf),af_err,(Ptr{af_array},Ptr{Cint},af_array,af_array,af_array,af_array,af_homography_type,Cfloat,UInt32,af_dtype),H,inliers,x_src,y_src,x_dst,y_dst,htype,inlier_thr,iterations,otype))
end


text:
module Design

using OffsetArrays

const Float = Float64

#==============================================================================
Polynomials
==============================================================================#

# DONE
struct VarLinForm{T}
    form ::Dict{Int, T}
end

#DONE
function add!(dest<:VarLinForm, source<:VarLinForm, factor=1) end

#DONE
function add_conjugated!(dest<:VarLinForm, source<:VarLinForm, factor=1) end

#DONE
function mul!(form<:VarLinForm, factor) end

#######################################

struct PolynomialForm{N <: Number}
    terms ::OffsetVector{ VarLinForm{N} }
end

function add!(dest<:PolynomialForm, source<:PolynomialForm, factor=1) end

function mul!(poly<:PolynomialForm, factor) end

function mul_by_power!(poly<:PolynomialForm, factor) end

function conjugate(poly<:PolynomialForm) end

function z_conj_diff(poly<:PolynomialForm) end

function matrix_form(poly<:PolynomialForm) end

#######################################

struct NormedPolynomial{N <: Number, FL <: AbstractFloat}
    poly ::PolynomialForm{N}
    r_norm ::FL
end

function add!(dest<:NormedPolynomial, source<:NormedPolynomial, factor=1) end

function empty!(normed_poly<:NormedPolynomial) end

function conjugate(normed_poly<:NormedPolynomial, r_contour) end

function re_conjugate!(normed_poly<:NormedPolynomial, r_old, r_new) end

function z_conj_diff(normed_poly<:NormedPolynomial, r_contour) end

function matrix_form(normed_poly<:NormedPolynomial) end

#######################################

struct PlaneLayer
    E       ::Float
    ν       ::Float
    r_inner ::Float
    r_outer ::Float
    ϕ       ::NormedPolynomial{Complex{Float}, Float}
    z_bar_Φ ::NormedPolynomial{Complex{Float}, Float}
    bar_ψ   ::NormedPolynomial{Complex{Float}, Float}
end

function couple!(dest::PlaneLayer, source::PlaneLayer) end

function displacements(layer::PlaneLayer) end

function forces(layer::PlaneLayer) end

#######################################

struct PlaneFiber
    layers ::Vector{PlaneLayer{Float}}
    var_indices ::UnitRange{Int}
    max_power ::Int
end

displacements(fiber::PlaneFiber) = displacements(fiber.layers[end])

forces(fiber::PlaneFiber) = forces(fiber.layers[end])

#######################################

struct PlaneCohesive end

function displacements(cohesive::PlaneCohesive) end

function forces(cohesive::PlaneCohesive) end

#######################################

struct PlaneCell
    fibers ::Vector{ PlaneFiber{Float} }
    cohesive ::PlaneCohesive{Float}
    slae_A ::Matrix{Float}
end

function fill_slae_from_fibers!(cell::PlaneCell)

end

###############################################################################
###############################################################################
###############################################################################

struct Contour
    center    ::Complex{ Rational{Int} }
    radius    ::Float
    max_power ::Int
end

abstract type ProblemType end

abstract type Fiber{P <: ProblemType} end

abstract type Cohesive{P <: ProblemType} end

abstract type SubMatrixType{P <: ProblemType} end

struct SubMatrix_Zero{P <: ProblemType} <: SubMatrixType{P}
    contour ::Contour
end

struct SubMatrix_Fiber{P <: ProblemType} <: SubMatrixType{P}
    contour ::Contour
    fiber   ::Fiber{P}
end

struct SubMatrix_Cohesive{P <: ProblemType} <: SubMatrixType{P}
    contour  ::Contour
    cohesive ::Cohesive{P}
end

abstract type SubMatrix_Averaging{P <: ProblemType} <: SubMatrixType{P} end

struct ReferenceMatrix{P <: ProblemType}
    matrix ::Matrix{ SubMatrixType{P} }
end

#==============================================================================
Ellipticals
==============================================================================#

struct EllipticPraecursor{FL <: AbstractFloat}
    terms :: OffsetVector{ Complex{FL} }
end

end # module Design

ext: jl


text:
# This file is a part of SimilaritySearch.jl

"""
    mutable struct RandomHints

Indicates that hints are a random sample of the dataset
"""
@with_kw mutable struct RandomHints <: Callback
    logbase::Float32 = 1.1
end

"""
    executed_callback(opt::RandomHints, index)

SearchGraph's callback for selecting hints at random
"""
function execute_callback(opt::RandomHints, index)
    n = length(index)
    m = ceil(Int, log(opt.logbase, n))
    empty!(index.hints)
    V = Set{Int}()

    for i in 1:m
        p = rand(1:n)
        if !(p in V)
            push!(V, p)
            push!(index.hints, p)
        end
    end
end

function callback__(opt::RandomHints, index)
    empty!(index.hints)
    push!(index.hints, 1)
end

"""
    mutable struct DisjointHints

Indicates that hints are a small disjoint (untouched neighbors) subsample
"""
@with_kw mutable struct DisjointHints <: Callback
    logbase::Float32 = 1.1
end

function execute_callback(opt::DisjointHints, index)
    n = length(index)
    m = ceil(Int, log(opt.logbase, n))
    empty!(index.hints)
    meansize = mean(length(index.links[i]) for i in 1:n)
    res = KnnResult(m)
    for i in 1:n
        push!(res, i, abs(length(index.links[i]) - meansize))
    end

    V = Set{Int}()
    for i in res.id
        i in V && continue
        push!(index.hints, i)
        push!(V, i)
        union!(V, index.links[i])
    end
end
"""
    struct KDisjointHints

Indicates that hints are selected to have a disjoint neighborhood
"""
@with_kw struct KDisjointHints <: Callback
    logbase::Float32 = 1.1
    disjoint::Int32 = 3
    expansion::Int32 = 4
end

"""
    execute_callback(opt::KDisjointHints, index)

SearchGraph's callback for selecting hints at random
"""
function execute_callback(opt::KDisjointHints, index)
    n = length(index)
    m = ceil(Int, log(opt.logbase, length(index)))
    sample = unique(rand(1:n, opt.expansion * m))
    m = min(length(sample), m)
    sort!(sample, by=i->length(index.links[i]), rev=true)

    visited = Set{Int32}()
    empty!(index.hints)
    E = Pair{Int32,Int32}[]
    i = 1
    while length(index.hints) < m && i < length(sample)
        # p = rand(1:n)
        p = sample[i]
        i += 1
        p in visited && continue
        push!(index.hints, p)
        push!(visited, p)
        # visit the neighborhood with some expansion factor
        push!(E, p => 0)
        while length(E) > 0
            parent, e = pop!(E)
            for child in keys(index.links[parent])
                if !(child in visited)
                    push!(visited, child)
                    e + 1 <= opt.expansion && push!(E, child => e + 1)
                end
            end
        end
    end

    # @info "disjoint hints $m --> $(length(index.hints))"
end

max_stars_repo_name: sadit/SimilaritySearch

max_issues_repo_name: sadit/NNS

max_forks_repo_name: sadit/SimilaritySearch


text:
@testset "filter" begin
  N = 347
  for T ∈ (Float32, Float64, Int32, Int64)
    @show T, @__LINE__
    if T <: Integer
      x = rand(T(-100):T(100), N)
    else
      x = rand(T, N)
    end
    y1 = filter(a -> a > 0.7, x)
    y2 = vfilter(a -> a > 0.7, x)
    @test y1 == y2
    y1 = filter(a -> a ≤ 0.7, x)
    y3 = vfilter(a -> a ≤ 0.7, x)
    @test y1 == y3
    @test length(y2) + length(y3) == N
  end
end


text:
module TimeseriesSurrogates

# TODO: I think it is more clear when each file uses the packages it needs instead of
# the global usage here. It makes it easier to understand how each algorithm works
# and what it needs
using Distributions
using StatsBase
using InplaceOps
using AbstractFFTs
using DSP
using Interpolations
using Wavelets
using Requires

include("api.jl")

include("utils/testsystems.jl")

# Periodogram interpolation
include("utils/interpolation.jl")

# The different surrogate routines
include("methods/randomshuffle.jl")
include("methods/large_shuffle.jl")
include("methods/randomfourier.jl")
include("methods/aaft.jl")
include("methods/iaaft.jl")
include("methods/truncated_fourier.jl")
include("methods/wavelet_based.jl")
include("methods/pseudoperiodic.jl")
include("methods/multidimensional.jl")
include("methods/ar.jl")

# Visualization routine for time series + surrogate + periodogram/acf/histogram
using Requires
function __init__()
    @require Plots="91a5bcdd-55d7-5caf-9e0b-520d859cae80" begin
        include("plotting/surrogate_plot.jl")
    end
    @require UncertainData="dcd9ba68-c27b-5cea-ae21-829cd07325bf" begin
        include("utils/uncertaindatasets.jl")
    end
end

end # module


text:
export ModuleProvider, dispose

# TODO: use this class implicitly? ie. when passing Modules to functions expecting a
#       ModuleProvider. Especially because dispose(mp) destroys the underlying mod.

@checked struct ModuleProvider
    ref::API.LLVMModuleProviderRef
end

Base.unsafe_convert(::Type{API.LLVMModuleProviderRef}, mp::ModuleProvider) = mp.ref

ModuleProvider(mod::Module) =
    ModuleProvider(API.LLVMCreateModuleProviderForExistingModule(mod))

function ModuleProvider(f::Core.Function, args...)
    mp = ModuleProvider(args...)
    try
        f(mp)
    finally
        dispose(mp)
    end
end

# NOTE: this destroys the underlying module
dispose(mp::ModuleProvider) = API.LLVMDisposeModuleProvider(mp)


text:
export Lambertian, Metal, Dielectric

reflect(v, n) =  v - 2dot(v,n)*n

struct Lambertian <: Material
	albedo::Color
	Lambertian(c::Color) = new(c)
	Lambertian(r,g,b) = new(Color(r,g,b))
	Lambertian() = Lambertian(Color(rand()*rand(), rand()*rand(), rand()*rand()))
end

function scatter(l::Lambertian, ray::Ray, hit::Hit)
	scatter_direction = hit.normal + random_unit_vector()
	if near_zero(scatter_direction)
		scatter_direction = hit.normal
	end
	Ray(hit.p, scatter_direction), l.albedo
end

struct Metal <: Material
	albedo::Color
	fuzz::Float64
	Metal(a, f) = new(a, f)
	Metal(r,g,b,f) = Metal(Color(r,g,b), f)
end

function scatter(m::Metal, ray::Ray, hit::Hit)
	reflected = reflect(ray.udirection, hit.normal)
    scattered = Ray(hit.p, reflected + m.fuzz * random_in_unit_sphere())
	dot(scattered.direction, hit.normal) > 0 ? (scattered, m.albedo) : (Ray(), zero(Color))
end

struct Dielectric <: Material
	ir::Float64
end

function scatter(d::Dielectric, ray::Ray, hit::Hit)

	function reflectance(cosine, ratio)
		r = ((1-ratio) / (1+ratio))^2
		r + (1-r)*(1 - cosine)^5
	end

	refraction_ratio = hit.front_face ? (1.0/d.ir) : d.ir

	cos_theta = min(dot(-ray.udirection, hit.normal), 1.0)
	sin_theta = sqrt(1.0 - cos_theta^2)
	cannot_refract = refraction_ratio * sin_theta > 1.0
	direction = if cannot_refract || reflectance(cos_theta, refraction_ratio) > rand()
			reflect(ray.udirection, hit.normal)
		else
			refract(ray.udirection, hit.normal, refraction_ratio)
		end

	Ray(hit.p, direction), Color(1,1,1)
end


text:
"""
    DensityMatrix

Density matrix, represented with respect to identity and Pauli basis (σ_j/2) by storing
4 real coefficients for each qubit, i.e., a real vector of length `4^N` for `N` qubits.
"""
struct DensityMatrix
    "coefficients with respect to identity and Pauli basis"
    v::Vector{Float64}
    "number of qubits"
    N::Int

    @doc """
        DensityMatrix(v::AbstractVector{<:Real}, N::Integer)

    Density matrix representation given Pauli-vector dotted with with vector of coefficients
    """
    function DensityMatrix(v::AbstractVector{<:Real}, N::Integer)
        length(v) == 4^N || error("Expected length of coefficient vector for density matrix is `4^N`.")
        new(v, N)
    end

    @doc """
        DensityMatrix(v::AbstractVector{<:Real})

    Density matrix representation given Pauli-vector dotted with with vector of coefficients
    """
    function DensityMatrix(v::AbstractVector{<:Real})
        N = intlog2(length(v)) ÷ 2
        length(v) == 4^N || error("Expected length of coefficient vector for density matrix is `4^N` for some integer `N`.")
        new(v, N)
    end
end

"""
    matrix(ρ::DensityMatrix)

Matrix representation of density matrix `ρ`.
"""
function matrix(ρ::DensityMatrix)
    # Pauli matrix basis (including identity matrix)
    halfpauli = SparseMatrixCSC{ComplexF64,Int}[
        0.5 * sparse(one(ComplexF64)*I, 2, 2),
        0.5 * sparse_matrix(X),
        0.5 * sparse_matrix(Y),
        0.5 * sparse_matrix(Z),
    ]
    mat = zeros(ComplexF64, 2^ρ.N, 2^ρ.N)
    m = quaternary_digits(ρ.N, 0)
    for i in 1:4^ρ.N
        mat += ρ.v[i] * kron([halfpauli[p + 1] for p in reverse(quaternary_digits!(m, i - 1))]...)
    end
    return mat
end

"""
    density_from_statevector(ψ::Vector)

Construct density matrix |ψ⟩⟨ψ| (Pauli representation) corresponding to quantum state `ψ`.
```jldoctest
julia> ψ = 1/sqrt(2)[1, -1]; # create ket - state.
julia> ρ = density_from_statevector(ψ)
DensityMatrix([0.9999999999999998, -0.9999999999999998, 0.0, 0.0], 1)
```
"""
function density_from_statevector(ψ::Vector)
    N = intlog2(length(ψ))
    2^N == length(ψ) || error("Length of input vector must be a power to 2.")
    pauli = SparseMatrixCSC{ComplexF64,Int}[
        sparse(one(ComplexF64)*I, 2, 2),
        sparse_matrix(X),
        sparse_matrix(Y),
        sparse_matrix(Z),
    ]
    v = zeros(4^N)
    m = quaternary_digits(N, 0)
    for i in 1:4^N
        v[i] = real(dot(ψ, kron([pauli[p + 1] for p in reverse(quaternary_digits!(m, i - 1))]...) * ψ))
    end
    return DensityMatrix(v, N)
end

"""
    density_from_matrix(ρmat::AbstractMatrix)

Construct density matrix in Pauli representation from matrix `ρmat`.
```jldoctest
julia> ρmat = 0.15 .*[ 1 -1; -1  1] + 0.35 .* [1 1; 1 1]; # create mixed state of + and -.
julia> ρ = density_from_matrix(ρmat)
DensityMatrix([1.0, 0.39999999999999997, 0.0, 0.0], 1)
```
"""
function density_from_matrix(ρmat::AbstractMatrix)
    N = intlog2(size(ρmat, 1))
    (2^N == size(ρmat, 1) && 2^N == size(ρmat, 2)) || error("Input must be a square `2^N × 2^N` matrix.")
    pauli = SparseMatrixCSC{ComplexF64,Int}[
        sparse(one(ComplexF64)*I, 2, 2),
        sparse_matrix(X),
        sparse_matrix(Y),
        sparse_matrix(Z),
    ]
    v = zeros(4^N)
    m = quaternary_digits(N, 0)
    for i in 1:4^N
        v[i] = real(tr(kron([pauli[p + 1] for p in reverse(quaternary_digits!(m, i - 1))]...) * ρmat))
    end
    return DensityMatrix(v, N)
end

"""
    pauli_group_matrix(ipauli)

Construct a Pauli group matrix (N-fold tensor products of identity and Pauli matrices)
encoded as `DensityMatrix`. `ipauli[j]` specifies the j-th matrix as integer 0,...,3.
"""
function pauli_group_matrix(ipauli::AbstractVector{<:Integer})
    i4 = Matrix{Int}(I, 4, 4)
    DensityMatrix(kron([2 * i4[i + 1, :] for i in reverse(ipauli)]...), length(ipauli))
end

function pauli_group_matrix(paulistring::String)
    pd = Dict('I' => 0, 'X' => 1, 'Y' => 2, 'Z' => 3)
    pauli_group_matrix([pd[s] for s in paulistring])
end


text:
### Generate measurements
@inbounds function rungenerator(system, measurements, num, numsys, settings, info; flow = 0)
    if settings.runflow == 1
        branch = flow.flow; bus = flow.main
        busi, Vi, Ti, Pinj, Qinj, branchi, fromi, toi, Pij,
            Qij, Pji, Qji, Iij, Dij, Iji, Dji = read_generator(bus, branch)

        for i = 1:numsys.Nbranch
            measurements.legacyFlow[i, 1] = branchi[i]
            measurements.legacyFlow[i + numsys.Nbranch, 1] = branchi[i]
            measurements.legacyFlow[i, 2] = fromi[i]
            measurements.legacyFlow[i + numsys.Nbranch, 2] = toi[i]
            measurements.legacyFlow[i, 3] = toi[i]
            measurements.legacyFlow[i + numsys.Nbranch, 3] = fromi[i]
            measurements.legacyFlow[i, 10] = Pij[i] / system.basePower
            measurements.legacyFlow[i + numsys.Nbranch, 10] = Pji[i] / system.basePower
            measurements.legacyFlow[i, 11] = Qij[i] / system.basePower
            measurements.legacyFlow[i + numsys.Nbranch, 11] = Qji[i] / system.basePower

            measurements.legacyCurrent[i, 1] = branchi[i]
            measurements.legacyCurrent[i + numsys.Nbranch, 1] = branchi[i]
            measurements.legacyCurrent[i, 2] = fromi[i]
            measurements.legacyCurrent[i + numsys.Nbranch, 2] = toi[i]
            measurements.legacyCurrent[i, 3] = toi[i]
            measurements.legacyCurrent[i + numsys.Nbranch, 3] = fromi[i]
            measurements.legacyCurrent[i, 7] = Iij[i]
            measurements.legacyCurrent[i + numsys.Nbranch, 7] = Iji[i]

            measurements.pmuCurrent[i, 1] = branchi[i]
            measurements.pmuCurrent[i + numsys.Nbranch, 1] = branchi[i]
            measurements.pmuCurrent[i, 2] = fromi[i]
            measurements.pmuCurrent[i + numsys.Nbranch, 2] = toi[i]
            measurements.pmuCurrent[i, 3] = toi[i]
            measurements.pmuCurrent[i + numsys.Nbranch, 3] = fromi[i]
            measurements.pmuCurrent[i, 10] = Iij[i]
            measurements.pmuCurrent[i + numsys.Nbranch, 10] = Iji[i]
            measurements.pmuCurrent[i, 11] = (pi / 180) * Dij[i]
            measurements.pmuCurrent[i + numsys.Nbranch, 11] = (pi / 180) * Dji[i]
        end

        for i = 1:numsys.Nbus
            measurements.legacyInjection[i, 1] = busi[i]
            measurements.legacyInjection[i, 8] = Pinj[i] / system.basePower
            measurements.legacyInjection[i, 9] = Qinj[i] / system.basePower

            measurements.legacyVoltage[i, 1] = busi[i]
            measurements.legacyVoltage[i, 5] = Vi[i]

            measurements.pmuVoltage[i, 1] = busi[i]
            measurements.pmuVoltage[i, 8] = Vi[i]
            measurements.pmuVoltage[i, 9] = (pi / 180) * Ti[i]
        end
    end

    names = Dict(:pmu => [:pmuVoltage, :pmuCurrent], :legacy => [:legacyFlow, :legacyCurrent, :legacyInjection, :legacyVoltage])
    measure = [:pmuVoltage, :pmuCurrent, :legacyFlow, :legacyCurrent, :legacyInjection, :legacyVoltage]
    pmuv = 1; pmuc = 1; legf = 1; legc = 1; legi = 1; legv = 1
    if num.pmuNv == 0 measure[1] = :no; pmuv = 0  end
    if num.pmuNc == 0 measure[2] = :no; pmuc = 0 end
    if num.legacyNf == 0 measure[3] = :no; legf = 0 end
    if num.legacyNc == 0 measure[4] = :no; legc = 0 end
    if num.legacyNi == 0 measure[5] = :no; legi = 0 end
    if num.legacyNv == 0 measure[6] = :no; legv = 0 end
    names[:legacy] = intersect(names[:legacy], measure)
    names[:pmu] = intersect(names[:pmu], measure)

    measurements = runset(system, measurements, numsys, settings, names)
    measurements = runvariance(system, measurements, settings, names)
    info = infogenerator(system, measurements, settings, info, names)

    gen = 2
    if numsys.Ngen == 0
        gen = 0
    end
    cost = 2
    if numsys.Ncost == 0
        cost = 0
    end
    group = (pmuVoltage = pmuv, pmuCurrent = pmuc, legacyFlow = legf, legacyCurrent = legc, legacyInjection = legi, legacyVoltage = legv, bus = 2, branch = 2, generator = gen, generatorcost = cost, basePower = 2)

    println("Measurment data is successfully generated.")
    if !isempty(settings.save)
        mheader = measureheader(); pheader = psheader(system); header = merge(mheader, pheader)
        savedata(measurements, system; group = group, header = header, path = settings.save, info = info)
    end

    return info
end

### Produce  measurement set
@inbounds function runset(system, measurements, numsys, settings, names)
    write = (pmuVoltage = [4, 7], pmuCurrent = [6, 9], legacyFlow = [6, 9], legacyCurrent = [6], legacyInjection = [4, 7], legacyVoltage = [4])
    type = (pmucomplete = :pmu,  legacycomplete = :legacy, pmuredundancy = :pmu,  legacyredundancy = :legacy)

    for set in keys(settings.set)
        if set in [:pmucomplete :legacycomplete]
            for i in names[type[set]]
                T::Array{Float64,2} = getfield(measurements, i)
                T[:, write[i]] = ones(size(T, 1), length(write[i]))
            end
        end
        if set in [:pmuVoltage, :pmuCurrent, :legacyFlow, :legacyCurrent, :legacyInjection, :legacyVoltage]
            for (pos, howMany) in enumerate(settings.set[set])
                success = false
                T::Array{Float64,2} = getfield(measurements, set)
                N = size(T, 1)
                if 0 <= howMany <= N
                    success = true
                    T[:, write[set][pos]] = zeros(N)
                    idxn = randperm(N)
                    idx = idxn[1:Int64(howMany)]
                    T[idx, write[set][pos]] = ones(N)[idx]
                elseif howMany > N || howMany == -200.0
                    success = true
                    T[:, write[set][pos]] = zeros(N)
                    T[:, write[set][pos]] = ones(N)
                elseif !success && howMany != -100
                    throw(ErrorException("the name-value pair setting is incorect, deployment measurements according to TYPE failed"))
                end
            end
        end
        if set in [:pmuredundancy :legacyredundancy]
            Nmax = 0
            for i in names[type[set]]
                Nmax += length(write[i]) * size(getfield(measurements, i), 1)
            end
            success = false
            howMany = settings.set[set][1]
            if 0 <= howMany <= Nmax / (2 * numsys.Nbus - 1)
                success = true
                idxn = randperm(Nmax)
                idx = idxn[1:trunc(Int, round((2 * numsys.Nbus - 1) * howMany))]
                total_set = fill(0.0, Nmax)
                total_set[idx] = ones(Nmax)[idx]
            elseif howMany > Nmax / (2 * numsys.Nbus - 1) || howMany == -200.0
                success = true
                total_set = fill(1.0, Nmax)
            end
            if success
                start = 0
                last = 0
                for i in names[type[set]]
                    for k in write[i]
                        T::Array{Float64,2} = getfield(measurements, i)
                        last += size(T, 1)
                        T[:, k] = total_set[(start + 1):last]
                        start += size(T, 1)
                    end
                end
            else
                throw(ErrorException("the name-value pair setting is incorect, deployment measurements according to REDUNDANCY failed"))
            end
        end
        if set == :pmudevice
            if :pmuVoltage in names[:pmu] && :pmuCurrent in names[:pmu]
                success = false
                howMany = settings.set[set][1]
                N = size(measurements.pmuVoltage, 1)
                if 0 <= howMany <= N
                    success = true
                    idxn = randperm(N)
                    idx = idxn[1:Int64(howMany)]
                elseif howMany > N || howMany == -200.0
                    success = true
                    idx = collect(1:N)
                end
                if success
                    Nc = size(measurements.pmuCurrent, 1)
                    measurements.pmuVoltage[:, [4, 7]] = zeros(N, 2)
                    measurements.pmuCurrent[:, [6, 9]] = zeros(Nc, 2)
                    labelVol = measurements.pmuVoltage[:, 1]
                    labelCurr = measurements.pmuCurrent[:, 2]
                    try
                        labelVol = measurements.pmuVoltage[:, 10]
                        labelCurr = measurements.pmuCurrent[:, 12]
                    catch
                    end
                    for i in idx
                        measurements.pmuVoltage[i, 4] = 1.0
                        measurements.pmuVoltage[i, 7] = 1.0
                        for j = 1:size(measurements.pmuCurrent, 1)
                            if labelVol[i] == labelCurr[j]
                                measurements.pmuCurrent[j, 6] = 1.0
                                measurements.pmuCurrent[j, 9] = 1.0
                            end
                        end
                    end
                else
                    throw(ErrorException("the name-value pair setting is incorect, deployment measurements according to DEVICE failed"))
                end
            else
                throw(ErrorException("the complete PMU measurement DATA is not found"))
           end
        end
        if set == :pmuoptimal
            if :pmuVoltage in names[:pmu] && :pmuCurrent in names[:pmu]
                Nvol = size(measurements.pmuVoltage, 1)
                Ncurr = size(measurements.pmuCurrent, 1)
                if Nvol == numsys.Nbus && Ncurr == 2 * numsys.Nbranch
                    bus = collect(1:numsys.Nbus)
                    numbering = false
                    fromi = convert(Array{Int64,1}, system.branch[:, 2])
                    toi = convert(Array{Int64,1}, system.branch[:, 3])
                    busi = @view(system.bus[:, 1])
                    for i = 1:numsys.Nbus
                        if bus[i] != busi[i]
                            numbering = true
                        end
                    end
                    from = renumber(fromi, busi, bus, numbering)
                    to = renumber(toi, busi, bus, numbering)

                    A = sparse([bus; from; to], [bus; to; from], fill(1, numsys.Nbus + 2 * numsys.Nbranch), numsys.Nbus, numsys.Nbus)
                    f  = fill(1, numsys.Nbus);
                    lb = fill(0, numsys.Nbus);
                    ub = fill(1, numsys.Nbus);
                    model = Model(GLPK.Optimizer)

                    @variable(model, x[i = 1:numsys.Nbus], Int)
                    @constraint(model, lb .<= x .<= ub)
                    @constraint(model, -A * x .<= -f)
                    @objective(model, Min, sum(x))
                    optimize!(model)
                    x = JuMP.value.(x)
                    idx = findall(x->x == 1, x)

                    measurements.pmuVoltage[:, [4, 7]] = zeros(Nvol, 2)
                    measurements.pmuCurrent[:, [6, 9]] = zeros(Ncurr, 2)
                    for i in idx
                        measurements.pmuVoltage[i, 4] = 1.0
                        measurements.pmuVoltage[i, 7] = 1.0
                        for j = 1:numsys.Nbranch
                            if busi[i] == fromi[j]
                                measurements.pmuCurrent[j, 6] = 1.0
                                measurements.pmuCurrent[j, 9] = 1.0
                            end
                            if busi[i] == toi[j]
                                measurements.pmuCurrent[j + numsys.Nbranch, 6] = 1.0
                                measurements.pmuCurrent[j + numsys.Nbranch, 9] = 1.0
                            end
                        end
                    end
                else
                    throw(ErrorException("the optimal algorithm requires the concordant number of buses and branches, and corresponding measurements"))
                end
            else
                throw(ErrorException("the complete PMU measurement DATA is not found"))
            end
        end
    end

    return measurements
end

### Produce measurement variances
@inbounds function runvariance(system, measurements, settings, names)
    write = (pmuVoltage = [2 8 3; 5 9 6], pmuCurrent = [4 10 5; 7 11 8], legacyFlow = [4 10 5; 7 11 8], legacyCurrent = [4 7 5], legacyInjection = [2 8 3; 5 9 6], legacyVoltage = [2 5 3])
    type = (pmucomplete = :pmu, legacycomplete = :legacy, pmurandom = :pmu, legacyrandom = :legacy)

    for var in keys(settings.variance)
        if var in [:pmucomplete :legacycomplete]
            howMany = settings.variance[var][1]
            if howMany > 0
                for i in names[type[var]]
                    T::Array{Float64,2} = getfield(measurements, i)
                    for row in eachrow(write[i])
                        T[:, row[3]] .= howMany
                        T[:, row[1]] .= T[:, row[2]] .+ howMany.^(1/2) .* randn!(zeros(size(T, 1)))
                    end
                end
            else
                error("the variance must be positive number")
            end
        end
        if var in [:pmurandom :legacyrandom]
            min = minimum(settings.variance[var])
            max = maximum(settings.variance[var])
            if min > 0 && max > 0
                for i in names[type[var]]
                    T::Array{Float64,2} = getfield(measurements, i)
                    for row in eachrow(write[i])
                        T[:, row[3]] .= min .+ (max - min) .* rand(size(T, 1))
                        T[:, row[1]] .= T[:, row[2]] .+ T[:, row[3]].^(1/2) .* randn!(zeros(size(T, 1)))

                    end
                end
            else
                throw(ErrorException("the variance value must be positive number"))
            end
        end
        if var in [:pmuVoltage, :pmuCurrent, :legacyFlow, :legacyCurrent, :legacyInjection, :legacyVoltage]
            for (pos, howMany) in enumerate(settings.variance[var])
                if howMany != -100.0
                    if howMany > 0
                        T::Array{Float64,2} = getfield(measurements, var)
                        T[:, write[var][pos, 3]] .= howMany
                        T[:, write[var][pos, 1]] .= T[:, write[var][pos, 2]] .+ howMany.^(1/2) .* randn!(zeros(size(T, 1)))
                    else
                        throw(ErrorException("the variance value must be positive number"))
                    end
                end
            end
        end
    end

    return measurements
end

### Read data
function read_generator(bus, branch)
    busi = @view(bus[:, 1])
    Vi = @view(bus[:, 2])
    Ti = @view(bus[:, 3])
    Pinj = @view(bus[:, 4])
    Qinj = @view(bus[:, 5])

    branchi = @view(branch[:, 1])
    fromi = @view(branch[:, 2])
    toi = @view(branch[:, 3])
    Pij = @view(branch[:, 4])
    Qij = @view(branch[:, 5])
    Pji = @view(branch[:, 6])
    Qji = @view(branch[:, 7])
    Iij = @view(branch[:, 11])
    Dij = @view(branch[:, 12])
    Iji = @view(branch[:, 13])
    Dji = @view(branch[:, 14])

    return busi, Vi, Ti, Pinj, Qinj,
        branchi, fromi, toi, Pij, Qij, Pji, Qji, Iij, Dij, Iji, Dji
end

max_stars_repo_name: mcosovic/JuliaGrid

max_issues_repo_name: mcosovic/JuliaGrid

max_forks_repo_name: mcosovic/JuliaGrid


text:
function fft_t_to_ω(arr::AbstractArray, dt, dim = 1)
	rfft(arr, dim) .* dt
end
function fft_t_to_ω(arr::OffsetArray, dt, dim = 1)
	rfft(parent(arr), dim) .* dt
end

function fft_ω_to_t(arr::AbstractArray, dν, dim = 1, Nt = 2*(size(arr, dim)-1))
	brfft(arr, Nt, dim) .* dν
end
function fft_ω_to_t(arr::OffsetArray, dν, dim = 1, Nt = 2*(size(arr, dim)-1))
	brfft(parent(arr),Nt, dim) .* dν
end


text:
## Fit counties with significant sero data

## Do inference in parallel

using Distributed

## add number of processors desired
# addprocs(2)
params = (exename = `nice -19 /Applications/Julia-1.7.app/Contents/Resources/julia/bin/julia`,
      dir = "./Github/KenyaCoVaccinesPrivate")
addprocs([("samandfi@10.0.0.6", 7)]; params...)
addprocs(4)

@everywhere begin
      using Pkg
      Pkg.activate(".")
end

## Load relevant code into scope for each worker

@everywhere using JLD2, LinearAlgebra, TransformVariables, LogDensityProblems, MCMCChains, Dates
@everywhere import KenyaCoVaccines

## Load data
# @everywhere begin
using DataFrames
@load("data/linelist_data_with_pos_neg_20feb_to_27sept_c_age__pcr.jld2")
@load("data/cleaned_serology_data_c_age__combined.jld2")
@load("data/deaths_20210919.jld2")
@load("data/p_IH.jld2")
@load("data/p_ID.jld2")

##Load contact structure and population size data
M_Kenya_ho, M_Kenya_other, M_Kenya_school, M_Kenya_work = KenyaCoVaccines.get_rescaled_contact_matrices("data/agemixingmatrix_Kenya_all_types.jld2")
N_kenya = KenyaCoVaccines.get_population_size_matrix("data/2019_census_age_pyramids_counties.csv")

# Parameter transformations and initial KE guess for HMC

trans = as((
      β₀ = as(Real, 0.0, 5.0),  #β₀= as(Real, 0.0, 7.0),
      β_home = as(Real, 0.0, 5.0),
      β_school = as(Real, 0.0, 5.0),
      β_other = as(Real, 0.0, 5.0),
      β_work = as(Real, 0.0, 5.0),
      ϵ = as(Real, 0.0, 0.999),
      χ = as(Real, 0.1, 30.0),
      p_test = as(Real, 0.01, 5),
      E₀ = as(Real, 0.0, 10e3),
      inc_R_αvar = as(Real, 0.0, 1.0),
      time_scale_αvar = as(Real, 0.01, 0.5),
      mid_point_αvar = as(Real, 0.0, 4.0),
      inc_R_δvar = as(Real, 0.001, 1.5),
      time_scale_δvar = as(Real, 0.01, 0.5),
      mid_point_δvar = as(Real, 0.0, 4.0),
      init_scale = as(Real, 0.0, 2.0)
))

D = Diagonal(0.1 * ones(TransformVariables.dimension(trans)))

# end

## Name for each county with substantial serological data, and matching priors

counties_with_serodata = ["Nairobi", "Mombasa",
      "Nakuru", "Uasin Gishu", "Embu", "Kisumu", "Siaya", "Kisii", "Nyeri",
      "Kilifi", "Kwale"]

priors = [fill(KenyaCoVaccines.priors_onegroup_alpha_delta_variant_cities, 2)
      fill(KenyaCoVaccines.priors_onegroup_alpha_delta_variant_outside_cities, 9)]

#Baseline seropos for low density coverage counties at December 1st
#Based on the unweighted seroprevalence from Ngere et al in Nairobi mid-Sept

init_sero_baseline = [(34 + 74) / (179 + 244), (100 + 95 + 51) / (265 + 241 + 134), 21 / 61, 9 / 40, 9 / 40, 9 / 40]

## parallelised loop for fitting each county
@distributed for i = 1:11
      name = counties_with_serodata[i]
      prior = priors[i]
      model = KenyaCoVaccines.CoVAreaModel(name, KenyaCoVaccines.ll_onegroup_newvariant_infboost, prior;
            linelist_data_with_pos_neg = linelist_data_with_pos_neg,
            serology_data = serology_data,
            average_sero_init = init_sero_baseline,
            deaths = deaths_data,
            pop_data = N_kenya,
            M_county_ho = M_Kenya_ho,
            M_county_other = M_Kenya_other,
            M_county_school = M_Kenya_school,
            M_county_work = M_Kenya_work,
            rapid = false,
            scenario = 0,
            startdate = Date(2020, 12, 1),
            enddate = Date(2021, 9, 24))

      KenyaCoVaccines.inferparameters!(model, 2000, trans, 0.05, D; serowaningrate = 0.0)
      @save("modelfits/$(name)_model.jld2", model)

end
##
rmprocs(workers())

##Tests
@everywhere counties_with_serodata = ["Nairobi", "Mombasa",
      "Nakuru", "Uasin Gishu", "Embu", "Kisumu", "Siaya", "Kisii", "Nyeri",
      "Kilifi", "Kwale"]

@everywhere priors = [fill(KenyaCoVaccines.priors_onegroup_alpha_delta_variant_cities, 2)
      fill(KenyaCoVaccines.priors_onegroup_alpha_delta_variant_outside_cities, 9)]

r = @spawnat 2 begin
      name = counties_with_serodata[1]
      prior = priors[1]
      model = KenyaCoVaccines.CoVAreaModel(name, KenyaCoVaccines.ll_onegroup_newvariant_infboost, prior;
            linelist_data_with_pos_neg = linelist_data_with_pos_neg,
            serology_data = serology_data,
            average_sero_init = init_sero_baseline,
            deaths = deaths_data,
            pop_data = N_kenya,
            M_county_ho = M_Kenya_ho,
            M_county_other = M_Kenya_other,
            M_county_school = M_Kenya_school,
            M_county_work = M_Kenya_work,
            rapid = false,
            scenario = 0,
            startdate = Date(2020, 12, 1),
            enddate = Date(2021, 9, 24))

      # KenyaCoVaccines.inferparameters!(model, 2000, trans, 0.05, D; serowaningrate = 0.0)
      # @save("modelfits/$(name)_model.jld2", model)
end

model = fetch(r)

name = counties_with_serodata[1]
prior = priors[1]
model = KenyaCoVaccines.CoVAreaModel(name, KenyaCoVaccines.ll_onegroup_newvariant_infboost, prior;
      PCR_cases = linelist_data_with_pos_neg,
      sero_cases = serology_data,
      average_sero_init = init_sero_baseline,
      deaths = deaths_data,
      pop_data = N_kenya,
      M_county_ho = M_Kenya_ho,
      M_county_other = M_Kenya_other,
      M_county_school = M_Kenya_school,
      M_county_work = M_Kenya_work,
      rapid = false,
      scenario = 0,
      startdate = Date(2020, 12, 1),
      enddate = Date(2021, 9, 24))
KenyaCoVaccines.inferparameters!(model, 2000, trans, 0.05, D; serowaningrate = 0.0)


text:
# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     formats: ipynb,jl:hydrogen
#     text_representation:
#       extension: .jl
#       format_name: hydrogen
#       format_version: '1.3'
#       jupytext_version: 1.11.2
#   kernelspec:
#     display_name: Julia 1.7.0-beta2
#     language: julia
#     name: julia-1.7
# ---

# %%
@show VERSION
using BenchmarkTools
pimc_sum(n) = 4sum(rand()^2 + rand()^2 ≤ 1 for _ in 1:n)/n
@btime pimc_sum(10^7)

# %%
@show VERSION
using BenchmarkTools, Random
pimc_sum(n, rng) = 4sum(rand(rng)^2 + rand(rng)^2 ≤ 1 for _ in 1:n)/n
@btime pimc_sum(10^7, $(Random.default_rng()))

# %%
@show VERSION
using BenchmarkTools, Random
function pimc_for(n, rng)
    c = 0
    for _ in 1:n
        c += rand(rng)^2 + rand(rng)^2 ≤ 1
    end
    4c/n
end
@btime pimc_for(10^7, $(Random.default_rng()))

# %%
@show VERSION
@btime pimc_sum(10^7, $(MersenneTwister()))
@btime pimc_for(10^7, $(MersenneTwister()))

# %%
@show VERSION
f3(n) = sum(k^3 for k in 1:n)
f4(n) = sum(k^4 for k in 1:n)
@btime f3(10^6)
@btime f4(10^6)

# %%
@show VERSION
f3(n) = sum(k^3 for k in 1:n)
f4(n) = sum(k^4 for k in 1:n)
@btime f3($(Int128(10^6)))
@btime f4($(Int128(10^6)))

# %%
@code_typed f3(10^6)

# %%
@code_typed f4(10^6)

# %%

# %%
@show VERSION
using BenchmarkTools
pimc_sum(n) = 4sum(rand()^2 + rand()^2 ≤ 1 for _ in 1:n)/n
@btime pimc_sum(10^7)

# %%
@show VERSION
using BenchmarkTools, Random
pimc_sum(n, rng) = 4sum(rand(rng)^2 + rand(rng)^2 ≤ 1 for _ in 1:n)/n
@btime pimc_sum(10^7, $(Random.default_rng()))

# %%
@show VERSION
using BenchmarkTools, Random
function pimc_for(n, rng)
    c = 0
    for _ in 1:n
        c += rand(rng)^2 + rand(rng)^2 ≤ 1
    end
    4c/n
end
@btime pimc_for(10^7, $(Random.default_rng()))

# %%
@show VERSION
@btime pimc_sum(10^7, $(MersenneTwister()))
@btime pimc_for(10^7, $(MersenneTwister()))

# %%
@show VERSION
f3(n) = sum(k^3 for k in 1:n)
f4(n) = sum(k^4 for k in 1:n)
@btime f3(10^6)
@btime f4(10^6)

# %%
@show VERSION
f3(n) = sum(k^3 for k in 1:n)
f4(n) = sum(k^4 for k in 1:n)
@btime f3($(Int128(10^6)))
@btime f4($(Int128(10^6)))

# %%
@code_typed f3(10^6)

# %%
@code_typed f4(10^6)

# %%

max_stars_repo_path: 0007/sum of generator.jl

max_stars_repo_name: genkuroki/public

max_issues_repo_path: 0007/sum of generator.jl

max_issues_repo_name: genkuroki/public

max_forks_repo_path: 0007/sum of generator.jl

max_forks_repo_name: genkuroki/public


text:
#### Tested moist thermodynamic profiles

#=
This file contains functions to compute all of the
thermodynamic _states_ that Thermodynamics is
tested with in runtests.jl
=#

using Random

"""
    ProfileSet

A set of profiles used to test Thermodynamics.
"""
struct ProfileSet{AFT, QPT, PT}
    z::AFT          # Altitude
    T::AFT          # Temperature
    p::AFT          # Pressure
    RS::AFT         # Relative saturation
    e_int::AFT      # Internal energy
    ρ::AFT          # Density
    θ_liq_ice::AFT  # Liquid Ice Potential temperature
    q_tot::AFT      # Total specific humidity
    q_liq::AFT      # Liquid specific humidity
    q_ice::AFT      # Ice specific humidity
    q_pt::QPT       # Phase partition
    RH::AFT         # Relative humidity
    e_pot::AFT      # gravitational potential
    u::AFT          # velocity (x component)
    v::AFT          # velocity (y component)
    w::AFT          # velocity (z component)
    e_kin::AFT      # kinetic energy
    phase_type::PT  # Phase type (e.g., `PhaseDry`, `PhaseEquil`)
end

function Base.iterate(ps::ProfileSet, state = 1)
    state > length(ps.z) && return nothing
    nt = (
        z = ps.z[state],
        T = ps.T[state],
        p = ps.p[state],
        RS = ps.RS[state],
        e_int = ps.e_int[state],
        ρ = ps.ρ[state],
        θ_liq_ice = ps.θ_liq_ice[state],
        q_tot = ps.q_tot[state],
        q_liq = ps.q_liq[state],
        q_ice = ps.q_ice[state],
        q_pt = ps.q_pt[state],
        RH = ps.RH[state],
        e_pot = ps.e_pot[state],
        u = ps.u[state],
        v = ps.v[state],
        w = ps.w[state],
        e_kin = ps.e_kin[state],
        phase_type = ps.phase_type,
    )
    return (nt, state + 1)
end
Base.IteratorSize(::ProfileSet) = Base.HasLength()
Base.length(ps::ProfileSet) = length(ps.z)

# Since we use `rand` to generate the ProfileSet,
# just initialize on the CPU, and provide convert
# function to move arrays to the GPU.
convert_profile_set(ps::ProfileSet, ArrayType, slice) = ProfileSet(
    ArrayType(ps.z[slice]),
    ArrayType(ps.T[slice]),
    ArrayType(ps.p[slice]),
    ArrayType(ps.RS[slice]),
    ArrayType(ps.e_int[slice]),
    ArrayType(ps.ρ[slice]),
    ArrayType(ps.θ_liq_ice[slice]),
    ArrayType(ps.q_tot[slice]),
    ArrayType(ps.q_liq[slice]),
    ArrayType(ps.q_ice[slice]),
    PhasePartition.(ps.q_tot[slice], ps.q_liq[slice], ps.q_ice[slice]),
    ArrayType(ps.RH[slice]),
    ArrayType(ps.e_pot[slice]),
    ArrayType(ps.u[slice]),
    ArrayType(ps.v[slice]),
    ArrayType(ps.w[slice]),
    ArrayType(ps.e_kin[slice]),
    ps.phase_type,
)

"""
    input_config(
        ArrayType;
        n=50,
        n_RS1=10,
        n_RS2=20,
        T_min=150,
        T_surface=340
    )

Return input arguments to construct profiles
"""
function input_config(
    ArrayType;
    n = 50,
    n_RS1 = 10,
    n_RS2 = 20,
    T_surface = 340,
    T_min = 150,
)
    n_RS = n_RS1 + n_RS2
    z_range = ArrayType(range(0, stop = 2.5e4, length = n))
    relative_sat1 = ArrayType(range(0, stop = 1, length = n_RS1))
    relative_sat2 = ArrayType(range(1, stop = 1.02, length = n_RS2))
    relative_sat = vcat(relative_sat1, relative_sat2)
    return z_range, relative_sat, T_surface, T_min
end

"""
    shared_profiles(
        param_set::AbstractParameterSet,
        z_range::AbstractArray,
        relative_sat::AbstractArray,
        T_surface,
        T_min,
    )

Compute profiles shared across `PhaseDry`,
`PhaseEquil` and `PhaseNonEquil` thermodynamic
states, including:
 - `z` altitude
 - `T` temperature
 - `p` pressure
 - `RS` relative saturation
"""
function shared_profiles(
    param_set::AbstractParameterSet,
    z_range::AbstractArray,
    relative_sat::AbstractArray,
    T_surface,
    T_min,
)
    FT = eltype(z_range)
    n_RS = length(relative_sat)
    n = length(z_range)
    T = similar(z_range, n * n_RS)
    p = similar(z_range, n * n_RS)
    RS = similar(z_range, n * n_RS)
    z = similar(z_range, n * n_RS)
    linear_indices = LinearIndices((1:n, 1:n_RS))
    # We take the virtual temperature, returned here,
    # as the temperature, and then compute a thermodynamic
    # state consistent with that temperature. This profile
    # will not be in hydrostatic balance, but this does not
    # matter for the thermodynamic test profiles.
    profile =
        DecayingTemperatureProfile{FT}(param_set, FT(T_surface), FT(T_min))
    for i in linear_indices.indices[1]
        for j in linear_indices.indices[2]
            k = linear_indices[i, j]
            z[k] = z_range[i]
            T[k], p[k] = profile(param_set, z[k])
            RS[k] = relative_sat[j]
        end
    end
    return z, T, p, RS
end

####
#### PhaseDry
####

"""
    PhaseDryProfiles(param_set, ::Type{ArrayType})

Returns a `ProfileSet` used to test dry thermodynamic states.
"""
function PhaseDryProfiles(
    param_set::AbstractParameterSet,
    ::Type{ArrayType},
) where {ArrayType}
    phase_type = PhaseDry

    z_range, relative_sat, T_surface, T_min = input_config(ArrayType)
    z, T_virt, p, RS =
        shared_profiles(param_set, z_range, relative_sat, T_surface, T_min)
    T = T_virt
    FT = eltype(T)
    _R_d::FT = R_d(param_set)
    _grav::FT = grav(param_set)
    ρ = p ./ (_R_d .* T)

    # Additional variables
    q_tot = similar(T)
    fill!(q_tot, 0)
    q_pt = PhasePartition_equil.(param_set, T, ρ, q_tot, phase_type)
    e_int = internal_energy.(param_set, T, q_pt)
    θ_liq_ice = liquid_ice_pottemp.(param_set, T, ρ, q_pt)
    q_liq = getproperty.(q_pt, :liq)
    q_ice = getproperty.(q_pt, :ice)
    RH = relative_humidity.(param_set, T, p, phase_type, q_pt)
    e_pot = _grav * z
    Random.seed!(15)
    u = rand(FT, size(T)) * 50
    v = rand(FT, size(T)) * 50
    w = rand(FT, size(T)) * 50
    e_kin = (u .^ 2 .+ v .^ 2 .+ w .^ 2) / 2

    return ProfileSet{typeof(T), typeof(q_pt), typeof(phase_type)}(
        z,
        T,
        p,
        RS,
        e_int,
        ρ,
        θ_liq_ice,
        q_tot,
        q_liq,
        q_ice,
        q_pt,
        RH,
        e_pot,
        u,
        v,
        w,
        e_kin,
        phase_type,
    )
end

####
#### PhaseEquil
####

"""
    PhaseEquilProfiles(param_set, ::Type{ArrayType})

Returns a `ProfileSet` used to test moist states in thermodynamic equilibrium.
"""
function PhaseEquilProfiles(
    param_set::AbstractParameterSet,
    ::Type{ArrayType},
) where {ArrayType}
    phase_type = PhaseEquil

    # Prescribe z_range, relative_sat, T_surface, T_min
    z_range, relative_sat, T_surface, T_min = input_config(ArrayType)

    # Compute T, p, from DecayingTemperatureProfile, (reshape RS)
    z, T_virt, p, RS =
        shared_profiles(param_set, z_range, relative_sat, T_surface, T_min)
    T = T_virt

    FT = eltype(T)
    _R_d = FT(R_d(param_set))
    _grav::FT = grav(param_set)
    # Compute total specific humidity from temperature, pressure
    # and relative saturation, and partition the saturation excess
    # according to temperature.
    ρ = p ./ (_R_d .* T)
    q_tot = RS .* q_vap_saturation.(Ref(param_set), T, ρ, Ref(phase_type))
    q_pt = PhasePartition_equil.(Ref(param_set), T, ρ, q_tot, Ref(phase_type))

    # Extract phase partitioning and update pressure
    # to be thermodynamically consistent with T, ρ, q_pt
    q_liq = getproperty.(q_pt, :liq)
    q_ice = getproperty.(q_pt, :ice)
    p = air_pressure.(Ref(param_set), T, ρ, q_pt)

    e_int = internal_energy.(Ref(param_set), T, q_pt)
    θ_liq_ice = liquid_ice_pottemp.(Ref(param_set), T, ρ, q_pt)
    RH = relative_humidity.(Ref(param_set), T, p, Ref(phase_type), q_pt)
    e_pot = _grav * z
    Random.seed!(15)
    u = rand(FT, size(T)) * 50
    v = rand(FT, size(T)) * 50
    w = rand(FT, size(T)) * 50
    e_kin = (u .^ 2 .+ v .^ 2 .+ w .^ 2) / 2

    return ProfileSet{typeof(T), typeof(q_pt), typeof(phase_type)}(
        z,
        T,
        p,
        RS,
        e_int,
        ρ,
        θ_liq_ice,
        q_tot,
        q_liq,
        q_ice,
        q_pt,
        RH,
        e_pot,
        u,
        v,
        w,
        e_kin,
        phase_type,
    )
end


text:
using EpiJ
using Documenter

DocMeta.setdocmeta!(EpiJ, :DocTestSetup, :(using EpiJ); recursive=true)

makedocs(;
    modules=[EpiJ],
    authors="Jacob Zelko <jacobszelko@gmail.com>, Georgia Tech Research Institute",
    repo="https://github.com/JuliaHealth/EpiJ/blob/{commit}{path}#{line}",
    sitename="EpiJ",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://juliahealth.org/EpiJ",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
    ],
)

deploydocs(;
    repo="github.com/JuliaHealth/EpiJ.git",
    devbranch = "main",
    push_preview = false,
    target = "build"
)

max_stars_repo_name: JuliaHealth/EpiJ

max_issues_repo_name: JuliaHealth/EpiJ

max_forks_repo_name: JuliaHealth/EpiJ


text:
@testset "test utilities" begin
    mutable struct NoThrowTestSet <: Test.AbstractTestSet
        results::Vector
        NoThrowTestSet(desc) = new([])
    end
    Test.record(ts::NoThrowTestSet, t::Test.Result) = (push!(ts.results, t); t)
    Test.finish(ts::NoThrowTestSet) = ts.results
    fails = @testset NoThrowTestSet begin
        # OK
        @test_throws_cuerror CUDA.ERROR_UNKNOWN throw(CuError(CUDA.ERROR_UNKNOWN))
        # Fail, wrong CuError
        @test_throws_cuerror CUDA.ERROR_UNKNOWN throw(CuError(CUDA.ERROR_INVALID_VALUE))
        # Fail, wrong Exception
        @test_throws_cuerror CUDA.ERROR_UNKNOWN error()
    end
    @test isa(fails[1], Test.Pass)
    @test isa(fails[2], Test.Fail)
    @test isa(fails[3], Test.Fail)
end

@testset "@sync" begin
  t = Base.@elapsed ret = CUDA.@sync begin
    # TODO: do something that takes a while on the GPU
    #       (need to wrap clock64 for that)
    42
  end
  @test t >= 0
  @test ret == 42

  CUDA.@sync blocking=false begin end
end

@testset "versioninfo" begin
    CUDA.versioninfo(devnull)
end