Skip to content

state

BoundaryType

Bases: str, Enum

Enumeration of boundary condition types for state variables.

This enum allows users to specify boundary conditions using plain strings while maintaining type safety internally. Boundary conditions control how the optimizer handles initial and final state values.

Attributes:

Name Type Description
FIXED str

State value is fixed to a specific value

FREE str

State value is free to be optimized within bounds

MINIMIZE str

Objective term to minimize the state value

MAXIMIZE str

Objective term to maximize the state value

Example

Can use either enum or string:

BoundaryType.FIXED
"fixed"  # Equivalent
Source code in openscvx/symbolic/expr/state.py
class BoundaryType(str, Enum):
    """Enumeration of boundary condition types for state variables.

    This enum allows users to specify boundary conditions using plain strings
    while maintaining type safety internally. Boundary conditions control how
    the optimizer handles initial and final state values.

    Attributes:
        FIXED (str): State value is fixed to a specific value
        FREE (str): State value is free to be optimized within bounds
        MINIMIZE (str): Objective term to minimize the state value
        MAXIMIZE (str): Objective term to maximize the state value

    Example:
        Can use either enum or string:

            BoundaryType.FIXED
            "fixed"  # Equivalent
    """

    FIXED = "fixed"
    FREE = "free"
    MINIMIZE = "minimize"
    MAXIMIZE = "maximize"

State

Bases: Variable

State variable with boundary conditions for trajectory optimization.

State represents a dynamic state variable in a trajectory optimization problem. Unlike control inputs, states evolve according to dynamics constraints and can have boundary conditions specified at the initial and final time points. Like all Variables, States also support min/max bounds and initial trajectory guesses to help guide the optimization solver toward good solutions.

States support four types of boundary conditions:

  • fixed: State value is constrained to a specific value
  • free: State value is optimized within the specified bounds
  • minimize: Adds a term to the objective function to minimize the state value
  • maximize: Adds a term to the objective function to maximize the state value

Each element of a multi-dimensional state can have different boundary condition types, allowing for fine-grained control over the optimization.

Attributes:

Name Type Description
name str

Unique name identifier for this state variable

_shape tuple[int, ...]

Shape of the state vector (typically 1D like (3,) for 3D position)

_slice slice | None

Internal slice information for variable indexing

_min ndarray | None

Minimum bounds for state variables

_max ndarray | None

Maximum bounds for state variables

_guess ndarray | None

Initial trajectory guess

_initial ndarray | None

Initial state values with boundary condition types

initial_type ndarray | None

Array of boundary condition types for initial state

_final ndarray | None

Final state values with boundary condition types

final_type ndarray | None

Array of boundary condition types for final state

Example

Scalar time state with fixed initial time, minimize final time:

time = State("time", (1,))
time.min = [0.0]
time.max = [10.0]
time.initial = [("fixed", 0.0)]
time.final = [("minimize", 5.0)]

3D position state with mixed boundary conditions:

