Using Jax Lax Scan with Inputs That Don't Change Across Iterations Within Scan but Are Different Eac

Using Jax Lax Scan with Inputs That Don't Change Across Iterations Within Scan but Are Different Eac
★ Key Takeaways

Jax Lax Scan Operates on a Function That Takes Two Arguments, a Carry and a Sequence of Inputs. I Am Wondering How Scan Should Be Called If Some Inputs Don't Change Across Iterations of the Scan. Naively, I Could Create a Sequence of Identical Inputs, but This Seems Wasteful/Redundant and More Importantly, This Isn't Always Possible, as Scan Can Only Scan over Arrays. for Example, One of the Inputs I Want to Pass to My Function Is a Train State (E. G. from Flax. Training Import Train_State) That Contains My Model and Its Parameters, Which Cannot Be Put into Array. as I Say in the Title, These Inputs May Also Change Each Time I Call Scan (E. G. the Model Parameters Will Change).

Explore the essential facts related to Using Jax Lax Scan with Inputs That Don't Change Across Iterations Within Scan but Are Different Eac with our comprehensive overview.

In general, you have three possible approaches for this:

  • Convert the single value into a sequence of identical inputs to scan over
  • Put the single value in the carry to carry it along to each step of the scan
  • Close over the single value
  • Here are three examples of a computation using these strategies:

    import jax import jax.numpy as jnp a = jnp.arange(5) b = 2 
    # Strategy 1: duplicate b across sequence def f(carry, xs): a, b = xs result = a * b return carry + result, result b_seq = jnp.full_like(a, b) total, cumulative = jax.lax.scan(f, 0, (a, b_seq)) print(total) # 20 print(cumulative) # [0 2 4 6 8] 
    # Strategy 2: put b in the carry def f(carry, xs): carry, b = carry a = xs result = a * b return (carry + result, b), result (total, _), cumulative = jax.lax.scan(f, (0, b), a) print(total) # 20 print(cumulative) # [0 2 4 6 8] 
    # Strategy 3: close over b from functools import partial def f(carry, xs, b): a = xs result = a * b return carry + result, result total, cumulative = jax.lax.scan(partial(f, b=b), 0, a) print(total) # 20 print(cumulative) # [0 2 4 6 8] 

    Which you use probably depends on the context of where you are using it, but I personally think closure (option 3) is probably the cleanest approach.

    2
    David Miller
    Author

    David Miller

    David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.