@@ -43,12 +43,13 @@ Let `M`, `D`, `F` be matrix-based, diagonal-matrix-based, and function-based
4343
4444``` julia
4545N = 4
46- f (u, p, t) = u .* u
47- f (v, u, p, t) = v .= u .* u
46+ f (v, u, p, t) = v .* u
47+ f (w, v, u, p, t) = w .= v .* u
4848
4949M = MatrixOperator (rand (N, N))
5050D = DiagonalOperator (rand (N))
51- F = FunctionOperator (f, zeros (N), zeros (N))
51+ # Fix: Specify that we're providing a parameter placeholder
52+ F = FunctionOperator (f, zeros (N), zeros (N); p= 1.0 , isconstant= true )
5253```
5354
5455Then, the following codes just work.
@@ -64,14 +65,33 @@ L5 = [M; D]' * [M F; F D] * [F; D]
6465Each ` L# ` can be applied to ` AbstractVector ` s of appropriate sizes:
6566
6667``` julia
67- p = nothing # parameter struct
68+ p = nothing # parameter struct - must be nothing or compatible with the FunctionOperator
6869t = 0.0 # time
6970
70- u = rand (N)
71- v = L1 (u, p, t) # == L1 * u
71+ u = rand (N) # update vector
72+ v = rand (N) # action vector
73+ w = zeros (N) # output vector
7274
73- u_kron = rand (N^ 3 )
74- v_kron = L3 (u_kron, p, t) # == L3 * u_kron
75+ # Out-of-place evaluation
76+ result1 = L1 (v, u, p, t) # L1 acting on v after updating with u
77+
78+ # In-place evaluation (after caching)
79+ L1_cached = cache_operator (L1, v)
80+ L1_cached (w, v, u, p, t) # Result stored in w
81+
82+ # For tensor product operators
83+ v_kron = rand (N^ 3 )
84+ u_kron = rand (N^ 3 ) # Update vector for tensor product
85+ w_kron = zeros (N^ 3 ) # Output vector for tensor product
86+
87+ # Cache the tensor product operator with the correct sized vector
88+ L3_cached = cache_operator (L3, v_kron)
89+
90+ # Out-of-place evaluation (action vector v_kron, update vector u_kron)
91+ result_kron = L3_cached (v_kron, u_kron, p, t)
92+
93+ # In-place evaluation (output to w_kron)
94+ L3_cached (w_kron, v_kron, u_kron, p, t)
7595```
7696
7797For mutating operator evaluations, call ` cache_operator ` to generate
@@ -80,13 +100,19 @@ in-place cache so the operation is nonallocating.
80100``` julia
81101α, β = rand (2 )
82102
83- # allocate cache
84- L2 = cache_operator (L2, u)
85- L4 = cache_operator (L4, u)
103+ # Allocate and cache operators first
104+ L2 = cache_operator (L2, v)
105+ L4 = cache_operator (L4, v)
106+
107+ # Allocation-free evaluation with separate update and action vectors
108+ w = zeros (N)
109+ L2 (w, v, u, p, t) # w = L2 * v
110+ L4 (w, v, u, p, t) # w = L4 * v
86111
87- # allocation-free evaluation
88- L2 (v, u, p, t) # == mul!(v, L2, u)
89- L4 (v, u, p, t, α, β) # == mul!(v, L4, u, α, β)
112+ # In-place evaluation with scaling: w = α*(L*v) + β*w
113+ result_w = rand (N) # Start with random vector
114+ L2 (result_w, v, u, p, t, α, β) # result_w = α*(L2*v) + β*result_w
115+ L4 (result_w, v, u, p, t, α, β) # result_w = α*(L4*v) + β*result_w
90116```
91117
92118## Roadmap
0 commit comments