Skip to main content

Array Indexing

csdl supports indexing into Variable objects for explicit outputs.

In this example, integer indices are used to concatenate multiple expressions/variables into one variable and extract values from a single variable representing an array.

The variable representing the array, 'x', is created with the Model.create_output method. Array index assignments are then used to define 'x' in terms of other CSDL variables.

Note: For every variable created with Model.create_output, there is no need to call Model.register_output.

from csdl_om import Simulatorimport numpy as npimport csdlfrom csdl import Model

class ExampleInteger(Model):
    def define(self):        a = self.declare_variable('a', val=0)        b = self.declare_variable('b', val=1)        c = self.declare_variable('c', val=2)        d = self.declare_variable('d', val=7.4)        e = self.declare_variable('e', val=np.pi)        f = self.declare_variable('f', val=9)        g = e + f        x = self.create_output('x', shape=(7, ))        x[0] = a        x[1] = b        x[2] = c        x[3] = d        x[4] = e        x[5] = f        x[6] = g
        # Get value from indices        self.register_output('x0', x[0])        self.register_output('x6', x[6])        self.register_output('x_2', x[-2])

sim = Simulator(ExampleInteger())sim.run()
print('x', sim['x'].shape)print(sim['x'])print('x0', sim['x0'].shape)print(sim['x0'])print('x6', sim['x6'].shape)print(sim['x6'])
[ 0.          1.          2.          7.4         3.14159265  9. 12.14159265]x0 (1,)[0.]x6 (1,)[12.14159265]

csdl supports specifying ranges as well as individual indices to slice and concatenate arrays.

from csdl_om import Simulatorimport numpy as npimport csdlfrom csdl import Model

class ExampleOneDimensional(Model):
    def define(self):        n = 20        u = self.declare_variable('u',                                  shape=(n, ),                                  val=np.arange(n).reshape((n, )))        v = self.declare_variable('v',                                  shape=(n - 4, ),                                  val=np.arange(n - 4).reshape(                                      (n - 4, )))        w = self.declare_variable('w',                                  shape=(4, ),                                  val=16 + np.arange(4).reshape((4, )))        x = self.create_output('x', shape=(n, ))        x[0:n] = 2 * (u + 1)        y = self.create_output('y', shape=(n, ))        y[0:n - 4] = 2 * (v + 1)        y[n - 4:n] = w - 3
        # Get value from indices        z = self.create_output('z', shape=(3, ))        z[0:3] = csdl.expand(x[2], (3, ))        self.register_output('x0_5', x[0:5])        self.register_output('x3_', x[3:])        self.register_output('x2_4', x[2:4])        self.register_output('x_last', x[-1])

sim = Simulator(ExampleOneDimensional())sim.run()
print('x', sim['x'].shape)print(sim['x'])print('y', sim['y'].shape)print(sim['y'])print('z', sim['z'].shape)print(sim['z'])print('x0_5', sim['x0_5'].shape)print(sim['x0_5'])print('x3_', sim['x3_'].shape)print(sim['x3_'])print('x2_4', sim['x2_4'].shape)print(sim['x2_4'])
[ 2.  4.  6.  8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36. 38. 40.]y (20,)[ 2.  4.  6.  8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 13. 14. 15. 16.]z (3,)[6. 6. 6.]x0_5 (5,)[ 2.  4.  6.  8. 10.]x3_ (17,)[ 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36. 38. 40.]x2_4 (2,)[6. 8.]

csdl supports specifying ranges along multiple axes as well as individual indices and ranges to slice and concatenate arrays.

from csdl_om import Simulatorimport numpy as npimport csdlfrom csdl import Model

class ExampleMultidimensional(Model):
    def define(self):        # Works with two dimensional arrays        z = self.declare_variable('z',                                  shape=(2, 3),                                  val=np.arange(6).reshape((2, 3)))        x = self.create_output('x', shape=(2, 3))        x[0:2, 0:3] = z
        # Also works with higher dimensional arrays        p = self.declare_variable('p',                                  shape=(5, 2, 3),                                  val=np.arange(30).reshape((5, 2, 3)))        q = self.create_output('q', shape=(5, 2, 3))        q[0:5, 0:2, 0:3] = p
        # Get value from indices        self.register_output('r', p[0, :, :])        self.register_output('r2', p[0, -1, 2])
        # Assign a vector to a slice        vec = self.create_input(            'vec',            shape=(1, 20),            val=np.arange(20).reshape((1, 20)),        )        s = self.create_output('s', shape=(2, 20))        s[0, :] = vec        s[1, :] = 2 * vec
        # Negative indices and unassigned indices that take on default        # values        t = self.create_output('t', shape=(5, 3, 3), val=0)        t[0:5, 0:-1, 0:3] = p

sim = Simulator(ExampleMultidimensional())sim.run()
print('x', sim['x'].shape)print(sim['x'])print('q', sim['q'].shape)print(sim['q'])print('r', sim['r'].shape)print(sim['r'])print('r2', sim['r2'].shape)print(sim['r2'])print('s', sim['s'].shape)print(sim['s'])print('t', sim['t'].shape)print(sim['t'])
[[0. 1. 2.] [3. 4. 5.]]q (5, 2, 3)[[[ 0.  1.  2.]  [ 3.  4.  5.]]
 [[ 6.  7.  8.]  [ 9. 10. 11.]]
 [[12. 13. 14.]  [15. 16. 17.]]
 [[18. 19. 20.]  [21. 22. 23.]]
 [[24. 25. 26.]  [27. 28. 29.]]]r (1, 2, 3)[[[0. 1. 2.]  [3. 4. 5.]]]r2 (1, 1, 1)[[[5.]]]s (2, 20)[[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14. 15. 16. 17.  18. 19.] [ 0.  2.  4.  6.  8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34.  36. 38.]]t (5, 3, 3)[[[ 0.  1.  2.]  [ 3.  4.  5.]  [ 0.  0.  0.]]
 [[ 6.  7.  8.]  [ 9. 10. 11.]  [ 0.  0.  0.]]
 [[12. 13. 14.]  [15. 16. 17.]  [ 0.  0.  0.]]
 [[18. 19. 20.]  [21. 22. 23.]  [ 0.  0.  0.]]
 [[24. 25. 26.]  [27. 28. 29.]  [ 0.  0.  0.]]]