Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify object whose name is based on contents of an array

Tags:

julia

I have a two-element vector whose elements can only be 0 or 1. For the sake of this example, suppose x = [0, 1]. Suppose also there are four objects y00, y01, y10, y11. My goal is to update the corresponding y (y01 in this example) according to the current value of x.

I am aware I can do this using a series of if statements:

if x == [0, 0]
    y00 += 1
elseif x == [0, 1]
    y01 += 1
elseif x == [1, 0]
    y10 += 1
elseif x == [1, 1]
    y11 += 1
end

However, I understand this can be done more succinctly using Julia's metaprogramming, although I'm unfamiliar with its usage and can't figure out how. I want to be able to express something like y{x[1]}{x[2]} += 1 (which is obviously wrong); basically, be able to refer and modify the correct y according to the current value of x. So far, I've been able to call the actual value of the correct y (but I can't summon the y object itself) with something like

eval(Symbol(string("y", x[1], x[2])))

I'm sorry if I did not use the appropriate lingo, but I hope I made myself clear.

like image 440
han-tyumi Avatar asked Jan 25 '23 11:01

han-tyumi


2 Answers

There's a much more elegant way using StaticArrays. You can define a common type for your y values, which will behave like a matrix (which I assume the ys represent?), and defines a lot of things for you:

julia> mutable struct Thing2 <: FieldMatrix{2, 2, Float64}
           y00::Float64
           y01::Float64
           y10::Float64
           y11::Float64
       end

julia> M = rand(Thing2)
2×2 Thing2 with indices SOneTo(2)×SOneTo(2):
 0.695919  0.624941 
 0.404213  0.0317816

julia> M.y00 += 1
1.6959194941562996

julia> M[1, 2] += 1
1.6249412302897646

julia> M * [2, 3]
2-element SArray{Tuple{2},Float64,1,2} with indices SOneTo(2):
 10.266662679181893 
  0.9037708026795666

(Side note: Julia indices begin at 1, so it might be more idiomatic to use one-based indices for y as well. Alternatively, can create array types with custom indexing, but that's more work, again.)

like image 69
phipsgabler Avatar answered Jan 28 '23 01:01

phipsgabler


How about using x as linear indices into an array Y?

x = reshape(1:4, 2, 2)
Y = zeros(4);
Y[ x[1,2] ] += 1
like image 41
Tasos Papastylianou Avatar answered Jan 27 '23 23:01

Tasos Papastylianou