Interacting with CSDM objectsΒΆ
Basic math operationsΒΆ
The csdm object supports basic mathematical operations such as additive and multiplicative operations.
Note
All operations applied to or involving the csdm objects apply only to the components of the dependent variables within the csdm object. These operations do not apply to the dimensions within the csdm object.
Consider the following csdm data object.
>>> arr1 = np.arange(6, dtype=np.float32).reshape(2, 3)
>>> csdm_obj1 = cp.as_csdm(arr1)
>>> # converting the dimension to proper physical dimensions.
>>> csdm_obj1.dimensions[0]*=cp.ScalarQuantity('2.64 m')
>>> csdm_obj1.dimensions[0].coordinates_offset = '1 km'
>>> # converting the dimension to proper physical dimensions.
>>> csdm_obj1.dimensions[1]*=cp.ScalarQuantity('10 Β΅s')
>>> csdm_obj1.dimensions[1].coordinates_offset = '-0.5 ms'
>>> print(csdm_obj1)
CSDM(
DependentVariable(
[[[0. 1. 2.]
[3. 4. 5.]]], quantity_type=scalar, numeric_type=float32),
LinearDimension([1000. 1002.64 1005.28] m),
LinearDimension([-500. -490.] us)
)
Additive operations involving a scalarΒΆ
Example 1
>>> csdm_obj1 += np.pi
>>> print(csdm_obj1)
CSDM(
DependentVariable(
[[[3.1415927 4.141593 5.141593 ]
[6.141593 7.141593 8.141593 ]]], quantity_type=scalar, numeric_type=float32),
LinearDimension([1000. 1002.64 1005.28] m),
LinearDimension([-500. -490.] us)
)
Example 2
>>> csdm_obj2 = csdm_obj1 + (2 - 4j)
>>> print(csdm_obj2)
CSDM(
DependentVariable(
[[[ 5.141593-4.j 6.141593-4.j 7.141593-4.j]
[ 8.141593-4.j 9.141593-4.j 10.141593-4.j]]], quantity_type=scalar, numeric_type=complex64),
LinearDimension([1000. 1002.64 1005.28] m),
LinearDimension([-500. -490.] us)
)
Multiplicative operations involving scalar / ScalarQuantityΒΆ
Example 3
>>> csdm_obj1 = cp.as_csdm(np.ones(6).reshape(2, 3))
>>> csdm_obj2 = csdm_obj1 * 4.693
>>> print(csdm_obj2)
CSDM(
DependentVariable(
[[[4.693 4.693 4.693]
[4.693 4.693 4.693]]], quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2.]),
LinearDimension([0. 1.])
)
Example 4
>>> csdm_obj2 = csdm_obj1 * 3j/2.4
>>> print(csdm_obj2)
CSDM(
DependentVariable(
[[[0.+1.25j 0.+1.25j 0.+1.25j]
[0.+1.25j 0.+1.25j 0.+1.25j]]], quantity_type=scalar, numeric_type=complex128),
LinearDimension([0. 1. 2.]),
LinearDimension([0. 1.])
)
You may change the dimensionality of the dependent variables by multiplying the csdm object with the appropriate scalar quantity, for example,
Example 5
>>> csdm_obj1 *= cp.ScalarQuantity('3.23 m')
>>> print(csdm_obj1)
CSDM(
DependentVariable(
[[[3.23 3.23 3.23]
[3.23 3.23 3.23]]] m, quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2.]),
LinearDimension([0. 1.])
)
Example 6
>>> csdm_obj1 /= cp.ScalarQuantity('3.23 m')
>>> print(csdm_obj1)
CSDM(
DependentVariable(
[[[1. 1. 1.]
[1. 1. 1.]]], quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2.]),
LinearDimension([0. 1.])
)
Additive operations involving two csdm objectsΒΆ
The additive operations are supported between two csdm objects only when the two objects have identical sets of Dimension objects and DependentVariable objects with the same dimensionality. For examples,
Example 7
>>> csdm1 = cp.as_csdm(np.ones((2,3)), unit='m/s')
>>> csdm2 = cp.as_csdm(np.ones((2,3)), unit='cm/s')
>>> csdm_obj = csdm1 + csdm2
>>> print(csdm_obj)
CSDM(
DependentVariable(
[[[1.01 1.01 1.01]
[1.01 1.01 1.01]]] m / s, quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2.]),
LinearDimension([0. 1.])
)
An exception will be raised if the DependentVariable objects of the two csdm objects have different dimensionality.
Example 8
>>> csdm1 = cp.as_csdm(np.ones((2,3)), unit='m/s')
>>> csdm2 = cp.as_csdm(np.ones((2,3)))
>>> csdm_obj = csdm1 + csdm2
Exception: Cannot operate on dependent variables with physical types: speed and dimensionless.
Similarly, an exception will be raised if the dimension objects of the two csdm objects are different.
Example 9
>>> csdm1 = cp.as_csdm(np.ones((2,3)), unit='m/s')
>>> csdm1.dimensions[1] = cp.MonotonicDimension(coordinates=['1 ms', '1 s'])
>>> csdm2 = cp.as_csdm(np.ones((2,3)), unit='cm/s')
>>> csdm_obj = csdm1 + csdm2
Exception: Cannot operate on CSDM objects with different dimensions.
Basic Slicing and IndexingΒΆ
The CSDM objects support NumPy basic slicing and indexing and follow the same rules as the NumPy array. Consider the following 3D{1} csdm object.
>>> csdm1 = cp.as_csdm(np.zeros((5, 10, 20)), unit='s')
>>> csdm1.dimensions[0] = cp.as_dimension(np.arange(20)*0.5+4.3, unit='kg')
>>> csdm1.dimensions[1] = cp.as_dimension([1, 2, 3, 5, 7, 11, 13, 17, 19, 23], unit='mm')
>>> csdm1.dimensions[2] = cp.LabeledDimension(labels=list('abcde'))
>>> print(csdm1.shape)
(20, 10, 5)
>>> print(csdm1.dimensions)
[LinearDimension(count=20, increment=0.5 kg, coordinates_offset=4.3 kg, quantity_name=mass),
MonotonicDimension(coordinates=[ 1. 2. 3. 5. 7. 11. 13. 17. 19. 23.] mm, quantity_name=length, reciprocal={'quantity_name': 'wavenumber'}),
LabeledDimension(labels=['a', 'b', 'c', 'd', 'e'])]
The above object csdm1
has three dimensions, each with different
dimensionality and dimension type.
To retrieve a sub-grid of this 3D{1} dataset, use the NumPy indexing scheme.
Example 10
>>> sub_csdm = csdm1[0]
>>> print(sub_csdm.shape)
(10, 5)
>>> print(sub_csdm.dimensions)
[MonotonicDimension(coordinates=[ 1. 2. 3. 5. 7. 11. 13. 17. 19. 23.] mm, quantity_name=length, reciprocal={'quantity_name': 'wavenumber'}),
LabeledDimension(labels=['a', 'b', 'c', 'd', 'e'])]
The above example returns a 2D{1} cross-section of the 3D{1} datasets
corresponding to the index 0 along the first dimension of the csdm1
object as a sub_csdm
csdm object. The two dimensions in sub_csdm
are
the MonotonicDimension and LabeledDimension.
Example 11
>>> sub_csdm = csdm1[::5, 2::2, :]
>>> print(sub_csdm.shape)
(4, 4, 5)
>>> print(sub_csdm.dimensions)
[LinearDimension(count=4, increment=2.5 kg, coordinates_offset=4.3 kg, quantity_name=mass),
MonotonicDimension(coordinates=[ 3. 7. 13. 19.] mm, quantity_name=length, reciprocal={'quantity_name': 'wavenumber'}),
LabeledDimension(labels=['a', 'b', 'c', 'd', 'e'])]
The above example returns a 3D{1} dataset, sub_csdm
, which contains a
sub-grid of the 3D{1} datasets from csdm1
. In sub_csdm
, the first
dimension is a sub-grid of the first dimension from the csdm1
object,
where only every fifth grid point is selected. Similarly, the second dimension
of the sub_csdm
object is sampled from the second dimension of the
csdm1
object, where every second grid point is selected, starting with the
entry at the grid index two. The third dimension of the sub_csdm
object
is the same as the third object of the csdm1
object. The values of the
corresponding linear, monotonic, and labeled dimensions are adjusted accordingly.
For example, notice the value of the count and increment attributes of the linear
dimension in sub_csdm
object.
Example 12
>>> sub_csdm = csdm1[::5, 2::2, -3::-1]
>>> print(sub_csdm.shape)
(4, 4, 3)
>>> print(sub_csdm.dimensions)
[LinearDimension(count=4, increment=2.5 kg, coordinates_offset=4.3 kg, quantity_name=mass),
MonotonicDimension(coordinates=[ 3. 7. 13. 19.] mm, quantity_name=length, reciprocal={'quantity_name': 'wavenumber'}),
LabeledDimension(labels=['c', 'b', 'a'])]
The above example is similar to the previous examples, except the third dimension indexed in reversed starting at the third index from the end.
See also
Support for Numpy methodsΒΆ
In most cases, the csdm object may be used as if it were a NumPy array. See the list of all supported Supported NumPy functions.
Method that only operate on dimensionless dependent variablesΒΆ
Example 13
>>> csdm_obj1 = cp.as_csdm(10**(np.arange(10)/10))
>>> new_csdm1 = np.log10(csdm_obj1)
>>> print(new_csdm1)
CSDM(
DependentVariable(
[[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]], quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2. 3. 4. 5. 6. 7. 8. 9.])
)
Example 14
>>> new_csdm2 = np.cos(2*np.pi*new_csdm1)
>>> print(new_csdm2)
CSDM(
DependentVariable(
[[ 1. 0.80901699 0.30901699 -0.30901699 -0.80901699 -1.
-0.80901699 -0.30901699 0.30901699 0.80901699]], quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2. 3. 4. 5. 6. 7. 8. 9.])
)
Example 15
>>> new_csdm2 = np.exp(new_csdm1 * cp.ScalarQuantity('K'))
ValueError: Cannot apply `exp` to quantity with physical type `temperature`.
An exception is raised for csdm object with non-dimensionless dependent variables.
Method that are independent of the dependent variable dimensionalityΒΆ
Example 16
>>> new_csdm2 = np.square(new_csdm1 * cp.ScalarQuantity('K'))
>>> print(new_csdm2)
CSDM(
DependentVariable(
[[0. 0.01 0.04 0.09 0.16 0.25 0.36 0.49 0.64 0.81]] K2, quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2. 3. 4. 5. 6. 7. 8. 9.])
)
Example 17
>>> new_csdm1 = np.sqrt(new_csdm2)
>>> print(new_csdm1)
CSDM(
DependentVariable(
[[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]] K, quantity_type=scalar, numeric_type=float64),
LinearDimension([0. 1. 2. 3. 4. 5. 6. 7. 8. 9.])
)
Dimension reduction methodsΒΆ
Example 18
>>> csdm1 = cp.as_csdm(np.ones((10,20,30)), unit='Β΅G')
>>> csdm1.shape
(30, 20, 10)
>>> new = np.sum(csdm1, axis=1)
>>> new.shape
(30, 10)
>>> print(new.dimensions)
[LinearDimension(count=30, increment=1.0),
LinearDimension(count=10, increment=1.0)]
Example 19
>>> csdm1 = cp.as_csdm(np.ones((10,20,30)), unit='Β΅G')
>>> csdm1.shape
(30, 20, 10)
>>> new = np.sum(csdm1, axis=(1, 2))
>>> new.shape
(30,)
>>> print(new.dimensions)
[LinearDimension(count=30, increment=1.0)]
Example 20
>>> minimum = np.min(new_csdm1)
>>> print(minimum)
0.0 K
>>> np.min(new_csdm1) == new_csdm1.min()
True
Note
See the list of all supported Supported NumPy functions.