@@ -24,17 +24,76 @@ struct Tensorizer{DMS<:Tuple}
24
24
blocks:: DMS
25
25
end
26
26
27
+ const Tensorizer2D{AA, BB} = Tensorizer{Tuple{AA, BB}}
27
28
const TrivialTensorizer{d} = Tensorizer{NTuple{d,Ones{Int,1 ,Tuple{OneToInf{Int}}}}}
28
29
29
30
Base. eltype (a:: Tensorizer ) = NTuple{length (a. blocks),Int}
30
31
Base. eltype (:: Tensorizer{<:NTuple{d}} ) where {d} = NTuple{d,Int}
31
32
dimensions (a:: Tensorizer ) = map (sum,a. blocks)
32
33
Base. length (a:: Tensorizer ) = mapreduce (sum,* ,a. blocks)
33
34
35
+
36
+ function start (a:: TrivialTensorizer{d} ) where {d}
37
+ if d== 2
38
+ return invoke (start, Tuple{Tensorizer2D}, a)
39
+ else
40
+ # ((block_dim_1, block_dim_2,...), (itaration_number, iterator, iterator_state)), (itemssofar, length)
41
+ return (ones (Int, d),(0 , nothing , nothing )), (0 ,length (a))
42
+ end
43
+ end
44
+
45
+ function next (a:: TrivialTensorizer{d} , iterator_tuple) where {d}
46
+
47
+ if d== 2
48
+ return invoke (next, Tuple{Tensorizer2D, Tuple}, a, iterator_tuple)
49
+ end
50
+
51
+ (block, (j, iterator, iter_state)), (i,tot) = iterator_tuple
52
+
53
+
54
+ @inline function check_block_finished ()
55
+ if iterator === nothing
56
+ return true
57
+ end
58
+ # there are N-1 over d-1 combinations in a block
59
+ amount_combinations_block = binomial (sum (block)- 1 , d- 1 )
60
+ # check if all combinations have been iterated over
61
+ amount_combinations_block <= j
62
+ end
63
+
64
+ ret = reverse (block)
65
+
66
+ if check_block_finished () # end of new block
67
+
68
+ # set up iterator for new block
69
+ current_sum = sum (block)
70
+ iterator = multiexponents (d, current_sum+ 1 - d)
71
+ iter_state = nothing
72
+ j = 0
73
+ end
74
+
75
+ # increase block, or initialize new block
76
+ res, iter_state = iterate (iterator, iter_state)
77
+ block .= res.+ 1
78
+ j = j+ 1
79
+
80
+ ret, ((block, (j, iterator, iter_state)), (i,tot))
81
+ end
82
+
83
+
84
+ function done (a:: TrivialTensorizer{d} , iterator_tuple) where {d}
85
+ if d== 2
86
+ return invoke (done, Tuple{Tensorizer2D, Tuple}, a, iterator_tuple)
87
+ end
88
+ (_, (i,tot)) = iterator_tuple
89
+ return i ≥ tot
90
+ end
91
+
92
+
34
93
# (blockrow,blockcol), (subrow,subcol), (rowshift,colshift), (numblockrows,numblockcols), (itemssofar, length)
35
- start (a:: Tensorizer{Tuple{ AA,BB} } ) where {AA,BB} = (1 ,1 ), (1 ,1 ), (0 ,0 ), (a. blocks[1 ][1 ],a. blocks[2 ][1 ]), (0 ,length (a))
94
+ start (a:: Tensorizer2D{ AA, BB } ) where {AA,BB} = (1 ,1 ), (1 ,1 ), (0 ,0 ), (a. blocks[1 ][1 ],a. blocks[2 ][1 ]), (0 ,length (a))
36
95
37
- function next (a:: Tensorizer{Tuple{ AA,BB} } , ((K,J), (k,j), (rsh,csh), (n,m), (i,tot))) where {AA,BB}
96
+ function next (a:: Tensorizer2D{ AA, BB } , ((K,J), (k,j), (rsh,csh), (n,m), (i,tot))) where {AA,BB}
38
97
ret = k+ rsh,j+ csh
39
98
if k== n && j== m # end of block
40
99
if J == 1 || K == length (a. blocks[1 ]) # end of new block
@@ -59,7 +118,7 @@ function next(a::Tensorizer{Tuple{AA,BB}}, ((K,J), (k,j), (rsh,csh), (n,m), (i,t
59
118
end
60
119
61
120
62
- done (a:: Tensorizer , ((K,J), (k,j), (rsh,csh), (n,m), (i,tot))) = i ≥ tot
121
+ done (a:: Tensorizer2D , ((K,J), (k,j), (rsh,csh), (n,m), (i,tot))) = i ≥ tot
63
122
64
123
iterate (a:: Tensorizer ) = next (a, start (a))
65
124
function iterate (a:: Tensorizer , st)
@@ -104,6 +163,14 @@ block(ci::CachedIterator{T,TrivialTensorizer{2}},k::Int) where {T} =
104
163
block (:: TrivialTensorizer{2} ,n:: Int ) =
105
164
Block (floor (Integer,sqrt (2 n) + 1 / 2 ))
106
165
166
+ function block (:: TrivialTensorizer{d} ,n:: Int ) where {d}
167
+ order:: Int = 0
168
+ while binomial (order+ d, d) < n
169
+ order = order + 1
170
+ end
171
+ return Block (order+ 1 )
172
+ end
173
+
107
174
block (sp:: Tensorizer{<:Tuple{<:AbstractFill{S},<:AbstractFill{T}}} ,n:: Int ) where {S,T} =
108
175
Block (floor (Integer,sqrt (2 floor (Integer,(n- 1 )/ (getindex_value (sp. blocks[1 ])* getindex_value (sp. blocks[2 ])))+ 1 ) + 1 / 2 ))
109
176
_cumsum (x) = cumsum (x)
@@ -211,6 +278,10 @@ struct TensorSpace{SV,D,R} <:AbstractProductSpace{SV,D,R}
211
278
spaces:: SV
212
279
end
213
280
281
+ # Tensorspace of 2 univariate spaces
282
+ const TensorSpace2D{AA, BB, D,R} = TensorSpace{<: Tuple{AA, BB} , D, R} where {AA<: UnivariateSpace , BB<: UnivariateSpace }
283
+ const TensorSpaceND{d, D, R} = TensorSpace{<: NTuple{d, <:UnivariateSpace} , D, R}
284
+
214
285
tensorizer (sp:: TensorSpace ) = Tensorizer (map (blocklengths,sp. spaces))
215
286
blocklengths (S:: TensorSpace ) = tensorblocklengths (map (blocklengths,S. spaces)... )
216
287
473
544
474
545
fromtensor (S:: Space ,M:: AbstractMatrix ) = fromtensor (tensorizer (S),M)
475
546
totensor (S:: Space ,M:: AbstractVector ) = totensor (tensorizer (S),M)
547
+ totensor (SS:: TensorSpace{<:NTuple{d}} ,M:: AbstractVector ) where {d} =
548
+ if d> 2 ; totensoriterator (tensorizer (SS),M) else totensor (tensorizer (SS),M) end
476
549
477
550
function fromtensor (it:: Tensorizer ,M:: AbstractMatrix )
478
551
n,m= size (M)
@@ -496,19 +569,27 @@ function totensor(it::Tensorizer,M::AbstractVector)
496
569
B= block (it,n)
497
570
ds = dimensions (it)
498
571
572
+ # ret=zeros(eltype(M),[sum(it.blocks[i][1:min(B.n[1],length(it.blocks[i]))]) for i=1:length(it.blocks)]...)
573
+
499
574
ret= zeros (eltype (M),sum (it. blocks[1 ][1 : min (B. n[1 ],length (it. blocks[1 ]))]),
500
575
sum (it. blocks[2 ][1 : min (B. n[1 ],length (it. blocks[2 ]))]))
576
+
501
577
k= 1
502
- for (K,J) in it
578
+ for index in it
503
579
if k > n
504
580
break
505
581
end
506
- ret[K,J ] = M[k]
582
+ ret[index ... ] = M[k]
507
583
k += 1
508
584
end
509
585
ret
510
586
end
511
587
588
+ @inline function totensoriterator (it:: TrivialTensorizer{d} ,M:: AbstractVector ) where {d}
589
+ B= block (it,length (M))
590
+ return it, M, B
591
+ end
592
+
512
593
for OP in (:block ,:blockstart ,:blockstop )
513
594
@eval begin
514
595
$ OP (s:: TensorSpace , :: PosInfinity ) = ℵ₀
@@ -542,10 +623,12 @@ end
542
623
543
624
itransform (sp:: TensorSpace ,cfs:: AbstractVector ) = vec (itransform! (sp,coefficientmatrix (Fun (sp,cfs))))
544
625
545
- evaluate (f :: AbstractVector ,S :: AbstractProductSpace ,x) = ProductFun ( totensor (S,f),S)(x ... )
546
- evaluate (f:: AbstractVector ,S:: AbstractProductSpace ,x,y ) = ProductFun (totensor (S,f),S)(x,y )
547
-
626
+ # 2D evaluation functions
627
+ evaluate (f:: AbstractVector ,S:: TensorSpace2D ,x ) = ProductFun (totensor (S,f), S)(x... )
628
+ evaluate (f :: AbstractVector ,S :: TensorSpace2D ,x,y) = ProductFun ( totensor (S,f),S)(x,y)
548
629
630
+ # ND evaluation functions of Trivial Spaces
631
+ evaluate (f:: AbstractVector ,S:: TensorSpaceND ,x) = TrivialTensorFun (totensor (S, f)... , S)(x... )
549
632
550
633
coefficientmatrix (f:: Fun{<:AbstractProductSpace} ) = totensor (space (f),f. coefficients)
551
634
0 commit comments