• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37940

22 Oct 2024 05:36AM UTC coverage: 85.868% (-1.8%) from 87.654%
#37940

push

local

web-flow
Remove NewPM pass exports. (#56269)

All ecosystem consumers have switched to the string-based API.

77546 of 90308 relevant lines covered (85.87%)

16057626.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.11
/base/abstractarraymath.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
 ## Basic functions ##
4

5
isreal(x::AbstractArray) = all(isreal,x)
3,562✔
6
iszero(x::AbstractArray) = all(iszero,x)
4,232✔
7
isreal(x::AbstractArray{<:Real}) = true
×
8

9
## Constructors ##
10

11
"""
12
    vec(a::AbstractArray) -> AbstractVector
13

14
Reshape the array `a` as a one-dimensional column vector. Return `a` if it is
15
already an `AbstractVector`. The resulting array
16
shares the same underlying data as `a`, so it will only be mutable if `a` is
17
mutable, in which case modifying one will also modify the other.
18

19
# Examples
20
```jldoctest
21
julia> a = [1 2 3; 4 5 6]
22
2×3 Matrix{Int64}:
23
 1  2  3
24
 4  5  6
25

26
julia> vec(a)
27
6-element Vector{Int64}:
28
 1
29
 4
30
 2
31
 5
32
 3
33
 6
34

35
julia> vec(1:3)
36
1:3
37
```
38

39
See also [`reshape`](@ref), [`dropdims`](@ref).
40
"""
41
vec(a::AbstractArray) = reshape(a,length(a))
3,168✔
42
vec(a::AbstractVector) = a
1,601✔
43

44
_sub(::Tuple{}, ::Tuple{}) = ()
×
45
_sub(t::Tuple, ::Tuple{}) = t
26✔
46
_sub(t::Tuple, s::Tuple) = _sub(tail(t), tail(s))
36✔
47

48
"""
49
    dropdims(A; dims)
50

51
Return an array with the same data as `A`, but with the dimensions specified by
52
`dims` removed. `size(A,d)` must equal 1 for every `d` in `dims`,
53
and repeated dimensions or numbers outside `1:ndims(A)` are forbidden.
54

55
The result shares the same underlying data as `A`, such that the
56
result is mutable if and only if `A` is mutable, and setting elements of one
57
alters the values of the other.
58

59
See also: [`reshape`](@ref), [`vec`](@ref).
60

61
# Examples
62
```jldoctest
63
julia> a = reshape(Vector(1:4),(2,2,1,1))
64
2×2×1×1 Array{Int64, 4}:
65
[:, :, 1, 1] =
66
 1  3
67
 2  4
68

69
julia> b = dropdims(a; dims=3)
70
2×2×1 Array{Int64, 3}:
71
[:, :, 1] =
72
 1  3
73
 2  4
74

75
julia> b[1,1,1] = 5; a
76
2×2×1×1 Array{Int64, 4}:
77
[:, :, 1, 1] =
78
 5  3
79
 2  4
80
```
81
"""
82
dropdims(A; dims) = _dropdims(A, dims)
68✔
83
function _dropdims(A::AbstractArray, dims::Dims)
20✔
84
    for i in eachindex(dims)
34✔
85
        1 <= dims[i] <= ndims(A) || throw(ArgumentError("dropped dims must be in range 1:ndims(A)"))
50✔
86
        length(axes(A, dims[i])) == 1 || throw(ArgumentError("dropped dims must all be size 1"))
49✔
87
        for j = 1:i-1
43✔
88
            dims[j] == dims[i] && throw(ArgumentError("dropped dims must be unique"))
16✔
89
        end
15✔
90
    end
54✔
91
    ax = _foldoneto((ds, d) -> d in dims ? ds : (ds..., axes(A,d)), (), Val(ndims(A)))
150✔
92
    reshape(A, ax::typeof(_sub(axes(A), dims)))
26✔
93
end
94
_dropdims(A::AbstractArray, dim::Integer) = _dropdims(A, (Int(dim),))
16✔
95

96

97
"""
98
    insertdims(A; dims)
99

100
Inverse of [`dropdims`](@ref); return an array with new singleton dimensions
101
at every dimension in `dims`.
102

103
Repeated dimensions are forbidden and the largest entry in `dims` must be
104
less than or equal than `ndims(A) + length(dims)`.
105

106
The result shares the same underlying data as `A`, such that the
107
result is mutable if and only if `A` is mutable, and setting elements of one
108
alters the values of the other.
109

110
See also: [`dropdims`](@ref), [`reshape`](@ref), [`vec`](@ref).
111
# Examples
112
```jldoctest
113
julia> x = [1 2 3; 4 5 6]
114
2×3 Matrix{Int64}:
115
 1  2  3
116
 4  5  6
117

118
julia> insertdims(x, dims=3)
119
2×3×1 Array{Int64, 3}:
120
[:, :, 1] =
121
 1  2  3
122
 4  5  6
123

124
julia> insertdims(x, dims=(1,2,5)) == reshape(x, 1, 1, 2, 3, 1)
125
true
126

127
julia> dropdims(insertdims(x, dims=(1,2,5)), dims=(1,2,5))
128
2×3 Matrix{Int64}:
129
 1  2  3
130
 4  5  6
131
```
132

133
!!! compat "Julia 1.12"
134
    Requires Julia 1.12 or later.
135
"""
136
insertdims(A; dims) = _insertdims(A, dims)
×
137
function _insertdims(A::AbstractArray{T, N}, dims::NTuple{M, Int}) where {T, N, M}
×
138
    for i in eachindex(dims)
×
139
        1 ≤ dims[i] || throw(ArgumentError("the smallest entry in dims must be ≥ 1."))
×
140
        dims[i] ≤ N+M || throw(ArgumentError("the largest entry in dims must be not larger than the dimension of the array and the length of dims added"))
×
141
        for j = 1:i-1
×
142
            dims[j] == dims[i] && throw(ArgumentError("inserted dims must be unique"))
×
143
        end
×
144
    end
×
145

146
    # acc is a tuple, where the first entry is the final shape
147
    # the second entry off acc is a counter for the axes of A
148
    inds= Base._foldoneto((acc, i) ->
×
149
                            i ∈ dims
150
                                ? ((acc[1]..., Base.OneTo(1)), acc[2])
151
                                : ((acc[1]..., axes(A, acc[2])), acc[2] + 1),
152
                            ((), 1), Val(N+M))
153
    new_shape = inds[1]
×
154
    return reshape(A, new_shape)
×
155
end
156
_insertdims(A::AbstractArray, dim::Integer) = _insertdims(A, (Int(dim),))
×
157

158

159

160
## Unary operators ##
161

162
"""
163
    conj!(A)
164

165
Transform an array to its complex conjugate in-place.
166

167
See also [`conj`](@ref).
168

169
# Examples
170
```jldoctest
171
julia> A = [1+im 2-im; 2+2im 3+im]
172
2×2 Matrix{Complex{Int64}}:
173
 1+1im  2-1im
174
 2+2im  3+1im
175

176
julia> conj!(A);
177

178
julia> A
179
2×2 Matrix{Complex{Int64}}:
180
 1-1im  2+1im
181
 2-2im  3-1im
182
```
183
"""
184
conj!(A::AbstractArray{<:Number}) = (@inbounds broadcast!(conj, A, A); A)
120,373✔
185
conj!(x::AbstractArray{<:Real}) = x
2✔
186
conj!(A::AbstractArray) = (foreach(conj!, A); A)
×
187

188
"""
189
    conj(A::AbstractArray)
190

191
Return an array containing the complex conjugate of each entry in array `A`.
192

193
Equivalent to `conj.(A)`, except that when `eltype(A) <: Real`
194
`A` is returned without copying, and that when `A` has zero dimensions,
195
a 0-dimensional array is returned (rather than a scalar).
196

197
# Examples
198
```jldoctest
199
julia> conj([1, 2im, 3 + 4im])
200
3-element Vector{Complex{Int64}}:
201
 1 + 0im
202
 0 - 2im
203
 3 - 4im
204

205
julia> conj(fill(2 - im))
206
0-dimensional Array{Complex{Int64}, 0}:
207
2 + 1im
208
```
209
"""
210
conj(A::AbstractArray) = broadcast_preserving_zero_d(conj, A)
188✔
211
conj(A::AbstractArray{<:Real}) = A
168✔
212

213
"""
214
    real(A::AbstractArray)
215

216
Return an array containing the real part of each entry in array `A`.
217

218
Equivalent to `real.(A)`, except that when `eltype(A) <: Real`
219
`A` is returned without copying, and that when `A` has zero dimensions,
220
a 0-dimensional array is returned (rather than a scalar).
221

222
# Examples
223
```jldoctest
224
julia> real([1, 2im, 3 + 4im])
225
3-element Vector{Int64}:
226
 1
227
 0
228
 3
229

230
julia> real(fill(2 - im))
231
0-dimensional Array{Int64, 0}:
232
2
233
```
234
"""
235
real(A::AbstractArray) = broadcast_preserving_zero_d(real, A)
1,388✔
236
real(A::AbstractArray{<:Real}) = A
700✔
237

238
"""
239
    imag(A::AbstractArray)
240

241
Return an array containing the imaginary part of each entry in array `A`.
242

243
Equivalent to `imag.(A)`, except that when `A` has zero dimensions,
244
a 0-dimensional array is returned (rather than a scalar).
245

246
# Examples
247
```jldoctest
248
julia> imag([1, 2im, 3 + 4im])
249
3-element Vector{Int64}:
250
 0
251
 2
252
 4
253

254
julia> imag(fill(2 - im))
255
0-dimensional Array{Int64, 0}:
256
-1
257
```
258
"""
259
imag(A::AbstractArray) = broadcast_preserving_zero_d(imag, A)
865✔
260
imag(A::AbstractArray{<:Real}) = zero(A)
304✔
261

262
"""
263
    reim(A::AbstractArray)
264

265
Return a tuple of two arrays containing respectively the real and the imaginary
266
part of each entry in `A`.
267

268
Equivalent to `(real.(A), imag.(A))`, except that when `eltype(A) <: Real`
269
`A` is returned without copying to represent the real part, and that when `A` has
270
zero dimensions, a 0-dimensional array is returned (rather than a scalar).
271

272
# Examples
273
```jldoctest
274
julia> reim([1, 2im, 3 + 4im])
275
([1, 0, 3], [0, 2, 4])
276

277
julia> reim(fill(2 - im))
278
(fill(2), fill(-1))
279
```
280
"""
281
reim(A::AbstractArray)
282

283
-(A::AbstractArray) = broadcast_preserving_zero_d(-, A)
2,494✔
284

285
+(x::AbstractArray{<:Number}) = x
3✔
286
*(x::AbstractArray{<:Number,2}) = x
1✔
287

288
# index A[:,:,...,i,:,:,...] where "i" is in dimension "d"
289

290
"""
291
    selectdim(A, d::Integer, i)
292

293
Return a view of all the data of `A` where the index for dimension `d` equals `i`.
294

295
Equivalent to `view(A,:,:,...,i,:,:,...)` where `i` is in position `d`.
296

297
See also: [`eachslice`](@ref).
298

299
# Examples
300
```jldoctest
301
julia> A = [1 2 3 4; 5 6 7 8]
302
2×4 Matrix{Int64}:
303
 1  2  3  4
304
 5  6  7  8
305

306
julia> selectdim(A, 2, 3)
307
2-element view(::Matrix{Int64}, :, 3) with eltype Int64:
308
 3
309
 7
310

311
julia> selectdim(A, 2, 3:4)
312
2×2 view(::Matrix{Int64}, :, 3:4) with eltype Int64:
313
 3  4
314
 7  8
315
```
316
"""
317
@inline selectdim(A::AbstractArray, d::Integer, i) = _selectdim(A, d, i, _setindex(i, d, map(Slice, axes(A))...))
26✔
318
@noinline function _selectdim(A, d, i, idxs)
26✔
319
    d >= 1 || throw(ArgumentError("dimension must be ≥ 1, got $d"))
26✔
320
    nd = ndims(A)
26✔
321
    d > nd && (i == 1 || throw(BoundsError(A, (ntuple(Returns(Colon()),d-1)..., i))))
26✔
322
    return view(A, idxs...)
26✔
323
end
324

325
function circshift(a::AbstractArray, shiftamt::Real)
46✔
326
    circshift!(similar(a), a, (Integer(shiftamt),))
206✔
327
end
328
circshift(a::AbstractArray, shiftamt::DimsInteger) = circshift!(similar(a), a, shiftamt)
51✔
329
"""
330
    circshift(A, shifts)
331

332
Circularly shift, i.e. rotate, the data in `A`. The second argument is a tuple or
333
vector giving the amount to shift in each dimension, or an integer to shift only in the
334
first dimension.
335

336
The generated code is most efficient when the shift amounts are known at compile-time, i.e.,
337
compile-time constants.
338

339
See also: [`circshift!`](@ref), [`circcopy!`](@ref), [`bitrotate`](@ref), [`<<`](@ref).
340

341
# Examples
342
```jldoctest
343
julia> b = reshape(Vector(1:16), (4,4))
344
4×4 Matrix{Int64}:
345
 1  5   9  13
346
 2  6  10  14
347
 3  7  11  15
348
 4  8  12  16
349

350
julia> circshift(b, (0,2))
351
4×4 Matrix{Int64}:
352
  9  13  1  5
353
 10  14  2  6
354
 11  15  3  7
355
 12  16  4  8
356

357
julia> circshift(b, (-1,0))
358
4×4 Matrix{Int64}:
359
 2  6  10  14
360
 3  7  11  15
361
 4  8  12  16
362
 1  5   9  13
363

364
julia> a = BitArray([true, true, false, false, true])
365
5-element BitVector:
366
 1
367
 1
368
 0
369
 0
370
 1
371

372
julia> circshift(a, 1)
373
5-element BitVector:
374
 1
375
 1
376
 1
377
 0
378
 0
379

380
julia> circshift(a, -1)
381
5-element BitVector:
382
 1
383
 0
384
 0
385
 1
386
 1
387

388
julia> x = (1, 2, 3, 4, 5)
389
(1, 2, 3, 4, 5)
390

391
julia> circshift(x, 4)
392
(2, 3, 4, 5, 1)
393

394
julia> z = (1, 'a', -7.0, 3)
395
(1, 'a', -7.0, 3)
396

397
julia> circshift(z, -1)
398
('a', -7.0, 3, 1)
399
```
400
"""
401
function circshift(a::AbstractArray, shiftamt)
×
402
    circshift!(similar(a), a, map(Integer, (shiftamt...,)))
×
403
end
404

405
## Other array functions ##
406

407
"""
408
    repeat(A::AbstractArray, counts::Integer...)
409

410
Construct an array by repeating array `A` a given number of times in each dimension, specified by `counts`.
411

412
See also: [`fill`](@ref), [`Iterators.repeated`](@ref), [`Iterators.cycle`](@ref).
413

414
# Examples
415
```jldoctest
416
julia> repeat([1, 2, 3], 2)
417
6-element Vector{Int64}:
418
 1
419
 2
420
 3
421
 1
422
 2
423
 3
424

425
julia> repeat([1, 2, 3], 2, 3)
426
6×3 Matrix{Int64}:
427
 1  1  1
428
 2  2  2
429
 3  3  3
430
 1  1  1
431
 2  2  2
432
 3  3  3
433
```
434
"""
435
function repeat(A::AbstractArray, counts...)
80✔
436
    return repeat(A, outer=counts)
284✔
437
end
438

439
"""
440
    repeat(A::AbstractArray; inner=ntuple(Returns(1), ndims(A)), outer=ntuple(Returns(1), ndims(A)))
441

442
Construct an array by repeating the entries of `A`. The i-th element of `inner` specifies
443
the number of times that the individual entries of the i-th dimension of `A` should be
444
repeated. The i-th element of `outer` specifies the number of times that a slice along the
445
i-th dimension of `A` should be repeated. If `inner` or `outer` are omitted, no repetition
446
is performed.
447

448
# Examples
449
```jldoctest
450
julia> repeat(1:2, inner=2)
451
4-element Vector{Int64}:
452
 1
453
 1
454
 2
455
 2
456

457
julia> repeat(1:2, outer=2)
458
4-element Vector{Int64}:
459
 1
460
 2
461
 1
462
 2
463

464
julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
465
4×6 Matrix{Int64}:
466
 1  2  1  2  1  2
467
 1  2  1  2  1  2
468
 3  4  3  4  3  4
469
 3  4  3  4  3  4
470
```
471
"""
472
function repeat(A::AbstractArray; inner = nothing, outer = nothing)
293✔
473
    return _RepeatInnerOuter.repeat(A, inner=inner, outer=outer)
293✔
474
end
475

476
module _RepeatInnerOuter
477

478
function repeat(arr; inner=nothing, outer=nothing)
330✔
479
    check(arr, inner, outer)
581✔
480
    arr, inner, outer = resolve(arr, inner, outer)
281✔
481
    repeat_inner_outer(arr, inner, outer)
281✔
482
end
483

484
to_tuple(t::Tuple) = t
279✔
485
to_tuple(x::Integer) = (x,)
×
486
to_tuple(itr) = tuple(itr...)
2✔
487

488
function pad(a, b)
2✔
489
    N = max(length(a), length(b))
281✔
490
    Base.fill_to_length(a, 1, Val(N)), Base.fill_to_length(b, 1, Val(N))
281✔
491
end
492
function pad(a, b, c)
×
493
    N = max(max(length(a), length(b)), length(c))
×
494
    Base.fill_to_length(a, 1, Val(N)), Base.fill_to_length(b, 1, Val(N)), Base.fill_to_length(c, 1, Val(N))
×
495
end
496

497
function resolve(arr::AbstractArray{<:Any, N}, inner::NTuple{N, Any}, outer::NTuple{N,Any}) where {N}
×
498
    arr, inner, outer
×
499
end
500
function resolve(arr, inner, outer)
×
501
    dims, inner, outer = pad(size(arr), to_tuple(inner), to_tuple(outer))
×
502
    reshape(arr, dims), inner, outer
×
503
end
504
function resolve(arr, inner::Nothing, outer::Nothing)
×
505
    return arr, inner, outer
×
506
end
507
function resolve(arr, inner::Nothing, outer)
2✔
508
    dims, outer = pad(size(arr), to_tuple(outer))
281✔
509
    reshape(arr, dims), inner, outer
281✔
510
end
511
function resolve(arr, inner, outer::Nothing)
×
512
    dims, inner = pad(size(arr), to_tuple(inner))
×
513
    reshape(arr, dims), inner, outer
×
514
end
515

516
function check(arr, inner, outer)
517
    if inner !== nothing
281✔
518
        # TODO: Currently one based indexing is demanded for inner !== nothing,
519
        # but not for outer !== nothing. Decide for something consistent.
520
        Base.require_one_based_indexing(arr)
×
521
        if any(<(0), inner)
×
522
            throw(ArgumentError("no inner repetition count may be negative; got $inner"))
×
523
        end
524
        if length(inner) < ndims(arr)
×
525
            throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input array ($(ndims(arr)))"))
×
526
        end
527
    end
528
    if outer !== nothing
281✔
529
        if any(<(0), outer)
581✔
530
            throw(ArgumentError("no outer repetition count may be negative; got $outer"))
×
531
        end
532
        if (length(outer) < ndims(arr)) && (inner !== nothing)
281✔
533
            throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input array ($(ndims(arr)))"))
×
534
        end
535
    end
536
end
537

538
repeat_inner_outer(arr, inner::Nothing, outer::Nothing) = arr
×
539
repeat_inner_outer(arr, ::Nothing, outer) = repeat_outer(arr, outer)
281✔
540
repeat_inner_outer(arr, inner, ::Nothing) = repeat_inner(arr, inner)
×
541
repeat_inner_outer(arr, inner, outer) = repeat_outer(repeat_inner(arr, inner), outer)
×
542

543
function repeat_outer(a::AbstractMatrix, (m,n)::NTuple{2, Any})
38✔
544
    o, p = size(a,1), size(a,2)
38✔
545
    b = similar(a, o*m, p*n)
61✔
546
    for j=1:n
38✔
547
        d = (j-1)*p+1
73✔
548
        R = d:d+p-1
73✔
549
        for i=1:m
73✔
550
            c = (i-1)*o+1
99✔
551
            @inbounds b[c:c+o-1, R] = a
99✔
552
        end
138✔
553
    end
116✔
554
    return b
38✔
555
end
556

557
function repeat_outer(a::AbstractVector, (m,)::Tuple{Any})
243✔
558
    o = length(a)
243✔
559
    b = similar(a, o*m)
421✔
560
    for i=1:m
243✔
561
        c = (i-1)*o+1
1,011,177✔
562
        @inbounds b[c:c+o-1] = a
2,020,029✔
563
    end
2,022,152✔
564
    return b
243✔
565
end
566

567
function repeat_outer(arr::AbstractArray{<:Any,N}, dims::NTuple{N,Any}) where {N}
×
568
    insize  = size(arr)
×
569
    outsize = map(*, insize, dims)
×
570
    out = similar(arr, outsize)
×
571
    for I in CartesianIndices(arr)
×
572
        for J in CartesianIndices(dims)
×
573
            TIJ = map(Tuple(I), Tuple(J), insize) do i, j, d
×
574
                i + d * (j-1)
×
575
            end
576
            IJ = CartesianIndex(TIJ)
×
577
            @inbounds out[IJ] = arr[I]
×
578
        end
×
579
    end
×
580
    return out
×
581
end
582

583
function repeat_inner(arr, inner)
×
584
    outsize = map(*, size(arr), inner)
×
585
    out = similar(arr, outsize)
×
586
    for I in CartesianIndices(arr)
×
587
        for J in CartesianIndices(inner)
×
588
            TIJ = map(Tuple(I), Tuple(J), inner) do i, j, d
×
589
                (i-1) * d + j
×
590
            end
591
            IJ = CartesianIndex(TIJ)
×
592
            @inbounds out[IJ] = arr[I]
×
593
        end
×
594
    end
×
595
    return out
×
596
end
597

598
end#module
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc