```julia
] activate .
```

[Vandermonde matrix:](https://en.wikipedia.org/wiki/Vandermonde_matrix)
\begin{align}V=\begin{bmatrix}1&\alpha _{1}&\alpha _{1}^{2}&\dots &\alpha _{1}^{n-1}\\1&\alpha _{2}&\alpha _{2}^{2}&\dots &\alpha _{2}^{n-1}\\1&\alpha _{3}&\alpha _{3}^{2}&\dots &\alpha _{3}^{n-1}\\\vdots &\vdots &\vdots &\ddots &\vdots \\1&\alpha _{m}&\alpha _{m}^{2}&\dots &\alpha _{m}^{n-1}\end{bmatrix}\end{align}


```julia
using PyCall
```


```julia
np = pyimport("numpy")
```




    PyObject <module 'numpy' from 'C:\\Users\\carsten\\Anaconda3\\lib\\site-packages\\numpy\\__init__.py'>




```julia
np.vander(1:5, increasing=true)
```




    5×5 Array{Int32,2}:
     1  1   1    1    1
     1  2   4    8   16
     1  3   9   27   81
     1  4  16   64  256
     1  5  25  125  625



The source code for this function is [here](https://github.com/numpy/numpy/blob/v1.16.1/numpy/lib/twodim_base.py#L475-L563). It calls `np.multiply.accumulate` which is implemented in C [here](https://github.com/numpy/numpy/blob/deea4983aedfa96905bbaee64e3d1de84144303f/numpy/core/src/umath/ufunc_object.c#L3678). However, this code doesn't actually perform the computation, it basically only checks types and stuff. The actual kernel that gets called is [here](https://github.com/numpy/numpy/blob/deea4983aedfa96905bbaee64e3d1de84144303f/numpy/core/src/umath/loops.c.src#L1742). This isn't even C code but a template for C code which is used to generate type specific kernels.

Overall, this setup only supports a limited set of types, like `Float64`, `Float32`, and so forth.

Here is a simple Julia implementation (taken from [Steve's Julia intro](https://web.mit.edu/18.06/www/Fall17/1806/julia/Julia-intro.pdf))


```julia
function vander(x::AbstractVector{T},  n=length(x)) where T
    m = length(x)
    V = Matrix{T}(undef, m, n)
    for j = 1:m
        V[j,1] = one(x[j])
    end
    for i= 2:n
        for j = 1:m
            V[j,i] = x[j] * V[j,i-1]
            end
        end
    return V
end
```




    vander (generic function with 2 methods)




```julia
vander(1:5)
```




    5×5 Array{Int64,2}:
     1  1   1    1    1
     1  2   4    8   16
     1  3   9   27   81
     1  4  16   64  256
     1  5  25  125  625



# A quick benchmark


```julia
using BenchmarkTools, Plots
```


```julia
ns = exp10.(range(1, 4, length=30));
```


```julia
tnp = Float64[]
tjl = Float64[]
for n in ns
    x = 1:n |> collect
    push!(tnp, @belapsed np.vander($x) samples=3 evals=1)
    push!(tjl, @belapsed vander($x) samples=3 evals=1)
end    
```


```julia
plot(ns, tnp./tjl, m=:circle, xscale=:log10, xlab="matrix size", ylab="NumPy time / Julia time", legend=:false)
```




    

    




```julia
savefig("vandermonde.pdf")
savefig("vandermonde.svg")
savefig("vandermonde.png")
```

Note that the clean and concise Julia implementation is beating the numpy implementation for small and is on-par for large matrix sizes!

At the same time, the Julia code is generic and works for arbitrary types!


```julia
vander(Int32[4, 8, 16, 32])
```




    4×4 Array{Int32,2}:
     1   4    16     64
     1   8    64    512
     1  16   256   4096
     1  32  1024  32768




```julia
vander(["this", "is", "a", "test"])
```




    4×4 Array{String,2}:
     ""  "this"  "thisthis"  "thisthisthis"
     ""  "is"    "isis"      "isisis"      
     ""  "a"     "aa"        "aaa"         
     ""  "test"  "testtest"  "testtesttest"




```julia
vander([true, false, false, true])
```




    4×4 Array{Bool,2}:
     true   true   true   true
     true  false  false  false
     true  false  false  false
     true   true   true   true




```julia

```

f914ce46e8f7b810739c0e8b28f512dca498c2a1
ipynb
Jupyter Notebook
playground/vandermonde/vandermonde.ipynb
crstnbr/JuliaWorkshop19
17a19bd100fcaf1c20b577af7af943061b8a157c
MIT
2019-07-26T20:02:31.000Z
2021-08-06T08:12:15.000Z
playground/vandermonde/vandermonde.ipynb
mattborghi/JuliaWorkshop19
ae4fc28e52e8fc0fd9abdf6359a72b0bb5fe61f3
MIT
2019-07-25T14:24:54.000Z
2019-10-25T17:37:37.000Z
playground/vandermonde/vandermonde.ipynb
mattborghi/JuliaWorkshop19
ae4fc28e52e8fc0fd9abdf6359a72b0bb5fe61f3
MIT
2019-08-09T18:26:12.000Z
2021-08-08T00:05:50.000Z
Qwen/Qwen-72B
1. YES
2. YES