@@ -675,25 +675,25 @@ function accumulate_pairwise(op, v::AbstractVector{T}) where T
675
675
return accumulate_pairwise! (op, out, v)
676
676
end
677
677
678
- function cumsum! (out, v:: AbstractVector , axis :: Integer = 1 )
678
+ function cumsum! (out, v:: AbstractVector , dim :: Integer )
679
679
# we dispatch on the possibility of numerical stability issues
680
- _cumsum! (out, v, axis , TypeArithmetic (eltype (out)))
680
+ _cumsum! (out, v, dim , TypeArithmetic (eltype (out)))
681
681
end
682
682
683
- function _cumsum! (out, v, axis , :: ArithmeticRounds )
684
- axis == 1 ? accumulate_pairwise! (+ , out, v) : copy! (out, v)
683
+ function _cumsum! (out, v, dim , :: ArithmeticRounds )
684
+ dim == 1 ? accumulate_pairwise! (+ , out, v) : copy! (out, v)
685
685
end
686
- function _cumsum! (out, v, axis , :: ArithmeticUnknown )
687
- _cumsum! (out, v, axis , ArithmeticRounds ())
686
+ function _cumsum! (out, v, dim , :: ArithmeticUnknown )
687
+ _cumsum! (out, v, dim , ArithmeticRounds ())
688
688
end
689
- function _cumsum! (out, v, axis , :: TypeArithmetic )
690
- axis == 1 ? accumulate! (+ , out, v) : copy! (out, v)
689
+ function _cumsum! (out, v, dim , :: TypeArithmetic )
690
+ dim == 1 ? accumulate! (+ , out, v) : copy! (out, v)
691
691
end
692
692
693
693
"""
694
- cumsum(A, dim=1 )
694
+ cumsum(A, dim::Integer )
695
695
696
- Cumulative sum along a dimension `dim`. See also [`cumsum!`](@ref)
696
+ Cumulative sum along the dimension `dim`. See also [`cumsum!`](@ref)
697
697
to use a preallocated output array, both for performance and to control the precision of the
698
698
output (e.g. to avoid overflow).
699
699
@@ -714,22 +714,52 @@ julia> cumsum(a,2)
714
714
4 9 15
715
715
```
716
716
"""
717
- function cumsum (A:: AbstractArray{T} , axis :: Integer = 1 ) where T
717
+ function cumsum (A:: AbstractArray{T} , dim :: Integer ) where T
718
718
out = similar (A, rcum_promote_type (+ , T))
719
- cumsum! (out, A, axis )
719
+ cumsum! (out, A, dim )
720
720
end
721
721
722
722
"""
723
- cumsum!(B, A, dim::Integer=1 )
723
+ cumsum(x::AbstractVector )
724
724
725
- Cumulative sum of `A` along a dimension, storing the result in `B`. See also [`cumsum`](@ref).
725
+ Cumulative sum a vector. See also [`cumsum!`](@ref)
726
+ to use a preallocated output array, both for performance and to control the precision of the
727
+ output (e.g. to avoid overflow).
728
+
729
+ ```jldoctest
730
+ julia> cumsum([1, 1, 1])
731
+ 3-element Array{Int64,1}:
732
+ 1
733
+ 2
734
+ 3
735
+
736
+ julia> cumsum([fill(1, 2) for i in 1:3])
737
+ 3-element Array{Array{Int64,1},1}:
738
+ [1, 1]
739
+ [2, 2]
740
+ [3, 3]
741
+ ```
742
+ """
743
+ cumsum (x:: AbstractVector ) = cumsum (x, 1 )
744
+
745
+ """
746
+ cumsum!(B, A, dim::Integer)
747
+
748
+ Cumulative sum of `A` along the dimension `dim`, storing the result in `B`. See also [`cumsum`](@ref).
749
+ """
750
+ cumsum! (B, A, dim:: Integer ) = accumulate! (+ , B, A, dim)
751
+
752
+ """
753
+ cumsum!(y::AbstractVector, x::AbstractVector)
754
+
755
+ Cumulative sum of a vector `x`, storing the result in `y`. See also [`cumsum`](@ref).
726
756
"""
727
- cumsum! (B, A, axis :: Integer = 1 ) = accumulate! ( + , B, A, axis )
757
+ cumsum! (y :: AbstractVector , x :: AbstractVector ) = cumsum! (y, x, 1 )
728
758
729
759
"""
730
- cumprod(A, dim=1 )
760
+ cumprod(A, dim::Integer )
731
761
732
- Cumulative product along a dimension `dim`. See also
762
+ Cumulative product along the dimension `dim`. See also
733
763
[`cumprod!`](@ref) to use a preallocated output array, both for performance and
734
764
to control the precision of the output (e.g. to avoid overflow).
735
765
@@ -750,20 +780,79 @@ julia> cumprod(a,2)
750
780
4 20 120
751
781
```
752
782
"""
753
- cumprod (A:: AbstractArray , axis:: Integer = 1 ) = accumulate (* , A, axis)
783
+ cumprod (A:: AbstractArray , dim:: Integer ) = accumulate (* , A, dim)
784
+
785
+ """
786
+ cumprod(x::AbstractVector)
787
+
788
+ Cumulative product of a vector. See also
789
+ [`cumprod!`](@ref) to use a preallocated output array, both for performance and
790
+ to control the precision of the output (e.g. to avoid overflow).
791
+
792
+ ```jldoctest
793
+ julia> cumprod(fill(1//2, 3))
794
+ 3-element Array{Rational{Int64},1}:
795
+ 1//2
796
+ 1//4
797
+ 1//8
798
+
799
+ julia> cumprod([fill(1//3, 2, 2) for i in 1:3])
800
+ 3-element Array{Array{Rational{Int64},2},1}:
801
+ Rational{Int64}[1//3 1//3; 1//3 1//3]
802
+ Rational{Int64}[2//9 2//9; 2//9 2//9]
803
+ Rational{Int64}[4//27 4//27; 4//27 4//27]
804
+ ```
805
+ """
806
+ cumprod (x:: AbstractVector ) = cumprod (x, 1 )
754
807
755
808
"""
756
- cumprod!(B, A, dim::Integer=1 )
809
+ cumprod!(B, A, dim::Integer)
757
810
758
- Cumulative product of `A` along a dimension, storing the result in `B`.
811
+ Cumulative product of `A` along the dimension `dim` , storing the result in `B`.
759
812
See also [`cumprod`](@ref).
760
813
"""
761
- cumprod! (B, A, axis :: Integer = 1 ) = accumulate! (* , B, A, axis )
814
+ cumprod! (B, A, dim :: Integer ) = accumulate! (* , B, A, dim )
762
815
763
816
"""
764
- accumulate(op, A, dim=1 )
817
+ cumprod!(y::AbstractVector, x::AbstractVector )
765
818
766
- Cumulative operation `op` along a dimension `dim`. See also
819
+ Cumulative product of a vector `x`, storing the result in `y`.
820
+ See also [`cumprod`](@ref).
821
+ """
822
+ cumprod! (y:: AbstractVector , x:: AbstractVector ) = cumprod! (y, x, 1 )
823
+
824
+ """
825
+ accumulate(op, A, dim::Integer)
826
+
827
+ Cumulative operation `op` along the dimension `dim`. See also
828
+ [`accumulate!`](@ref) to use a preallocated output array, both for performance and
829
+ to control the precision of the output (e.g. to avoid overflow). For common operations
830
+ there are specialized variants of `accumulate`, see:
831
+ [`cumsum`](@ref), [`cumprod`](@ref)
832
+
833
+ ```jldoctest
834
+ julia> accumulate(+, fill(1, 3, 3), 1)
835
+ 3×3 Array{Int64,2}:
836
+ 1 1 1
837
+ 2 2 2
838
+ 3 3 3
839
+
840
+ julia> accumulate(+, fill(1, 3, 3), 2)
841
+ 3×3 Array{Int64,2}:
842
+ 1 2 3
843
+ 1 2 3
844
+ 1 2 3
845
+ ```
846
+ """
847
+ function accumulate (op, A, dim:: Integer )
848
+ out = similar (A, rcum_promote_type (op, eltype (A)))
849
+ accumulate! (op, out, A, dim)
850
+ end
851
+
852
+ """
853
+ accumulate(op, x::AbstractVector)
854
+
855
+ Cumulative operation `op` on a vector. See also
767
856
[`accumulate!`](@ref) to use a preallocated output array, both for performance and
768
857
to control the precision of the output (e.g. to avoid overflow). For common operations
769
858
there are specialized variants of `accumulate`, see:
@@ -783,14 +872,67 @@ julia> accumulate(*, [1,2,3])
783
872
6
784
873
```
785
874
"""
786
- function accumulate (op, A, axis:: Integer = 1 )
787
- out = similar (A, rcum_promote_type (op, eltype (A)))
788
- accumulate! (op, out, A, axis)
875
+ accumulate (op, x:: AbstractVector ) = accumulate (op, x, 1 )
876
+
877
+ """
878
+ accumulate!(op, B, A, dim::Integer)
879
+
880
+ Cumulative operation `op` on `A` along the dimension `dim`, storing the result in `B`.
881
+ See also [`accumulate`](@ref).
882
+ """
883
+ function accumulate! (op, B, A, dim:: Integer )
884
+ dim > 0 || throw (ArgumentError (" dim must be a positive integer" ))
885
+ inds_t = indices (A)
886
+ indices (B) == inds_t || throw (DimensionMismatch (" shape of B must match A" ))
887
+ dim > ndims (A) && return copy! (B, A)
888
+ isempty (inds_t[dim]) && return B
889
+ if dim == 1
890
+ # We can accumulate to a temporary variable, which allows
891
+ # register usage and will be slightly faster
892
+ ind1 = inds_t[1 ]
893
+ @inbounds for I in CartesianRange (tail (inds_t))
894
+ tmp = convert (eltype (B), A[first (ind1), I])
895
+ B[first (ind1), I] = tmp
896
+ for i_1 = first (ind1)+ 1 : last (ind1)
897
+ tmp = op (tmp, A[i_1, I])
898
+ B[i_1, I] = tmp
899
+ end
900
+ end
901
+ else
902
+ R1 = CartesianRange (indices (A)[1 : dim- 1 ]) # not type-stable
903
+ R2 = CartesianRange (indices (A)[dim+ 1 : end ])
904
+ _accumulate! (op, B, A, R1, inds_t[dim], R2) # use function barrier
905
+ end
906
+ return B
789
907
end
790
908
909
+ """
910
+ accumulate!(op, y, x::AbstractVector)
791
911
912
+ Cumulative operation `op` on a vector `x`, storing the result in `y`.
913
+ See also [`accumulate`](@ref).
792
914
"""
793
- accumulate(op, v0, A)
915
+ function accumulate! (op:: Op , y, x:: AbstractVector ) where Op
916
+ isempty (x) && return y
917
+ v1 = first (x)
918
+ _accumulate1! (op, y, v1, x, 1 )
919
+ end
920
+
921
+ @noinline function _accumulate! (op, B, A, R1, ind, R2)
922
+ # Copy the initial element in each 1d vector along dimension `dim`
923
+ ii = first (ind)
924
+ @inbounds for J in R2, I in R1
925
+ B[I, ii, J] = A[I, ii, J]
926
+ end
927
+ # Accumulate
928
+ @inbounds for J in R2, i in first (ind)+ 1 : last (ind), I in R1
929
+ B[I, i, J] = op (B[I, i- 1 , J], A[I, i, J])
930
+ end
931
+ B
932
+ end
933
+
934
+ """
935
+ accumulate(op, v0, x::AbstractVector)
794
936
795
937
Like `accumulate`, but using a starting element `v0`. The first entry of the result will be
796
938
`op(v0, first(A))`.
@@ -810,30 +952,23 @@ julia> accumulate(min, 0, [1,2,-1])
810
952
-1
811
953
```
812
954
"""
813
- function accumulate (op, v0, A, axis:: Integer = 1 )
814
- T = rcum_promote_type (op, typeof (v0), eltype (A))
815
- out = similar (A, T)
816
- accumulate! (op, out, v0, A, 1 )
817
- end
818
-
819
- function accumulate! (op:: Op , B, A:: AbstractVector , axis:: Integer = 1 ) where Op
820
- isempty (A) && return B
821
- v1 = first (A)
822
- _accumulate1! (op, B, v1, A, axis)
955
+ function accumulate (op, v0, x:: AbstractVector )
956
+ T = rcum_promote_type (op, typeof (v0), eltype (x))
957
+ out = similar (x, T)
958
+ accumulate! (op, out, v0, x)
823
959
end
824
960
825
- function accumulate! (op, B , v0, A :: AbstractVector , axis :: Integer = 1 )
826
- isempty (A ) && return B
827
- v1 = op (v0, first (A ))
828
- _accumulate1! (op, B , v1, A, axis )
961
+ function accumulate! (op, y , v0, x :: AbstractVector )
962
+ isempty (x ) && return y
963
+ v1 = op (v0, first (x ))
964
+ _accumulate1! (op, y , v1, x, 1 )
829
965
end
830
966
831
-
832
- function _accumulate1! (op, B, v1, A:: AbstractVector , axis:: Integer = 1 )
833
- axis > 0 || throw (ArgumentError (" axis must be a positive integer" ))
967
+ function _accumulate1! (op, B, v1, A:: AbstractVector , dim:: Integer )
968
+ dim > 0 || throw (ArgumentError (" dim must be a positive integer" ))
834
969
inds = linearindices (A)
835
970
inds == linearindices (B) || throw (DimensionMismatch (" linearindices of A and B don't match" ))
836
- axis > 1 && return copy! (B, A)
971
+ dim > 1 && return copy! (B, A)
837
972
i1 = inds[1 ]
838
973
cur_val = v1
839
974
B[i1] = cur_val
@@ -844,51 +979,6 @@ function _accumulate1!(op, B, v1, A::AbstractVector, axis::Integer=1)
844
979
return B
845
980
end
846
981
847
- """
848
- accumulate!(op, B, A, dim=1)
849
-
850
- Cumulative operation `op` on `A` along a dimension, storing the result in `B`.
851
- See also [`accumulate`](@ref).
852
- """
853
- function accumulate! (op, B, A, axis:: Integer = 1 )
854
- axis > 0 || throw (ArgumentError (" axis must be a positive integer" ))
855
- inds_t = indices (A)
856
- indices (B) == inds_t || throw (DimensionMismatch (" shape of B must match A" ))
857
- axis > ndims (A) && return copy! (B, A)
858
- isempty (inds_t[axis]) && return B
859
- if axis == 1
860
- # We can accumulate to a temporary variable, which allows
861
- # register usage and will be slightly faster
862
- ind1 = inds_t[1 ]
863
- @inbounds for I in CartesianRange (tail (inds_t))
864
- tmp = convert (eltype (B), A[first (ind1), I])
865
- B[first (ind1), I] = tmp
866
- for i_1 = first (ind1)+ 1 : last (ind1)
867
- tmp = op (tmp, A[i_1, I])
868
- B[i_1, I] = tmp
869
- end
870
- end
871
- else
872
- R1 = CartesianRange (indices (A)[1 : axis- 1 ]) # not type-stable
873
- R2 = CartesianRange (indices (A)[axis+ 1 : end ])
874
- _accumulate! (op, B, A, R1, inds_t[axis], R2) # use function barrier
875
- end
876
- return B
877
- end
878
-
879
- @noinline function _accumulate! (op, B, A, R1, ind, R2)
880
- # Copy the initial element in each 1d vector along dimension `axis`
881
- ii = first (ind)
882
- @inbounds for J in R2, I in R1
883
- B[I, ii, J] = A[I, ii, J]
884
- end
885
- # Accumulate
886
- @inbounds for J in R2, i in first (ind)+ 1 : last (ind), I in R1
887
- B[I, i, J] = op (B[I, i- 1 , J], A[I, i, J])
888
- end
889
- B
890
- end
891
-
892
982
# ## from abstractarray.jl
893
983
894
984
"""
0 commit comments