Skip to content

Commit a879bd1

Browse files
committed
Initial commit
1 parent f4beadc commit a879bd1

File tree

7 files changed

+1522
-0
lines changed

7 files changed

+1522
-0
lines changed

src/sparse_array.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,11 @@ end
368368

369369
Base.:*(scalar::Number, A::SparseArray) = A * scalar
370370

371+
# Base show method (without MIME) - delegates to text/plain
372+
function Base.show(io::IO, A::SparseArray{T, N}) where {T, N}
373+
show(io, MIME"text/plain"(), A)
374+
end
375+
371376
# Improved display with better formatting
372377
function Base.show(io::IO, ::MIME"text/plain", A::SparseArray{T, N}) where {T, N}
373378
compact = get(io, :compact, false)

test/test_advanced_arithmetic.jl

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
module TestAdvancedArithmetic
2+
3+
using MultidimensionalSparseArrays
4+
using Test
5+
6+
@testset "Advanced Arithmetic Operations" begin
7+
@testset "Addition Edge Cases" begin
8+
# Test addition with completely disjoint sparse patterns
9+
A = SparseArray{Int, 2}((3, 3))
10+
A[1, 1] = 5
11+
A[2, 2] = 10
12+
13+
B = SparseArray{Int, 2}((3, 3))
14+
B[1, 3] = 3
15+
B[3, 1] = 7
16+
17+
C = A + B
18+
@test C[1, 1] == 5
19+
@test C[2, 2] == 10
20+
@test C[1, 3] == 3
21+
@test C[3, 1] == 7
22+
@test nnz(C) == 4
23+
@test !hasindex(C, 2, 1)
24+
@test !hasindex(C, 3, 3)
25+
26+
# Test addition with overlapping indices
27+
D = SparseArray{Int, 2}((3, 3))
28+
D[1, 1] = 2
29+
D[2, 3] = 8
30+
31+
E = A + D
32+
@test E[1, 1] == 7 # 5 + 2
33+
@test E[2, 2] == 10 # 10 + 0 (D doesn't have [2,2])
34+
@test E[2, 3] == 8 # 0 + 8 (A doesn't have [2,3])
35+
@test nnz(E) == 3
36+
end
37+
38+
@testset "Subtraction with Zero Results" begin
39+
A = SparseArray{Int, 2}((3, 3))
40+
A[1, 1] = 5
41+
A[2, 2] = 10
42+
A[1, 3] = 7
43+
44+
B = SparseArray{Int, 2}((3, 3))
45+
B[1, 1] = 5 # Same as A[1,1] - should result in zero
46+
B[2, 2] = 3 # Different from A[2,2]
47+
B[3, 1] = 4 # Not in A
48+
49+
C = A - B
50+
@test !hasindex(C, 1, 1) # 5 - 5 = 0, not stored
51+
@test C[2, 2] == 7 # 10 - 3 = 7
52+
@test C[1, 3] == 7 # 7 - 0 = 7
53+
@test C[3, 1] == -4 # 0 - 4 = -4
54+
@test nnz(C) == 3
55+
end
56+
57+
@testset "Type Promotion in Arithmetic" begin
58+
# Int + Float64
59+
A = SparseArray{Int, 2}((2, 2))
60+
A[1, 1] = 5
61+
62+
B = SparseArray{Float64, 2}((2, 2))
63+
B[1, 1] = 2.5
64+
B[2, 2] = 3.7
65+
66+
C = A + B
67+
@test eltype(C) == Float64
68+
@test C[1, 1] == 7.5
69+
@test C[2, 2] == 3.7
70+
71+
# Int + Complex
72+
D = SparseArray{Complex{Float64}, 2}((2, 2))
73+
D[1, 1] = 1.0 + 2.0im
74+
75+
E = A + D
76+
@test eltype(E) == Complex{Float64}
77+
@test E[1, 1] == 6.0 + 2.0im
78+
79+
# Rational arithmetic
80+
F = SparseArray{Rational{Int}, 2}((2, 2))
81+
F[1, 1] = 1//3
82+
83+
G = SparseArray{Rational{Int}, 2}((2, 2))
84+
G[1, 1] = 1//6
85+
G[2, 1] = 2//3
86+
87+
H = F + G
88+
@test H[1, 1] == 1//2 # 1/3 + 1/6 = 1/2
89+
@test H[2, 1] == 2//3
90+
end
91+
92+
@testset "Scalar Multiplication Edge Cases" begin
93+
A = SparseArray{Float64, 2}((3, 3))
94+
A[1, 1] = 2.0
95+
A[2, 3] = -1.5
96+
A[3, 2] = 0.0 # Explicitly stored zero
97+
98+
# Multiplication by zero
99+
B = A * 0
100+
@test nnz(B) == 0 # All values become zero, nothing stored
101+
102+
# Multiplication by negative number
103+
C = A * (-2)
104+
@test C[1, 1] == -4.0
105+
@test C[2, 3] == 3.0
106+
@test C[3, 2] == 0.0
107+
@test nnz(C) == 3 # Zero is still stored
108+
109+
# Multiplication by complex number
110+
D = A * (1 + 1im)
111+
@test eltype(D) == Complex{Float64}
112+
@test D[1, 1] == 2.0 + 2.0im
113+
@test D[2, 3] == -1.5 - 1.5im
114+
115+
# Left multiplication
116+
E = (2 + 3im) * A
117+
@test E[1, 1] == 4.0 + 6.0im
118+
@test E[2, 3] == -3.0 - 4.5im
119+
end
120+
121+
@testset "Large Sparse Array Arithmetic" begin
122+
# Test arithmetic on larger arrays to ensure efficiency
123+
A = SparseArray{Float64, 2}((100, 100))
124+
B = SparseArray{Float64, 2}((100, 100))
125+
126+
# Add sparse diagonal pattern
127+
for i in 1:10:100
128+
A[i, i] = Float64(i)
129+
B[i, i] = Float64(i) * 0.5
130+
end
131+
132+
# Add some off-diagonal elements
133+
A[25, 75] = 12.5
134+
B[75, 25] = 8.3
135+
136+
C = A + B
137+
@test nnz(C) == 12 # 10 diagonal + 2 off-diagonal
138+
@test C[11, 11] == 16.5 # 11 + 5.5
139+
@test C[25, 75] == 12.5
140+
@test C[75, 25] == 8.3
141+
142+
# Scalar multiplication should preserve sparsity
143+
D = A * 2.0
144+
@test nnz(D) == nnz(A)
145+
end
146+
147+
@testset "Arithmetic with Different Dimensions" begin
148+
A = SparseArray{Int, 3}((2, 2, 2))
149+
A[1, 1, 1] = 5
150+
A[2, 2, 2] = 10
151+
152+
B = SparseArray{Int, 3}((2, 2, 2))
153+
B[1, 1, 1] = 3
154+
B[1, 2, 1] = 7
155+
156+
C = A + B
157+
@test C[1, 1, 1] == 8
158+
@test C[2, 2, 2] == 10
159+
@test C[1, 2, 1] == 7
160+
@test nnz(C) == 3
161+
end
162+
163+
@testset "Arithmetic Result Optimization" begin
164+
# Test that arithmetic operations don't store unnecessary zeros
165+
A = SparseArray{Float64, 2}((3, 3))
166+
A[1, 1] = 5.0
167+
A[2, 2] = 3.0
168+
169+
B = SparseArray{Float64, 2}((3, 3))
170+
B[1, 1] = 5.0 # Will cancel out in subtraction
171+
B[3, 3] = 2.0
172+
173+
C = A - B
174+
@test !hasindex(C, 1, 1) # Should not store 5.0 - 5.0 = 0.0
175+
@test C[2, 2] == 3.0
176+
@test C[3, 3] == -2.0
177+
@test nnz(C) == 2
178+
end
179+
180+
@testset "Precision and Floating Point Arithmetic" begin
181+
A = SparseArray{Float64, 2}((2, 2))
182+
A[1, 1] = 0.1 + 0.2 # This is 0.30000000000000004 in floating point
183+
184+
B = SparseArray{Float64, 2}((2, 2))
185+
B[1, 1] = 0.3
186+
187+
C = A - B
188+
# The result should be close to zero but not exactly zero due to floating point precision
189+
@test hasindex(C, 1, 1)
190+
@test abs(C[1, 1]) < 1e-15
191+
@test C[1, 1] != 0.0
192+
end
193+
194+
@testset "Chain Operations" begin
195+
A = SparseArray{Int, 2}((3, 3))
196+
A[1, 1] = 1
197+
A[2, 2] = 2
198+
199+
B = SparseArray{Int, 2}((3, 3))
200+
B[1, 1] = 1
201+
B[1, 3] = 3
202+
203+
C = SparseArray{Int, 2}((3, 3))
204+
C[2, 2] = 1
205+
C[3, 1] = 4
206+
207+
# Test (A + B) - C
208+
D = (A + B) - C
209+
@test D[1, 1] == 2 # (1 + 1) - 0 = 2
210+
@test D[2, 2] == 1 # (2 + 0) - 1 = 1
211+
@test D[1, 3] == 3 # (0 + 3) - 0 = 3
212+
@test D[3, 1] == -4 # (0 + 0) - 4 = -4
213+
@test nnz(D) == 4
214+
end
215+
end
216+
217+
end

0 commit comments

Comments
 (0)