@@ -2,7 +2,9 @@ abstract type Basis{T} <: LazyQuasiMatrix{T} end
2
2
abstract type Weight{T} <: LazyQuasiVector{T} end
3
3
4
4
5
- struct WeightLayout <: AbstractQuasiLazyLayout end
5
+ abstract type AbstractWeightLayout <: AbstractQuasiLazyLayout end
6
+ struct WeightLayout <: AbstractWeightLayout end
7
+ struct MappedWeightLayout <: AbstractWeightLayout end
6
8
abstract type AbstractBasisLayout <: AbstractQuasiLazyLayout end
7
9
abstract type AbstractWeightedBasisLayout <: AbstractBasisLayout end
8
10
struct BasisLayout <: AbstractBasisLayout end
@@ -12,22 +14,22 @@ struct WeightedBasisLayout{Basis} <: AbstractWeightedBasisLayout end
12
14
const SubWeightedBasisLayout = WeightedBasisLayout{SubBasisLayout}
13
15
const MappedWeightedBasisLayout = WeightedBasisLayout{MappedBasisLayout}
14
16
17
+ struct AdjointBasisLayout{Basis} <: AbstractQuasiLazyLayout end
18
+ const AdjointSubBasisLayout = AdjointBasisLayout{SubBasisLayout}
19
+
15
20
SubBasisLayouts = Union{SubBasisLayout,SubWeightedBasisLayout}
16
21
WeightedBasisLayouts = Union{WeightedBasisLayout,SubWeightedBasisLayout,MappedWeightedBasisLayout}
17
22
MappedBasisLayouts = Union{MappedBasisLayout,MappedWeightedBasisLayout}
18
-
19
- struct AdjointBasisLayout{Basis} <: AbstractQuasiLazyLayout end
20
- const AdjointSubBasisLayout = AdjointBasisLayout{SubBasisLayout}
21
- const AdjointMappedBasisLayout = AdjointBasisLayout{MappedBasisLayout}
23
+ AdjointMappedBasisLayouts = AdjointBasisLayout{<: MappedBasisLayouts }
22
24
23
25
MemoryLayout (:: Type{<:Basis} ) = BasisLayout ()
24
26
MemoryLayout (:: Type{<:Weight} ) = WeightLayout ()
25
27
26
28
adjointlayout (:: Type , :: Basis ) where Basis<: AbstractBasisLayout = AdjointBasisLayout {Basis} ()
27
- broadcastlayout (:: Type{typeof(*)} , :: WeightLayout , :: Basis ) where Basis<: AbstractBasisLayout = WeightedBasisLayout {Basis} ()
29
+ broadcastlayout (:: Type{typeof(*)} , :: AbstractWeightLayout , :: Basis ) where Basis<: AbstractBasisLayout = WeightedBasisLayout {Basis} ()
28
30
29
- # A sub of a weight is still a weight
30
- sublayout (:: WeightLayout , _ ) = WeightLayout ()
31
+ sublayout ( :: AbstractWeightLayout , _) = WeightLayout ()
32
+ sublayout (:: AbstractWeightLayout , :: Type{<:Tuple{Map}} ) = MappedWeightLayout ()
31
33
sublayout (:: AbstractBasisLayout , :: Type{<:Tuple{Map,AbstractVector}} ) = MappedBasisLayout ()
32
34
33
35
# copy with an Inclusion can not be materialized
@@ -39,6 +41,7 @@ unweighted(P::BroadcastQuasiMatrix{<:Any,typeof(*),<:Tuple{AbstractQuasiVector,A
39
41
unweighted (V:: SubQuasiArray ) = view (unweighted (parent (V)), parentindices (V)... )
40
42
weight (P:: BroadcastQuasiMatrix{<:Any,typeof(*),<:Tuple{AbstractQuasiVector,AbstractQuasiMatrix}} ) = first (P. args)
41
43
weight (V:: SubQuasiArray ) = weight (parent (V))[parentindices (V)[1 ]]
44
+ weight (V:: SubQuasiArray{<:Any,2,<:Any, <:Tuple{Inclusion,Any}} ) = weight (parent (V))
42
45
43
46
unweighted (a:: AbstractQuasiArray ) = unweighted (MemoryLayout (a), a)
44
47
# Default is lazy
@@ -109,7 +112,7 @@ copy(L::Ldiv{<:MappedBasisLayouts,ApplyLayout{typeof(*)},<:Any,<:AbstractQuasiVe
109
112
end
110
113
111
114
# default to transform for expanding weights
112
- copy (L:: Ldiv{<:AbstractBasisLayout,WeightLayout } ) = transform_ldiv (L. A, L. B)
115
+ copy (L:: Ldiv{<:AbstractBasisLayout,<:AbstractWeightLayout } ) = transform_ldiv (L. A, L. B)
113
116
114
117
# multiplication operators, reexpand in basis A
115
118
@inline function _broadcast_mul_ldiv (:: Tuple{Any,AbstractBasisLayout} , A, B)
@@ -341,6 +344,8 @@ gives a basis for expanding given quasi-vector.
341
344
basis (v) = basis_layout (MemoryLayout (v), v)
342
345
343
346
basis_layout (:: ExpansionLayout , v:: ApplyQuasiArray{<:Any,N,typeof(*)} ) where N = v. args[1 ]
347
+ basis_layout (lay:: ApplyLayout{typeof(*)} , v) = basis (first (arguments (lay, v)))
348
+ basis_layout (lay:: AbstractBasisLayout , v) = v
344
349
basis_layout (lay, v) = basis_axes (axes (v,1 ), v) # allow choosing a basis based on axes
345
350
basis_axes (ax, v) = error (" Overload for $ax " )
346
351
499
504
# \int_a^b f(y) g(y) dy = \int_{-1}^1 f(p(x))*g(p(x)) * p'(x) dx
500
505
501
506
502
- _sub_getindex (A, kr, jr) = A[kr, jr]
503
- _sub_getindex (A, :: Slice , :: Slice ) = A
504
-
505
- @simplify function * (Ac:: QuasiAdjoint{<:Any,<:SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:AbstractAffineQuasiVector,<:Any}}} ,
506
- B:: SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:AbstractAffineQuasiVector,<:Any}} )
507
- A = Ac'
508
- PA,PB = parent (A),parent (B)
509
- kr,jr = parentindices (B)
510
- _sub_getindex ((PA' PB)/ kr. A,parentindices (A)[2 ],jr)
511
- end
512
-
513
-
514
- # Differentiation of sub-arrays
515
-
516
- # avoid stack overflow from unmaterialize Derivative() * parent()
517
- _der_sub (DP, inds... ) = DP[inds... ]
518
- _der_sub (DP:: ApplyQuasiMatrix{T,typeof(*),<:Tuple{Derivative,Any}} , kr, jr) where T = ApplyQuasiMatrix {T} (* , DP. args[1 ], view (DP. args[2 ], kr, jr))
519
-
520
- # need to customise simplifiable so can't use @simplify
521
- simplifiable (:: typeof (* ), A:: Derivative , B:: SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:Inclusion,<:Any}} )= simplifiable (* , Derivative (axes (parent (B),1 )), parent (B))
522
- simplifiable (:: typeof (* ), Ac:: QuasiAdjoint{<:Any,<:SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:Inclusion,<:Any}}} , Bc:: QuasiAdjoint{<:Any,<:Derivative} ) = simplifiable (* , Bc' , Ac' )
523
- function mul (A:: Derivative , B:: SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:Inclusion,<:Any}} )
524
- axes (A,2 ) == axes (B,1 ) || throw (DimensionMismatch ())
525
- P = parent (B)
526
- _der_sub (Derivative (axes (P,1 ))* P, parentindices (B)... )
527
- end
528
- mul (Ac:: QuasiAdjoint{<:Any,<:SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:Inclusion,<:Any}}} , Bc:: QuasiAdjoint{<:Any,<:Derivative} ) = mul (Bc' , Ac' )'
529
-
530
- simplifiable (:: typeof (* ), A:: Derivative , B:: SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:AbstractAffineQuasiVector,<:Any}} ) = simplifiable (* , Derivative (axes (parent (B),1 )), parent (B))
531
- simplifiable (:: typeof (* ), Ac:: QuasiAdjoint{<:Any,<:SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:AbstractAffineQuasiVector,<:Any}}} , Bc:: QuasiAdjoint{<:Any,<:Derivative} ) = simplifiable (* , Bc' , Ac' )
532
- function mul (A:: Derivative , B:: SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:AbstractAffineQuasiVector,<:Any}} )
533
- axes (A,2 ) == axes (B,1 ) || throw (DimensionMismatch ())
534
- P = parent (B)
535
- kr,jr = parentindices (B)
536
- (Derivative (axes (P,1 ))* P* kr. A)[kr,jr]
537
- end
538
- mul (Ac:: QuasiAdjoint{<:Any,<:SubQuasiArray{<:Any,2,<:AbstractQuasiMatrix,<:Tuple{<:AbstractAffineQuasiVector,<:Any}}} , Bc:: QuasiAdjoint{<:Any,<:Derivative} ) = mul (Bc' , Ac' )'
539
507
540
508
# we represent as a Mul with a banded matrix
541
509
sublayout (:: AbstractBasisLayout , :: Type{<:Tuple{<:Inclusion,<:AbstractVector}} ) = SubBasisLayout ()
600
568
# sum
601
569
# ###
602
570
function sum_layout (:: SubBasisLayout , Vm, dims)
603
- @assert dims == 1
571
+ dims == 1 || error ( " not implemented " )
604
572
sum (parent (Vm); dims= dims)[:,parentindices (Vm)[2 ]]
605
573
end
606
574
616
584
sum_layout (:: ExpansionLayout , A, dims) = sum_layout (ApplyLayout {typeof(*)} (), A, dims)
617
585
cumsum_layout (:: ExpansionLayout , A, dims) = cumsum_layout (ApplyLayout {typeof(*)} (), A, dims)
618
586
587
+ # ##
588
+ # diff
589
+ # ##
590
+
591
+ function diff_layout (:: SubBasisLayout , Vm, dims:: Integer )
592
+ dims == 1 || error (" not implemented" )
593
+ diff (parent (Vm); dims= dims)[:,parentindices (Vm)[2 ]]
594
+ end
595
+
596
+ function diff_layout (:: WeightedBasisLayout{<:SubBasisLayout} , Vm, dims:: Integer )
597
+ dims == 1 || error (" not implemented" )
598
+ w = weight (Vm)
599
+ V = unweighted (Vm)
600
+ view (diff (w .* parent (V)), parentindices (V)... )
601
+ end
602
+
603
+ function diff_layout (:: MappedBasisLayouts , V, dims)
604
+ kr = basismap (V)
605
+ @assert kr isa AbstractAffineQuasiVector
606
+ D = diff (demap (V); dims= dims)
607
+ view (basis (D), kr, :) * (kr. A* coefficients (D))
608
+ end
609
+
610
+ diff_layout (:: ExpansionLayout , A, dims... ) = diff_layout (ApplyLayout {typeof(*)} (), A, dims... )
611
+
612
+
613
+ # ###
614
+ # Gram matrix
615
+ # ###
616
+
617
+ simplifiable (:: Mul{<:AdjointBasisLayout, <:AbstractBasisLayout} ) = Val (true )
618
+ function copy (M:: Mul{<:AdjointBasisLayout, <:AbstractBasisLayout} )
619
+ A = (M. A)'
620
+ A == M. B && return grammatrix (A)
621
+ error (" Not implemented" )
622
+ end
623
+
624
+ grammatrix (A) = grammatrix_layout (MemoryLayout (A), A)
625
+ grammatrix_layout (_, A) = error (" Not implemented" )
626
+
627
+ function grammatrix_layout (:: MappedBasisLayouts , P)
628
+ Q = demap (P)
629
+ kr = basismap (P)
630
+ @assert kr isa AbstractAffineQuasiVector
631
+ grammatrix (Q)/ kr. A
632
+ end
633
+
634
+ function copy (M:: Mul{<:AdjointMappedBasisLayouts, <:MappedBasisLayouts} )
635
+ A = M. A'
636
+ kr = basismap (A)
637
+ @assert kr isa AbstractAffineQuasiVector
638
+ @assert kr == basismap (M. B)
639
+ demap (A)' demap (M. B) / kr. A
640
+ end
641
+
642
+
643
+
619
644
include (" basisconcat.jl" )
620
645
include (" basiskron.jl" )
621
646
include (" splines.jl" )
0 commit comments