Skip to contents

Updates elements of an array at specified positions, returning a new array. You can also use the [<- operator.

Usage

# S3 method for class 'AnvlArray'
x[...] <- value

nv_subset_assign(x, ..., value, update_fn = "replace", inplace = FALSE)

Arguments

x

(arrayish)
The array to update. Can be any data type. An R object is materialized at its default data type.

...

Subset specifications, one per axis. Omitted trailing axes select all elements.

A boolean mask (an R logical array such as arr(TRUE, FALSE), or an arrayish value of dtype bool) selects the elements at the TRUE positions. A mask for one axis must have as many elements as the size of that axis. A mask that is the only subscript and has the same shape as x selects across the whole array, yielding a 1-D result. Under jit(), the values of a mask must be known at compile time, because the number of selected elements determines the output shape: R logical arrays and arrays created in or closed over by the function work, a mask computed from the function's inputs does not.

See the Subsetting article for details.

value

(arrayish)
Replacement values, or with another update_fn the values to combine the subset with. Scalars are broadcast to the subset shape and non-scalar values must match it. It is brought to x's data type: an R value is built at it when its category can reach it (0L serves an integer and a float x alike, while 1.5 into an i32 x is an error), and an array is converted unless that would narrow it or leave its category (an f64 value for an f32 x is an error).

update_fn

(character(1) | function)
How value combines with the subset of x:

  • "replace" (the default): value replaces it,

  • "add", "sub", "mul": it becomes the subset plus, minus or times value,

  • "max", "min": it becomes the larger or the smaller of the two,

or a binary function f(old, new) of two scalars, see prim_scatter(). Unlike x[i] <- x[i] + value in R, a position that i selects more than once gets every one of its values: with "add", x[array(c(1L, 1L))] adds both to x[1]. gradient() differentiates the names, but not a function; with "mul", not with respect to value where i selects several positions of an axis by an index array or a mask, since those may repeat. With [<-, pass it among the subscripts, e.g. x[1, update_fn = "add"] <- 1.

inplace

(logical(1))
Whether to write into the memory of x instead of allocating a new array. This avoids the copy of x that an eager subset assignment otherwise makes, but it consumes x: its buffer is donated, so x – and any other R variable referring to the same array – can no longer be used afterwards. With [<-, pass it among the subscripts, e.g. x[1, inplace = TRUE] <- 0, which rebinds x to the result. It is an error inside a jitted function: there, other references to x would stay valid, so the same code would behave differently in eager and in jit mode. Inside jit(), the compiler already avoids the copy anyway. Default is FALSE.

Value

(arrayish)
Has x's data type and shape, with the subset replaced (or combined with value as update_fn says).

See also

nv_subset(), the Subsetting article for a comprehensive guide.

Examples

x <- nv_matrix(1:12, nrow = 3)
# set row 1 to zeros
nv_subset_assign(x, 1, value = nv_scalar(0L))
#> AnvlArray
#>   0  0  0  0
#>   2  5  8 11
#>   3  6  9 12
#> [ CPUi32{3,4} ] 
x[1, ] <- nv_scalar(0L)
x
#> AnvlArray
#>   0  0  0  0
#>   2  5  8 11
#>   3  6  9 12
#> [ CPUi32{3,4} ] 

# Zero out every element greater than 6 (not in `jit()`, see `nv_subset()`)
x[x > 6] <- 0L
x
#> AnvlArray
#>  0 0 0 0
#>  2 5 0 0
#>  3 6 0 0
#> [ CPUi32{3,4} ] 

# add to the subset instead of replacing it; a repeated index adds twice
nv_subset_assign(x, array(c(1L, 1L)), 1, value = nv_scalar(10L), update_fn = "add")
#> AnvlArray
#>  20  0  0  0
#>   2  5  0  0
#>   3  6  0  0
#> [ CPUi32{3,4} ] 

# write into the memory of `x` instead of copying it
x[2, inplace = TRUE] <- nv_scalar(1L)
x
#> AnvlArray
#>  0 0 0 0
#>  1 1 1 1
#>  3 6 0 0
#> [ CPUi32{3,4} ]