いつまでも，古いママやってんじゃねえよって話(7)

たくさんあるので，ひとまずまとめて投稿。

いつまでも，古いママやってんじゃねえよって話(7)

https://qiita.com/yatra9/items/a4b58020ebf478b87a1e

ここに書くのも，それでも，Julia 1.7.2 での話。そのうち古くなる。


# 20. サイズが(6,7,8)の配列を考える。100番目の要素のインデックス(x,y,z)は?

```Julia
println(ind2sub((6, 7, 8), 100))
```

ind2sub(） は Julia-1.0 あたりで既に廃止。
代わりに CartesianIndex(） を使う。

```Julia
CartesianIndices(zeros(6, 7, 8))[100] # CartesianIndex(4, 3, 3)
```

# 21. tile関数を利用して市松模様の8x8行列を作成 (★☆☆)

```Julia
# numpy's tile equal to repmat
Z = repmat([0 1; 1 0], 4, 4)
# --> UndefVarError: repmat not defined 　廃止された
```

https://github.com/JuliaLang/julia/tree/d386e40c17d43b79fc89d3e579fc04547241787c/base/abstractarraymath.jl#L283-L309
に，ソースがある。

```Julia
function repmat(a::AbstractVecOrMat, m::Int, n::Int=1)
    o, p = size(a,1), size(a,2)
    b = similar(a, o*m, p*n)
    for j=1:n
        d = (j-1)*p+1
        R = d:d+p-1
        for i=1:m
            c = (i-1)*o+1
            b[c:c+o-1, R] = a
        end
    end
    return b
end
```

これを使って以下を得る。

```Julia
repmat([0 1; 1 0], 4, 4)

8×8 Matrix{Int64}:
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
```

そんなことはしない。今は，repeat() を使う。

```Julia
repeat([0 1; 1 0], outer=(4, 4))

8×8 Matrix{Int64}:
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
 0  1  0  1  0  1  0  1
 1  0  1  0  1  0  1  0
```


# 27. Zが整数であるとき下のうち正当（エラーにならない）な文は? (★☆☆)

```
　27. Consider an integer vector Z, which of these expressions are legal? (★☆☆)
all of these expression are legal.
　全て正当(エラーにならない）文です。
```

原文では「整数ベクトル Z」と言っている。正整数と限定しているわけでもない。

`Z` によっては，エラーが出る。

```Julia
Z = [-100, 0, 100]
Z^Z # MethodError: no method matching ^(::Vector{Int64}, ::Vector{Int64})
Z .^ Z # DomainError with -100

2 << Z >> 2 # MethodError: no method matching <<(::Int64, ::Vector{Int64})
2 .<< Z .>> 2 ならば，エラーにはならない
```


# 30. 2つの配列の共通要素を取得する (★☆☆)

```Julia
Z1 = [1,1,1,2,2,2,3,3,3,4,4,4]
Z2 = [1,1,1,2,2,2,3,3,3]
unique(Z1 ∩ Z2) # [1, 2, 3]
collect(Set(Z1) ∩ Set(Z2)) # [2, 3, 1] Set は順不同になる
```

unique() も collect() も不要。Z1 ∩ Z2 でよい。

```Julia
Z1 ∩ Z2 # [1, 2, 3]
```


# 37. 各行が0から4までの連続値である5x5行列を作成する (★★☆)

```Julia
Z = zeros(5, 5)
Z .= (0:4)'
@show Z

5×5 Matrix{Float64}:
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
```

これは良いが，以下はだめ。

```Julia
# another solution
Z = repmat((0:4)', 4)
```

repmat() は廃止された。
repeat() を使う。

```Julia
repeat(0.:4, inner=(1,5))'

5×5 adjoint(::Matrix{Float64}) with eltype Float64:
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
 0.0  1.0  2.0  3.0  4.0
```

# 39. 0から1の範囲を等分するサイズ10のベクトルを作成する。ただし、両端(0と1）を除く (★★☆)

```Julia
Z = linspace(0, 1, 12)[2:end-1]
@show Z
```

linspace() は廃止。
range() を使う。

```Julia
collect(range(0, 1, length=12)[2:end-1])

10-element Vector{Float64}:
 0.09090909090909091
 0.18181818181818182
 0.2727272727272727
 0.36363636363636365
 0.45454545454545453
 0.5454545454545454
 0.6363636363636364
 0.7272727272727273
 0.8181818181818182
 0.9090909090909091
```


# 44. 直交座標の点を表す10x2の乱数行列を、極座標に変換する (★★☆)

```Julia
Z = rand(10,2)
@views X, Y = Z[:, 1], Z[:,2]  # use view to avoid copy
R = hypot.(X, Y)
T = atan2.(Y, X)
@show R
@show T
```

atan2(x, y) は廃止。
atan(x, y) で計算できる。

```Julia
T = atan.(Y, X)

10-element Vector{Float64}:
 1.4811428722635127
 0.994244750881299
 0.8931153175906136
 0.8432674001861374
 0.9587241207299946
 0.3336986049113172
 0.4401103267747072
 0.09465048365510123
 0.9772132106166795
 0.33945881232211095
```

# 45. サイズ10の乱数ベクトルを生成し、最大値を0に置換する(★★☆)

```Julia
Z = rand(100)
Z[indmax(Z)] = 0
```

indmax() は廃止。
argmax() を使う。

```Julia
Z[argmax(Z)] = 0
```


# 46. [0,1]x[0,1]の範囲で、x and y 座標を表す構造化された配列のグリッドを作成する(★★☆)

```Julia
struct Point
  x::Float64
  y::Float64
end
Z = [Point(x, y) for x in linspace(0,1,10), y in linspace(0,1,10)]
@show Z
```

linspace() は廃止。
range() を使うか `start:by:end` を使う。

```Julia
Z = [Point(x, y) for x in range(0,1,length=10), y in range(0,1,length=10)]

10×10 Matrix{Point}:
 Point(0.0, 0.0)       Point(0.0, 0.111111)       …  Point(0.0, 1.0)
 Point(0.111111, 0.0)  Point(0.111111, 0.111111)     Point(0.111111, 1.0)
 Point(0.222222, 0.0)  Point(0.222222, 0.111111)     Point(0.222222, 1.0)
 Point(0.333333, 0.0)  Point(0.333333, 0.111111)     Point(0.333333, 1.0)
 Point(0.444444, 0.0)  Point(0.444444, 0.111111)     Point(0.444444, 1.0)
 Point(0.555556, 0.0)  Point(0.555556, 0.111111)  …  Point(0.555556, 1.0)
 Point(0.666667, 0.0)  Point(0.666667, 0.111111)     Point(0.666667, 1.0)
 Point(0.777778, 0.0)  Point(0.777778, 0.111111)     Point(0.777778, 1.0)
 Point(0.888889, 0.0)  Point(0.888889, 0.111111)     Point(0.888889, 1.0)
 Point(1.0, 0.0)       Point(1.0, 0.111111)          Point(1.0, 1.0)

Z = [Point(x, y) for x in 0:0.1:1, y in 0:0.1:1]

11×11 Matrix{Point}:
 Point(0.0, 0.0)  Point(0.0, 0.1)  …  Point(0.0, 0.9)  Point(0.0, 1.0)
 Point(0.1, 0.0)  Point(0.1, 0.1)     Point(0.1, 0.9)  Point(0.1, 1.0)
 Point(0.2, 0.0)  Point(0.2, 0.1)     Point(0.2, 0.9)  Point(0.2, 1.0)
 Point(0.3, 0.0)  Point(0.3, 0.1)     Point(0.3, 0.9)  Point(0.3, 1.0)
 Point(0.4, 0.0)  Point(0.4, 0.1)     Point(0.4, 0.9)  Point(0.4, 1.0)
 Point(0.5, 0.0)  Point(0.5, 0.1)  …  Point(0.5, 0.9)  Point(0.5, 1.0)
 Point(0.6, 0.0)  Point(0.6, 0.1)     Point(0.6, 0.9)  Point(0.6, 1.0)
 Point(0.7, 0.0)  Point(0.7, 0.1)     Point(0.7, 0.9)  Point(0.7, 1.0)
 Point(0.8, 0.0)  Point(0.8, 0.1)     Point(0.8, 0.9)  Point(0.8, 1.0)
 Point(0.9, 0.0)  Point(0.9, 0.1)     Point(0.9, 0.9)  Point(0.9, 1.0)
 Point(1.0, 0.0)  Point(1.0, 0.1)  …  Point(1.0, 0.9)  Point(1.0, 1.0)
```


# 47. 2つの配列X, Yからコーシー行列 Cを作成する (ただし、Cij =1/(xi - yj))

```Julia
X = collect(0:7)
Y = X + 0.5
C = @. 1 / (X - Y')
@show det(C)
```
collect() は不要。
`+` はだめ，`.+` にしないとだめ。

```Julia
X = 0:7 # collect() 不要
Y = X .+ 0.5 # .+ でないとエラー
C = @. 1 / (X - Y')

8×8 Matrix{Float64}:
 -2.0       -0.666667  -0.4       …  -0.181818  -0.153846  -0.133333
  2.0       -2.0       -0.666667     -0.222222  -0.181818  -0.153846
  0.666667   2.0       -2.0          -0.285714  -0.222222  -0.181818
  0.4        0.666667   2.0          -0.4       -0.285714  -0.222222
  0.285714   0.4        0.666667     -0.666667  -0.4       -0.285714
  0.222222   0.285714   0.4       …  -2.0       -0.666667  -0.4
  0.181818   0.222222   0.285714      2.0       -2.0       -0.666667
  0.153846   0.181818   0.222222      0.666667   2.0       -2.0
```


# 49. 配列のすべての値を表示する (★★☆)

```Julia
Z = zeros(16, 16)
showall(Z)
```

showall() は廃止。
IOContext() を使用。

```Julia
io = IOContext(stdout, :limit => false)
Base.print_matrix(io, Z)
# または，単純に print(io, Z)
io = IOContext(stdout, :limit => true) # 必要なら，もとに戻す

0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
```


# 50. How to find the closest value (to a given scalar) in a vector? (★★☆)

     50. ベクトルから与えられた値に最も近い値を取り出す (★★☆)

```Julia
using Distributions
Z = 1:100
V = rand(Uniform(1, 100))
println(Z[indmin(abs.(Z .- V))])
```

設問は，「ベクトルから，スカラーの値に最も近い値を取り出す」であるが?

ともかく，indmin() は廃止。
argmin() を使う。

```Julia
using Distributions
Z = 1:100
V = rand(Uniform(1, 100))
println(Z[argmin(abs.(Z .- V))])
```