antioch-py 2.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of antioch-py might be problematic. Click here for more details.
- antioch/__init__.py +0 -0
- antioch/message.py +87 -0
- antioch/module/__init__.py +53 -0
- antioch/module/clock.py +62 -0
- antioch/module/execution.py +278 -0
- antioch/module/input.py +127 -0
- antioch/module/module.py +218 -0
- antioch/module/node.py +357 -0
- antioch/module/token.py +42 -0
- antioch/session/__init__.py +150 -0
- antioch/session/ark.py +504 -0
- antioch/session/asset.py +65 -0
- antioch/session/error.py +80 -0
- antioch/session/record.py +158 -0
- antioch/session/scene.py +1521 -0
- antioch/session/session.py +220 -0
- antioch/session/task.py +323 -0
- antioch/session/views/__init__.py +40 -0
- antioch/session/views/animation.py +189 -0
- antioch/session/views/articulation.py +245 -0
- antioch/session/views/basis_curve.py +186 -0
- antioch/session/views/camera.py +92 -0
- antioch/session/views/collision.py +75 -0
- antioch/session/views/geometry.py +74 -0
- antioch/session/views/ground_plane.py +63 -0
- antioch/session/views/imu.py +73 -0
- antioch/session/views/joint.py +64 -0
- antioch/session/views/light.py +175 -0
- antioch/session/views/pir_sensor.py +140 -0
- antioch/session/views/radar.py +73 -0
- antioch/session/views/rigid_body.py +282 -0
- antioch/session/views/xform.py +119 -0
- antioch_py-2.0.6.dist-info/METADATA +115 -0
- antioch_py-2.0.6.dist-info/RECORD +99 -0
- antioch_py-2.0.6.dist-info/WHEEL +5 -0
- antioch_py-2.0.6.dist-info/entry_points.txt +2 -0
- antioch_py-2.0.6.dist-info/top_level.txt +2 -0
- common/__init__.py +0 -0
- common/ark/__init__.py +60 -0
- common/ark/ark.py +128 -0
- common/ark/hardware.py +121 -0
- common/ark/kinematics.py +31 -0
- common/ark/module.py +85 -0
- common/ark/node.py +94 -0
- common/ark/scheduler.py +439 -0
- common/ark/sim.py +33 -0
- common/assets/__init__.py +3 -0
- common/constants.py +47 -0
- common/core/__init__.py +52 -0
- common/core/agent.py +296 -0
- common/core/auth.py +305 -0
- common/core/registry.py +331 -0
- common/core/task.py +36 -0
- common/message/__init__.py +59 -0
- common/message/annotation.py +89 -0
- common/message/array.py +500 -0
- common/message/base.py +517 -0
- common/message/camera.py +91 -0
- common/message/color.py +139 -0
- common/message/frame.py +50 -0
- common/message/image.py +171 -0
- common/message/imu.py +14 -0
- common/message/joint.py +47 -0
- common/message/log.py +31 -0
- common/message/pir.py +16 -0
- common/message/point.py +109 -0
- common/message/point_cloud.py +63 -0
- common/message/pose.py +148 -0
- common/message/quaternion.py +273 -0
- common/message/radar.py +58 -0
- common/message/types.py +37 -0
- common/message/vector.py +786 -0
- common/rome/__init__.py +9 -0
- common/rome/client.py +430 -0
- common/rome/error.py +16 -0
- common/session/__init__.py +54 -0
- common/session/environment.py +31 -0
- common/session/sim.py +240 -0
- common/session/views/__init__.py +263 -0
- common/session/views/animation.py +73 -0
- common/session/views/articulation.py +184 -0
- common/session/views/basis_curve.py +102 -0
- common/session/views/camera.py +147 -0
- common/session/views/collision.py +59 -0
- common/session/views/geometry.py +102 -0
- common/session/views/ground_plane.py +41 -0
- common/session/views/imu.py +66 -0
- common/session/views/joint.py +81 -0
- common/session/views/light.py +96 -0
- common/session/views/pir_sensor.py +115 -0
- common/session/views/radar.py +82 -0
- common/session/views/rigid_body.py +236 -0
- common/session/views/viewport.py +21 -0
- common/session/views/xform.py +39 -0
- common/utils/__init__.py +4 -0
- common/utils/comms.py +571 -0
- common/utils/logger.py +123 -0
- common/utils/time.py +42 -0
- common/utils/usd.py +12 -0
common/message/array.py
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from pydantic import Field, PrivateAttr, model_validator
|
|
7
|
+
|
|
8
|
+
from common.message.base import Message
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Array(Message):
|
|
12
|
+
"""
|
|
13
|
+
A message type for representing an unbounded array of float32 values.
|
|
14
|
+
Serialized as bytes, with lazy numpy array conversion for operations.
|
|
15
|
+
|
|
16
|
+
Arrays automatically convert from common Python types:
|
|
17
|
+
- Lists: Array(data=[1.0, 2.0, 3.0]) or Array.from_any([1.0, 2.0, 3.0])
|
|
18
|
+
- Tuples: Array(data=(1.0, 2.0, 3.0))
|
|
19
|
+
- Sets: Array(data={1.0, 2.0, 3.0})
|
|
20
|
+
- Numpy arrays: Array(data=np.array([1.0, 2.0, 3.0]))
|
|
21
|
+
- Any iterable: Array(data=range(10))
|
|
22
|
+
|
|
23
|
+
When used as a field in Messages, conversion happens automatically:
|
|
24
|
+
class RobotCommand(Message):
|
|
25
|
+
joint_positions: Array
|
|
26
|
+
|
|
27
|
+
cmd = RobotCommand(joint_positions=[0.1, 0.2, 0.3]) # List auto-converts!
|
|
28
|
+
|
|
29
|
+
This makes it seamless to use in APIs without explicit conversion calls.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
_type = "antioch/array"
|
|
33
|
+
_arr: np.ndarray | None = PrivateAttr(default=None)
|
|
34
|
+
data: bytes = Field(description="Serialized array data as bytes")
|
|
35
|
+
|
|
36
|
+
def __len__(self) -> int:
|
|
37
|
+
"""
|
|
38
|
+
Get the length of the array.
|
|
39
|
+
|
|
40
|
+
:return: The length.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
return len(self.data) // 4 # 4 bytes per float32
|
|
44
|
+
|
|
45
|
+
def __iter__(self):
|
|
46
|
+
"""
|
|
47
|
+
Iterate over array elements.
|
|
48
|
+
|
|
49
|
+
:return: Iterator over float values.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
return iter(self.to_numpy())
|
|
53
|
+
|
|
54
|
+
def __getitem__(self, key: Any) -> Any:
|
|
55
|
+
"""
|
|
56
|
+
Get an item from the array.
|
|
57
|
+
|
|
58
|
+
:param key: The index or slice.
|
|
59
|
+
:return: The item.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
return self.to_numpy()[key]
|
|
63
|
+
|
|
64
|
+
def __setitem__(self, key: Any, value: Any) -> None:
|
|
65
|
+
"""
|
|
66
|
+
Set an item in the array.
|
|
67
|
+
|
|
68
|
+
:param key: The index or slice.
|
|
69
|
+
:param value: The value to set.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
arr = self.to_numpy().copy()
|
|
73
|
+
arr[key] = value
|
|
74
|
+
self.data = arr.tobytes()
|
|
75
|
+
self._arr = arr
|
|
76
|
+
|
|
77
|
+
def __eq__(self, other: object) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Check equality with another Array.
|
|
80
|
+
|
|
81
|
+
:param other: Another Array.
|
|
82
|
+
:return: True if arrays are equal.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
if not isinstance(other, Array):
|
|
86
|
+
return False
|
|
87
|
+
return self.data == other.data
|
|
88
|
+
|
|
89
|
+
def __repr__(self) -> str:
|
|
90
|
+
"""
|
|
91
|
+
Return a readable string representation showing array values.
|
|
92
|
+
|
|
93
|
+
:return: String representation.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
arr = self.to_numpy()
|
|
97
|
+
return f"Array({arr!r})"
|
|
98
|
+
|
|
99
|
+
def __str__(self) -> str:
|
|
100
|
+
"""
|
|
101
|
+
Return a readable string representation showing array values.
|
|
102
|
+
|
|
103
|
+
:return: String representation.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
arr = self.to_numpy()
|
|
107
|
+
return f"Array({arr!r})"
|
|
108
|
+
|
|
109
|
+
def __add__(self, other: Array | float | int) -> Array:
|
|
110
|
+
"""
|
|
111
|
+
Add arrays element-wise or add a scalar to all elements.
|
|
112
|
+
|
|
113
|
+
:param other: Another Array or a scalar value.
|
|
114
|
+
:return: The result array.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
if isinstance(other, Array):
|
|
118
|
+
result = self.to_numpy() + other.to_numpy()
|
|
119
|
+
elif isinstance(other, (int, float)):
|
|
120
|
+
result = self.to_numpy() + other
|
|
121
|
+
return Array.from_numpy(result)
|
|
122
|
+
|
|
123
|
+
def __radd__(self, other: float | int) -> Array:
|
|
124
|
+
"""
|
|
125
|
+
Add a scalar to all elements (reversed operands).
|
|
126
|
+
|
|
127
|
+
:param other: A scalar value.
|
|
128
|
+
:return: The result array.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
return self.__add__(other)
|
|
132
|
+
|
|
133
|
+
def __sub__(self, other: Array | float | int) -> Array:
|
|
134
|
+
"""
|
|
135
|
+
Subtract arrays element-wise or subtract a scalar from all elements.
|
|
136
|
+
|
|
137
|
+
:param other: Another Array or a scalar value.
|
|
138
|
+
:return: The result array.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
if isinstance(other, Array):
|
|
142
|
+
result = self.to_numpy() - other.to_numpy()
|
|
143
|
+
elif isinstance(other, (int, float)):
|
|
144
|
+
result = self.to_numpy() - other
|
|
145
|
+
return Array.from_numpy(result)
|
|
146
|
+
|
|
147
|
+
def __rsub__(self, other: float | int) -> Array:
|
|
148
|
+
"""
|
|
149
|
+
Subtract all elements from a scalar (reversed operands).
|
|
150
|
+
|
|
151
|
+
:param other: A scalar value.
|
|
152
|
+
:return: The result array.
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
result = other - self.to_numpy()
|
|
156
|
+
return Array.from_numpy(result)
|
|
157
|
+
|
|
158
|
+
def __mul__(self, other: Array | float | int) -> Array:
|
|
159
|
+
"""
|
|
160
|
+
Multiply arrays element-wise or multiply all elements by a scalar.
|
|
161
|
+
|
|
162
|
+
:param other: Another Array or a scalar value.
|
|
163
|
+
:return: The result array.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
if isinstance(other, Array):
|
|
167
|
+
result = self.to_numpy() * other.to_numpy()
|
|
168
|
+
elif isinstance(other, (int, float)):
|
|
169
|
+
result = self.to_numpy() * other
|
|
170
|
+
return Array.from_numpy(result)
|
|
171
|
+
|
|
172
|
+
def __rmul__(self, other: float | int) -> Array:
|
|
173
|
+
"""
|
|
174
|
+
Multiply all elements by a scalar (reversed operands).
|
|
175
|
+
|
|
176
|
+
:param other: A scalar value.
|
|
177
|
+
:return: The result array.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
return self.__mul__(other)
|
|
181
|
+
|
|
182
|
+
def __truediv__(self, other: Array | float | int) -> Array:
|
|
183
|
+
"""
|
|
184
|
+
Divide arrays element-wise or divide all elements by a scalar.
|
|
185
|
+
|
|
186
|
+
:param other: Another Array or a scalar value.
|
|
187
|
+
:return: The result array.
|
|
188
|
+
:raises ZeroDivisionError: If dividing by zero scalar.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
if isinstance(other, Array):
|
|
192
|
+
result = self.to_numpy() / other.to_numpy()
|
|
193
|
+
elif isinstance(other, (int, float)):
|
|
194
|
+
if other == 0:
|
|
195
|
+
raise ZeroDivisionError("Cannot divide array by zero")
|
|
196
|
+
result = self.to_numpy() / other
|
|
197
|
+
return Array.from_numpy(result)
|
|
198
|
+
|
|
199
|
+
def __rtruediv__(self, other: float | int) -> Array:
|
|
200
|
+
"""
|
|
201
|
+
Divide a scalar by all elements (reversed operands).
|
|
202
|
+
|
|
203
|
+
:param other: A scalar value.
|
|
204
|
+
:return: The result array.
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
result = other / self.to_numpy()
|
|
208
|
+
return Array.from_numpy(result)
|
|
209
|
+
|
|
210
|
+
def __neg__(self) -> Array:
|
|
211
|
+
"""
|
|
212
|
+
Negate all elements in the array.
|
|
213
|
+
|
|
214
|
+
:return: The negated array.
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
return Array.from_numpy(-self.to_numpy())
|
|
218
|
+
|
|
219
|
+
def __pow__(self, other: float | int) -> Array:
|
|
220
|
+
"""
|
|
221
|
+
Raise all elements to a power.
|
|
222
|
+
|
|
223
|
+
:param other: The exponent.
|
|
224
|
+
:return: The result array.
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
result = self.to_numpy() ** other
|
|
228
|
+
return Array.from_numpy(result)
|
|
229
|
+
|
|
230
|
+
@model_validator(mode="before")
|
|
231
|
+
@classmethod
|
|
232
|
+
def convert_iterables(cls, data: Any) -> Any:
|
|
233
|
+
"""
|
|
234
|
+
Automatically convert common Python types to Array format.
|
|
235
|
+
|
|
236
|
+
Supports: lists, tuples, sets, numpy arrays, and any iterable.
|
|
237
|
+
This allows seamless usage without explicit Array.from_*() calls.
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
# Already an Array instance
|
|
241
|
+
if isinstance(data, cls):
|
|
242
|
+
return data.model_dump()
|
|
243
|
+
|
|
244
|
+
# Dict format - check if data field needs conversion
|
|
245
|
+
if isinstance(data, dict):
|
|
246
|
+
# If data field is already bytes, no conversion needed
|
|
247
|
+
if "data" in data and isinstance(data["data"], bytes):
|
|
248
|
+
return data
|
|
249
|
+
# If data field is an iterable, convert it
|
|
250
|
+
if "data" in data:
|
|
251
|
+
data_value = data["data"]
|
|
252
|
+
if isinstance(data_value, np.ndarray):
|
|
253
|
+
data["data"] = data_value.astype(np.float32).tobytes()
|
|
254
|
+
return data
|
|
255
|
+
if hasattr(data_value, "__iter__") and not isinstance(data_value, (str, bytes)):
|
|
256
|
+
try:
|
|
257
|
+
arr = np.array(list(data_value), dtype=np.float32)
|
|
258
|
+
data["data"] = arr.tobytes()
|
|
259
|
+
return data
|
|
260
|
+
except (ValueError, TypeError) as e:
|
|
261
|
+
raise ValueError(f"Failed to convert iterable to Array: {e}") from None
|
|
262
|
+
return data
|
|
263
|
+
|
|
264
|
+
# Raw bytes (used internally)
|
|
265
|
+
if isinstance(data, bytes):
|
|
266
|
+
return {"data": data}
|
|
267
|
+
|
|
268
|
+
# Numpy array - convert directly
|
|
269
|
+
if isinstance(data, np.ndarray):
|
|
270
|
+
return {"data": data.astype(np.float32).tobytes()}
|
|
271
|
+
|
|
272
|
+
# Any iterable (list, tuple, set, generator, etc.) - exclude strings and bytes
|
|
273
|
+
if hasattr(data, "__iter__") and not isinstance(data, (str, bytes)):
|
|
274
|
+
try:
|
|
275
|
+
arr = np.array(list(data), dtype=np.float32)
|
|
276
|
+
return {"data": arr.tobytes()}
|
|
277
|
+
except (ValueError, TypeError) as e:
|
|
278
|
+
raise ValueError(f"Failed to convert iterable to Array: {e}") from None
|
|
279
|
+
|
|
280
|
+
return data
|
|
281
|
+
|
|
282
|
+
@classmethod
|
|
283
|
+
def from_any(cls, data: Any) -> Array:
|
|
284
|
+
"""
|
|
285
|
+
Create Array from any iterable type (list, tuple, set, numpy array, etc.).
|
|
286
|
+
|
|
287
|
+
:param data: Any iterable containing numeric values, or an Array instance.
|
|
288
|
+
:return: An Array instance.
|
|
289
|
+
:raises ValueError: If conversion fails.
|
|
290
|
+
"""
|
|
291
|
+
|
|
292
|
+
# Already an Array - return as-is
|
|
293
|
+
if isinstance(data, cls):
|
|
294
|
+
return data
|
|
295
|
+
|
|
296
|
+
# Let the validator handle the conversion
|
|
297
|
+
try:
|
|
298
|
+
return cls(data=data)
|
|
299
|
+
except Exception as e:
|
|
300
|
+
raise ValueError(f"Cannot convert to Array: {e}") from None
|
|
301
|
+
|
|
302
|
+
@classmethod
|
|
303
|
+
def from_numpy(cls, array: np.ndarray) -> Array:
|
|
304
|
+
"""
|
|
305
|
+
Create from a numpy array.
|
|
306
|
+
|
|
307
|
+
:param array: The numpy array.
|
|
308
|
+
:return: An Array instance.
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
return cls(data=array.astype(np.float32).tobytes())
|
|
312
|
+
|
|
313
|
+
@classmethod
|
|
314
|
+
def from_list(cls, values: list[float]) -> Array:
|
|
315
|
+
"""
|
|
316
|
+
Create from a list of floats.
|
|
317
|
+
|
|
318
|
+
:param values: List of float values.
|
|
319
|
+
:return: An Array instance.
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
return cls(data=np.array(values, dtype=np.float32).tobytes())
|
|
323
|
+
|
|
324
|
+
@classmethod
|
|
325
|
+
def zeros(cls, size: int) -> Array:
|
|
326
|
+
"""
|
|
327
|
+
Create an array of zeros.
|
|
328
|
+
|
|
329
|
+
:param size: The size of the array.
|
|
330
|
+
:return: An Array of zeros.
|
|
331
|
+
"""
|
|
332
|
+
|
|
333
|
+
return cls(data=np.zeros(size, dtype=np.float32).tobytes())
|
|
334
|
+
|
|
335
|
+
@classmethod
|
|
336
|
+
def ones(cls, size: int) -> Array:
|
|
337
|
+
"""
|
|
338
|
+
Create an array of ones.
|
|
339
|
+
|
|
340
|
+
:param size: The size of the array.
|
|
341
|
+
:return: An Array of ones.
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
return cls(data=np.ones(size, dtype=np.float32).tobytes())
|
|
345
|
+
|
|
346
|
+
def sum(self) -> float:
|
|
347
|
+
"""
|
|
348
|
+
Compute the sum of all elements.
|
|
349
|
+
|
|
350
|
+
:return: The sum.
|
|
351
|
+
"""
|
|
352
|
+
|
|
353
|
+
return float(np.sum(self.to_numpy()))
|
|
354
|
+
|
|
355
|
+
def mean(self) -> float:
|
|
356
|
+
"""
|
|
357
|
+
Compute the mean of all elements.
|
|
358
|
+
|
|
359
|
+
:return: The mean.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
return float(np.mean(self.to_numpy()))
|
|
363
|
+
|
|
364
|
+
def min(self) -> float:
|
|
365
|
+
"""
|
|
366
|
+
Find the minimum element.
|
|
367
|
+
|
|
368
|
+
:return: The minimum value.
|
|
369
|
+
"""
|
|
370
|
+
|
|
371
|
+
return float(np.min(self.to_numpy()))
|
|
372
|
+
|
|
373
|
+
def max(self) -> float:
|
|
374
|
+
"""
|
|
375
|
+
Find the maximum element.
|
|
376
|
+
|
|
377
|
+
:return: The maximum value.
|
|
378
|
+
"""
|
|
379
|
+
|
|
380
|
+
return float(np.max(self.to_numpy()))
|
|
381
|
+
|
|
382
|
+
def std(self) -> float:
|
|
383
|
+
"""
|
|
384
|
+
Compute the standard deviation.
|
|
385
|
+
|
|
386
|
+
:return: The standard deviation.
|
|
387
|
+
"""
|
|
388
|
+
|
|
389
|
+
return float(np.std(self.to_numpy()))
|
|
390
|
+
|
|
391
|
+
def dot(self, other: Array) -> float:
|
|
392
|
+
"""
|
|
393
|
+
Compute dot product with another array.
|
|
394
|
+
|
|
395
|
+
:param other: Another Array.
|
|
396
|
+
:return: The dot product.
|
|
397
|
+
:raises ValueError: If arrays have different lengths.
|
|
398
|
+
"""
|
|
399
|
+
|
|
400
|
+
if len(self) != len(other):
|
|
401
|
+
raise ValueError(f"Arrays must have same length for dot product: {len(self)} != {len(other)}")
|
|
402
|
+
return float(np.dot(self.to_numpy(), other.to_numpy()))
|
|
403
|
+
|
|
404
|
+
def magnitude(self) -> float:
|
|
405
|
+
"""
|
|
406
|
+
Compute the magnitude (L2 norm) of the array.
|
|
407
|
+
|
|
408
|
+
:return: The magnitude.
|
|
409
|
+
"""
|
|
410
|
+
|
|
411
|
+
return float(np.linalg.norm(self.to_numpy()))
|
|
412
|
+
|
|
413
|
+
def magnitude_squared(self) -> float:
|
|
414
|
+
"""
|
|
415
|
+
Compute the squared magnitude of the array.
|
|
416
|
+
|
|
417
|
+
:return: The squared magnitude.
|
|
418
|
+
"""
|
|
419
|
+
|
|
420
|
+
return float(np.sum(self.to_numpy() ** 2))
|
|
421
|
+
|
|
422
|
+
def normalize(self) -> Array:
|
|
423
|
+
"""
|
|
424
|
+
Return a normalized version of this array (unit magnitude).
|
|
425
|
+
|
|
426
|
+
:return: The normalized array.
|
|
427
|
+
:raises ValueError: If the array has zero magnitude.
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
mag = self.magnitude()
|
|
431
|
+
if mag == 0:
|
|
432
|
+
raise ValueError("Cannot normalize zero-magnitude array")
|
|
433
|
+
return self / mag
|
|
434
|
+
|
|
435
|
+
def to_numpy(self) -> np.ndarray:
|
|
436
|
+
"""
|
|
437
|
+
Convert to a numpy array (cached).
|
|
438
|
+
|
|
439
|
+
:return: The numpy array.
|
|
440
|
+
"""
|
|
441
|
+
|
|
442
|
+
if self._arr is None:
|
|
443
|
+
self._arr = np.frombuffer(self.data, dtype=np.float32)
|
|
444
|
+
return self._arr
|
|
445
|
+
|
|
446
|
+
def to_list(self) -> list[float]:
|
|
447
|
+
"""
|
|
448
|
+
Convert to a list.
|
|
449
|
+
|
|
450
|
+
:return: The list of values.
|
|
451
|
+
"""
|
|
452
|
+
|
|
453
|
+
return self.to_numpy().tolist()
|
|
454
|
+
|
|
455
|
+
def is_empty(self) -> bool:
|
|
456
|
+
"""
|
|
457
|
+
Check if the array is empty.
|
|
458
|
+
|
|
459
|
+
:return: True if empty, False otherwise.
|
|
460
|
+
"""
|
|
461
|
+
|
|
462
|
+
return len(self.data) == 0
|
|
463
|
+
|
|
464
|
+
def as_bytes(self) -> bytes:
|
|
465
|
+
"""
|
|
466
|
+
Get the raw byte data (alias for data field for Rust compatibility).
|
|
467
|
+
|
|
468
|
+
:return: The raw bytes.
|
|
469
|
+
"""
|
|
470
|
+
|
|
471
|
+
return self.data
|
|
472
|
+
|
|
473
|
+
def get(self, index: int) -> float | None:
|
|
474
|
+
"""
|
|
475
|
+
Get element at index (returns None if out of bounds).
|
|
476
|
+
|
|
477
|
+
:param index: The index.
|
|
478
|
+
:return: The value or None.
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
if index < 0 or index >= len(self):
|
|
482
|
+
return None
|
|
483
|
+
return float(self.to_numpy()[index])
|
|
484
|
+
|
|
485
|
+
def set(self, index: int, value: float) -> bool:
|
|
486
|
+
"""
|
|
487
|
+
Set element at index.
|
|
488
|
+
|
|
489
|
+
:param index: The index.
|
|
490
|
+
:param value: The value to set.
|
|
491
|
+
:return: True if successful, False if out of bounds.
|
|
492
|
+
"""
|
|
493
|
+
|
|
494
|
+
if index < 0 or index >= len(self):
|
|
495
|
+
return False
|
|
496
|
+
arr = self.to_numpy().copy()
|
|
497
|
+
arr[index] = value
|
|
498
|
+
self.data = arr.tobytes()
|
|
499
|
+
self._arr = arr
|
|
500
|
+
return True
|