pos = State("pos", (3,))
pos.min = [0, 0, 10]
pos.max = [10, 10, 200]
pos.initial = [0, ("free", 1), 50]  # x fixed, y free, z fixed
pos.final = [10, ("free", 5), ("maximize", 150)]  # Maximize final altitude
Source code in openscvx/symbolic/expr/state.py
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
class State(Variable):
    """State variable with boundary conditions for trajectory optimization.

    State represents a dynamic state variable in a trajectory optimization problem.
    Unlike control inputs, states evolve according to dynamics constraints and can
    have boundary conditions specified at the initial and final time points.
    Like all Variables, States also support min/max bounds and initial trajectory
    guesses to help guide the optimization solver toward good solutions.

    States support four types of boundary conditions:

    - **fixed**: State value is constrained to a specific value
    - **free**: State value is optimized within the specified bounds
    - **minimize**: Adds a term to the objective function to minimize the state value
    - **maximize**: Adds a term to the objective function to maximize the state value

    Each element of a multi-dimensional state can have different boundary condition
    types, allowing for fine-grained control over the optimization.

    Attributes:
        name (str): Unique name identifier for this state variable
        _shape (tuple[int, ...]): Shape of the state vector (typically 1D like (3,) for 3D position)
        _slice (slice | None): Internal slice information for variable indexing
        _min (np.ndarray | None): Minimum bounds for state variables
        _max (np.ndarray | None): Maximum bounds for state variables
        _guess (np.ndarray | None): Initial trajectory guess
        _initial (np.ndarray | None): Initial state values with boundary condition types
        initial_type (np.ndarray | None): Array of boundary condition types for initial state
        _final (np.ndarray | None): Final state values with boundary condition types
        final_type (np.ndarray | None): Array of boundary condition types for final state

    Example:
        Scalar time state with fixed initial time, minimize final time:

            time = State("time", (1,))
            time.min = [0.0]
            time.max = [10.0]
            time.initial = [("fixed", 0.0)]
            time.final = [("minimize", 5.0)]

        3D position state with mixed boundary conditions:

            pos = State("pos", (3,))
            pos.min = [0, 0, 10]
            pos.max = [10, 10, 200]
            pos.initial = [0, ("free", 1), 50]  # x fixed, y free, z fixed
            pos.final = [10, ("free", 5), ("maximize", 150)]  # Maximize final altitude
    """

    def __init__(self, name, shape):
        """Initialize a State object.

        Args:
            name: Name identifier for the state variable
            shape: Shape of the state vector (typically 1D tuple)
        """
        super().__init__(name, shape)
        self._initial = None
        self.initial_type = None
        self._final = None
        self.final_type = None
        self._scaling_min = None
        self._scaling_max = None

    def _hash_into(self, hasher: "hashlib._Hash") -> None:
        """Hash State including boundary condition types.

        Extends Variable._hash_into to include the structural metadata that
        affects the compiled problem: boundary condition types (fixed, free,
        minimize, maximize). Values are not hashed as they are runtime parameters.

        Args:
            hasher: A hashlib hash object to update
        """
        # Hash the base Variable attributes (class name, shape, slice)
        super()._hash_into(hasher)
        # Hash boundary condition types (these affect constraint structure)
        if self.initial_type is not None:
            hasher.update(b"initial_type:")
            hasher.update(str(self.initial_type.tolist()).encode())
        if self.final_type is not None:
            hasher.update(b"final_type:")
            hasher.update(str(self.final_type.tolist()).encode())

    @property
    def min(self):
        """Get the minimum bounds for the state variables.

        Returns:
            Array of minimum values for each state variable element.

        Example:
            Get lower bounds:

                pos = State("pos", (3,))
                pos.min = [0, 0, 10]
                print(pos.min)  # [0. 0. 10.]
        """
        return self._min

    @min.setter
    def min(self, val):
        """Set the minimum bounds for the state variables.

        Bounds are validated against any fixed initial/final conditions to ensure
        consistency.

        Args:
            val: Array of minimum values, must match the state shape exactly

        Raises:
            ValueError: If the shape doesn't match the state shape, or if fixed
                boundary conditions violate the bounds

        Example:
            Set lower bounds:

                pos = State("pos", (3,))
                pos.min = [0, 0, 10]
                pos.initial = [0, 5, 15]  # Must satisfy: 0>=0, 5>=0, 15>=10
        """
        val = np.asarray(val, dtype=float)
        if val.shape != self.shape:
            raise ValueError(f"Min shape {val.shape} does not match State shape {self.shape}")
        self._min = val
        self._check_bounds_against_initial_final()

    @property
    def max(self):
        """Get the maximum bounds for the state variables.

        Returns:
            Array of maximum values for each state variable element.

        Example:
            Get upper bounds:

                vel = State("vel", (3,))
                vel.max = [10, 10, 5]
                print(vel.max)  # [10. 10. 5.]
        """
        return self._max

    @max.setter
    def max(self, val):
        """Set the maximum bounds for the state variables.

        Bounds are validated against any fixed initial/final conditions to ensure
        consistency.

        Args:
            val: Array of maximum values, must match the state shape exactly

        Raises:
            ValueError: If the shape doesn't match the state shape, or if fixed
                boundary conditions violate the bounds

        Example:
            Set upper bounds:

                vel = State("vel", (3,))
                vel.max = [10, 10, 5]
                vel.final = [8, 9, 4]  # Must satisfy: 8<=10, 9<=10, 4<=5
        """
        val = np.asarray(val, dtype=float)
        if val.shape != self.shape:
            raise ValueError(f"Max shape {val.shape} does not match State shape {self.shape}")
        self._max = val
        self._check_bounds_against_initial_final()

    def _check_bounds_against_initial_final(self):
        """Validate that fixed boundary conditions respect min/max bounds.

        This internal method is automatically called when bounds or boundary
        conditions are set to ensure consistency.

        Raises:
            ValueError: If any fixed initial or final value violates the min/max bounds
        """
        for field_name, data, types in [
            ("initial", self._initial, self.initial_type),
            ("final", self._final, self.final_type),
        ]:
            if data is None or types is None:
                continue
            for i, val in np.ndenumerate(data):
                if types[i] != "Fix":
                    continue
                min_i = self._min[i] if self._min is not None else -np.inf
                max_i = self._max[i] if self._max is not None else np.inf
                if val < min_i:
                    raise ValueError(
                        f"{field_name.capitalize()} Fixed value at index {i[0]} is lower then the "
                        f"min: {val} < {min_i}"
                    )
                if val > max_i:
                    raise ValueError(
                        f"{field_name.capitalize()} Fixed value at index {i[0]} is greater then "
                        f"the max: {val} > {max_i}"
                    )

    @property
    def initial(self):
        """Get the initial state boundary condition values.

        Returns:
            Array of initial state values (regardless of boundary condition type),
            or None if not set.

        Note:
            Use `initial_type` to see the boundary condition types for each element.

        Example:
            Get initial state boundary conditions:

                x = State("x", (2,))
                x.initial = [0, ("free", 1)]
                print(x.initial)  # [0. 1.]
                print(x.initial_type)  # ['Fix' 'Free']
        """
        return self._initial

    @initial.setter
    def initial(self, arr):
        """Set the initial state boundary conditions.

        Each element can be specified as either a simple number (defaults to "fixed")
        or a tuple of (type, value) where type specifies the boundary condition.

        Args:
            arr: Array-like of initial conditions. Each element can be:
                - A number: Defaults to fixed boundary condition at that value
                - A tuple (type, value): Where type is one of:
                    - "fixed": Constrain state to this exact value
                    - "free": Let optimizer choose within bounds, initialize at value
                    - "minimize": Add objective term to minimize, initialize at value
                    - "maximize": Add objective term to maximize, initialize at value

        Raises:
            ValueError: If the shape doesn't match the state shape, if boundary
                condition type is invalid, or if fixed values violate bounds

        Example:
            Set initial state boundary conditions:

                pos = State("pos", (3,))
                pos.min = [0, 0, 0]
                pos.max = [10, 10, 10]
                # x fixed at 0, y free (starts at 5), z fixed at 2
                pos.initial = [0, ("free", 5), 2]

            Can also minimize/maximize boundary values:

                time = State("t", (1,))
                time.initial = [("minimize", 0)]  # Minimize initial time
        """
        # Convert to list first to handle mixed types properly
        if not isinstance(arr, (list, tuple)):
            arr = np.asarray(arr)
            if arr.shape != self.shape:
                raise ValueError(f"Shape mismatch: {arr.shape} != {self.shape}")
            arr = arr.tolist()

        # Ensure we have the right number of elements
        if len(arr) != self.shape[0]:
            raise ValueError(f"Length mismatch: got {len(arr)} elements, expected {self.shape[0]}")

        self._initial = np.zeros(self.shape, dtype=float)
        self.initial_type = np.full(self.shape, "Fix", dtype=object)

        for i, v in enumerate(arr):
            if isinstance(v, tuple) and len(v) == 2:
                # Tuple API: (type, value)
                bc_type_str, bc_value = v
                try:
                    bc_type = BoundaryType(bc_type_str)  # Validates the string
                except ValueError:
                    valid_types = [t.value for t in BoundaryType]
                    raise ValueError(
                        f"Invalid boundary condition type: {bc_type_str}. "
                        f"Valid types are: {valid_types}"
                    )
                self._initial[i] = float(bc_value)
                self.initial_type[i] = bc_type.value.capitalize()
            elif isinstance(v, (int, float, np.number)):
                # Simple number defaults to fixed
                self._initial[i] = float(v)
                self.initial_type[i] = "Fix"
            else:
                raise ValueError(
                    f"Invalid boundary condition format: {v}. "
                    f"Use a number (defaults to fixed) or tuple ('type', value) "
                    f"where type is 'fixed', 'free', 'minimize', or 'maximize'."
                )

        self._check_bounds_against_initial_final()

    @property
    def final(self):
        """Get the final state boundary condition values.

        Returns:
            Array of final state values (regardless of boundary condition type),
            or None if not set.

        Note:
            Use `final_type` to see the boundary condition types for each element.

        Example:
            Get final state boundary conditions:

                x = State("x", (2,))
                x.final = [10, ("minimize", 0)]
                print(x.final)  # [10. 0.]
                print(x.final_type)  # ['Fix' 'Minimize']
        """
        return self._final

    @final.setter
    def final(self, arr):
        """Set the final state boundary conditions.

        Each element can be specified as either a simple number (defaults to "fixed")
        or a tuple of (type, value) where type specifies the boundary condition.

        Args:
            arr: Array-like of final conditions. Each element can be:
                - A number: Defaults to fixed boundary condition at that value
                - A tuple (type, value): Where type is one of:
                    - "fixed": Constrain state to this exact value
                    - "free": Let optimizer choose within bounds, initialize at value
                    - "minimize": Add objective term to minimize, initialize at value
                    - "maximize": Add objective term to maximize, initialize at value

        Raises:
            ValueError: If the shape doesn't match the state shape, if boundary
                condition type is invalid, or if fixed values violate bounds

        Example:
            Set final state boundary conditionis:

                pos = State("pos", (3,))
                pos.min = [0, 0, 0]
                pos.max = [10, 10, 10]
                # x fixed at 10, y free (starts at 5), z maximize altitude
                pos.final = [10, ("free", 5), ("maximize", 8)]

            Minimize final time in time-optimal problem:

                time = State("t", (1,))
                time.final = [("minimize", 10)]
        """
        # Convert to list first to handle mixed types properly
        if not isinstance(arr, (list, tuple)):
            arr = np.asarray(arr)
            if arr.shape != self.shape:
                raise ValueError(f"Shape mismatch: {arr.shape} != {self.shape}")
            arr = arr.tolist()

        # Ensure we have the right number of elements
        if len(arr) != self.shape[0]:
            raise ValueError(f"Length mismatch: got {len(arr)} elements, expected {self.shape[0]}")

        self._final = np.zeros(self.shape, dtype=float)
        self.final_type = np.full(self.shape, "Fix", dtype=object)

        for i, v in enumerate(arr):
            if isinstance(v, tuple) and len(v) == 2:
                # Tuple API: (type, value)
                bc_type_str, bc_value = v
                try:
                    bc_type = BoundaryType(bc_type_str)  # Validates the string
                except ValueError:
                    valid_types = [t.value for t in BoundaryType]
                    raise ValueError(
                        f"Invalid boundary condition type: {bc_type_str}. "
                        f"Valid types are: {valid_types}"
                    )
                self._final[i] = float(bc_value)
                self.final_type[i] = bc_type.value.capitalize()
            elif isinstance(v, (int, float, np.number)):
                # Simple number defaults to fixed
                self._final[i] = float(v)
                self.final_type[i] = "Fix"
            else:
                raise ValueError(
                    f"Invalid boundary condition format: {v}. "
                    f"Use a number (defaults to fixed) or tuple ('type', value) "
                    f"where type is 'fixed', 'free', 'minimize', or 'maximize'."
                )

        self._check_bounds_against_initial_final()

    @property
    def scaling_min(self):
        """Get the scaling minimum bounds for the state variables.

        Returns:
            Array of scaling minimum values for each state variable element, or None if not set.
        """
        return self._scaling_min

    @scaling_min.setter
    def scaling_min(self, val):
        """Set the scaling minimum bounds for the state variables.

        Args:
            val: Array of scaling minimum values, must match the state shape exactly

        Raises:
            ValueError: If the shape doesn't match the state shape
        """
        if val is None:
            self._scaling_min = None
            return
        val = np.asarray(val, dtype=float)
        if val.shape != self.shape:
            raise ValueError(
                f"Scaling min shape {val.shape} does not match State shape {self.shape}"
            )
        self._scaling_min = val

    @property
    def scaling_max(self):
        """Get the scaling maximum bounds for the state variables.

        Returns:
            Array of scaling maximum values for each state variable element, or None if not set.
        """
        return self._scaling_max

    @scaling_max.setter
    def scaling_max(self, val):
        """Set the scaling maximum bounds for the state variables.

        Args:
            val: Array of scaling maximum values, must match the state shape exactly

        Raises:
            ValueError: If the shape doesn't match the state shape
        """
        if val is None:
            self._scaling_max = None
            return
        val = np.asarray(val, dtype=float)
        if val.shape != self.shape:
            raise ValueError(
                f"Scaling max shape {val.shape} does not match State shape {self.shape}"
            )
        self._scaling_max = val

    def __repr__(self):
        """String representation of the State object.

        Returns:
            Concise string showing the state name and shape.
        """
        return f"State('{self.name}', shape={self.shape})"
final property writable

Get the final state boundary condition values.

Returns:

Type Description

Array of final state values (regardless of boundary condition type),

or None if not set.

Note

Use final_type to see the boundary condition types for each element.

Example

Get final state boundary conditions:

x = State("x", (2,))
x.final = [10, ("minimize", 0)]
print(x.final)  # [10. 0.]
print(x.final_type)  # ['Fix' 'Minimize']
initial property writable

Get the initial state boundary condition values.

Returns:

Type Description

Array of initial state values (regardless of boundary condition type),

or None if not set.

Note

Use initial_type to see the boundary condition types for each element.

Example

Get initial state boundary conditions:

x = State("x", (2,))
x.initial = [0, ("free", 1)]
print(x.initial)  # [0. 1.]
print(x.initial_type)  # ['Fix' 'Free']
max property writable

Get the maximum bounds for the state variables.

Returns:

Type Description

Array of maximum values for each state variable element.

Example

Get upper bounds:

vel = State("vel", (3,))
vel.max = [10, 10, 5]
print(vel.max)  # [10. 10. 5.]
min property writable

Get the minimum bounds for the state variables.

Returns:

Type Description

Array of minimum values for each state variable element.

Example

Get lower bounds:

pos = State("pos", (3,))
pos.min = [0, 0, 10]
print(pos.min)  # [0. 0. 10.]
scaling_max property writable

Get the scaling maximum bounds for the state variables.

Returns:

Type Description

Array of scaling maximum values for each state variable element, or None if not set.

scaling_min property writable

Get the scaling minimum bounds for the state variables.

Returns:

Type Description

Array of scaling minimum values for each state variable element, or None if not set.

_check_bounds_against_initial_final()

Validate that fixed boundary conditions respect min/max bounds.

This internal method is automatically called when bounds or boundary conditions are set to ensure consistency.

Raises:

Type Description
ValueError

If any fixed initial or final value violates the min/max bounds

Source code in openscvx/symbolic/expr/state.py
def _check_bounds_against_initial_final(self):
    """Validate that fixed boundary conditions respect min/max bounds.

    This internal method is automatically called when bounds or boundary
    conditions are set to ensure consistency.

    Raises:
        ValueError: If any fixed initial or final value violates the min/max bounds
    """
    for field_name, data, types in [
        ("initial", self._initial, self.initial_type),
        ("final", self._final, self.final_type),
    ]:
        if data is None or types is None:
            continue
        for i, val in np.ndenumerate(data):
            if types[i] != "Fix":
                continue
            min_i = self._min[i] if self._min is not None else -np.inf
            max_i = self._max[i] if self._max is not None else np.inf
            if val < min_i:
                raise ValueError(
                    f"{field_name.capitalize()} Fixed value at index {i[0]} is lower then the "
                    f"min: {val} < {min_i}"
                )
            if val > max_i:
                raise ValueError(
                    f"{field_name.capitalize()} Fixed value at index {i[0]} is greater then "
                    f"the max: {val} > {max_i}"
                )
_hash_into(hasher: hashlib._Hash) -> None

Hash State including boundary condition types.

Extends Variable._hash_into to include the structural metadata that affects the compiled problem: boundary condition types (fixed, free, minimize, maximize). Values are not hashed as they are runtime parameters.

Parameters:

Name Type Description Default
hasher _Hash

A hashlib hash object to update

required
Source code in openscvx/symbolic/expr/state.py
def _hash_into(self, hasher: "hashlib._Hash") -> None:
    """Hash State including boundary condition types.

    Extends Variable._hash_into to include the structural metadata that
    affects the compiled problem: boundary condition types (fixed, free,
    minimize, maximize). Values are not hashed as they are runtime parameters.

    Args:
        hasher: A hashlib hash object to update
    """
    # Hash the base Variable attributes (class name, shape, slice)
    super()._hash_into(hasher)
    # Hash boundary condition types (these affect constraint structure)
    if self.initial_type is not None:
        hasher.update(b"initial_type:")
        hasher.update(str(self.initial_type.tolist()).encode())
    if self.final_type is not None:
        hasher.update(b"final_type:")
        hasher.update(str(self.final_type.tolist()).encode())

Fixed(value)

Create a fixed boundary condition tuple.

This is a convenience function that returns a tuple ("fixed", value) which can be used to explicitly specify fixed boundary conditions for State or Time objects. Note that plain numbers default to fixed, so this is mainly for clarity.

Parameters:

Name Type Description Default
value

Fixed value for the boundary condition.

required

Returns:

Name Type Description
tuple

("fixed", value) tuple suitable for use in State.initial, State.final, or Time.initial, Time.final.

Example
pos = ox.State("pos", (3,))
pos.final = [ox.Fixed(10.0), ox.Free(5.0), ox.Fixed(2.0)]

# Equivalent to:
pos.final = [10.0, ox.Free(5.0), 2.0]  # Plain numbers default to fixed
Source code in openscvx/symbolic/expr/state.py
def Fixed(value):
    """Create a fixed boundary condition tuple.

    This is a convenience function that returns a tuple ("fixed", value) which
    can be used to explicitly specify fixed boundary conditions for State or Time objects.
    Note that plain numbers default to fixed, so this is mainly for clarity.

    Args:
        value: Fixed value for the boundary condition.

    Returns:
        tuple: ("fixed", value) tuple suitable for use in State.initial, State.final,
            or Time.initial, Time.final.

    Example:
        ```python
        pos = ox.State("pos", (3,))
        pos.final = [ox.Fixed(10.0), ox.Free(5.0), ox.Fixed(2.0)]

        # Equivalent to:
        pos.final = [10.0, ox.Free(5.0), 2.0]  # Plain numbers default to fixed
        ```
    """
    return ("fixed", value)

Free(guess)

Create a free boundary condition tuple.

This is a convenience function that returns a tuple ("free", guess) which can be used to specify free boundary conditions for State or Time objects.

Parameters:

Name Type Description Default
guess

Initial guess value for the free variable.

required

Returns:

Name Type Description
tuple

("free", guess) tuple suitable for use in State.initial, State.final, or Time.initial, Time.final.

Example
pos = ox.State("pos", (3,))
pos.final = [ox.Free(5.0), ox.Free(3.0), 10]  # First two free, third fixed

time = ox.Time(
    initial=0.0,
    final=ox.Free(10.0),
    min=0.0,
    max=20.0
)
Source code in openscvx/symbolic/expr/state.py
def Free(guess):
    """Create a free boundary condition tuple.

    This is a convenience function that returns a tuple ("free", guess) which
    can be used to specify free boundary conditions for State or Time objects.

    Args:
        guess: Initial guess value for the free variable.

    Returns:
        tuple: ("free", guess) tuple suitable for use in State.initial, State.final,
            or Time.initial, Time.final.

    Example:
        ```python
        pos = ox.State("pos", (3,))
        pos.final = [ox.Free(5.0), ox.Free(3.0), 10]  # First two free, third fixed

        time = ox.Time(
            initial=0.0,
            final=ox.Free(10.0),
            min=0.0,
            max=20.0
        )
        ```
    """
    return ("free", guess)

Maximize(guess)

Create a maximize boundary condition tuple.

This is a convenience function that returns a tuple ("maximize", guess) which can be used to specify that a boundary value should be maximized in the objective function for State or Time objects.

Parameters:

Name Type Description Default
guess

Initial guess value for the variable to be maximized.

required

Returns:

Name Type Description
tuple

("maximize", guess) tuple suitable for use in State.initial, State.final, or Time.initial, Time.final.

Example
altitude = ox.State("altitude", (1,))
altitude.final = [ox.Maximize(100.0)]  # Maximize final altitude

time = ox.Time(
    initial=ox.Maximize(0.0),  # Maximize initial time
    final=10.0,
    min=0.0,
    max=20.0
)
Source code in openscvx/symbolic/expr/state.py
def Maximize(guess):
    """Create a maximize boundary condition tuple.

    This is a convenience function that returns a tuple ("maximize", guess) which
    can be used to specify that a boundary value should be maximized in the objective
    function for State or Time objects.

    Args:
        guess: Initial guess value for the variable to be maximized.

    Returns:
        tuple: ("maximize", guess) tuple suitable for use in State.initial, State.final,
            or Time.initial, Time.final.

    Example:
        ```python
        altitude = ox.State("altitude", (1,))
        altitude.final = [ox.Maximize(100.0)]  # Maximize final altitude

        time = ox.Time(
            initial=ox.Maximize(0.0),  # Maximize initial time
            final=10.0,
            min=0.0,
            max=20.0
        )
        ```
    """
    return ("maximize", guess)

Minimize(guess)

Create a minimize boundary condition tuple.

This is a convenience function that returns a tuple ("minimize", guess) which can be used to specify that a boundary value should be minimized in the objective function for State or Time objects.

Parameters:

Name Type Description Default
guess

Initial guess value for the variable to be minimized.

required

Returns:

Name Type Description
tuple

("minimize", guess) tuple suitable for use in State.initial, State.final, or Time.initial, Time.final.

Example
time = ox.Time(
    initial=0.0,
    final=ox.Minimize(10.0),  # Minimize final time
    min=0.0,
    max=20.0
)

fuel = ox.State("fuel", (1,))
fuel.final = [ox.Minimize(0)]  # Minimize final fuel consumption
Source code in openscvx/symbolic/expr/state.py
def Minimize(guess):
    """Create a minimize boundary condition tuple.

    This is a convenience function that returns a tuple ("minimize", guess) which
    can be used to specify that a boundary value should be minimized in the objective
    function for State or Time objects.

    Args:
        guess: Initial guess value for the variable to be minimized.

    Returns:
        tuple: ("minimize", guess) tuple suitable for use in State.initial, State.final,
            or Time.initial, Time.final.

    Example:
        ```python
        time = ox.Time(
            initial=0.0,
            final=ox.Minimize(10.0),  # Minimize final time
            min=0.0,
            max=20.0
        )

        fuel = ox.State("fuel", (1,))
        fuel.final = [ox.Minimize(0)]  # Minimize final fuel consumption
        ```
    """
    return ("minimize", guess)