Class: Matrix Private

Inherits:
Object show all
Defined in:
lib/musa-dsl/matrix/matrix.rb,
lib/musa-dsl/matrix/matrix.rb,
lib/musa-dsl/matrix/matrix.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

TODO:

POTENTIAL LOGIC INCONSISTENCY: Review the direction logic in backward and forward scans.

  • Line 300 comment: "Scan backward... while time is non-decreasing"
  • Line 306 code: while i >= 0 && array[i][time_dimension] >= xx
  • Line 316 comment: "Scan forward... while time is non-decreasing"
  • Line 322 code: while i < array.size && array[i][time_dimension] >= xx Both scans use >= xx, which seems contradictory. When scanning backward (decreasing indices), for "non-decreasing time" we might expect <= xx (times getting smaller or equal as we go back in indices). Currently both directions use the same comparison operator. IMPLEMENT TESTS to verify expected behavior with various input patterns and confirm whether this is intentional or a bug. Test cases should include:
  • Forward-only monotonic sequences
  • Backward-only monotonic sequences
  • Mixed direction sequences
  • The example documented above

Decomposes an array of points into directional segments based on a time dimension.

This private method analyzes the array to find monotonic (non-decreasing) sequences in the specified time dimension. It scans bidirectionally from each point to discover maximal segments where time progresses consistently.

The algorithm:

  1. Groups points by their time values
  2. Iterates through time values in sorted order
  3. For each unprocessed index, scans backward and forward
  4. Collects points while time is non-decreasing
  5. Returns segments with 2+ points

Examples:

# Points with time in dimension 0
points = [[0, 10], [1, 20], [0.5, 15], [2, 30]]
decompose(points, 0)
# => [[[1, 20], [0.5, 15], [0, 10]], [[0, 10], [0.5, 15], [1, 20], [2, 30]]]
# Two segments: one going backward in time, one forward

Returns:

  • (Array<Array<Array>>)

    array of directional segments, each segment being an array of points.

Instance Method Summary collapse

Instance Method Details

#_rowsArray<Array>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

This method is added to Matrix via refinement. Requires using Musa::Extension::Matrix.

Note:

This method accesses Ruby's Matrix internals and should be used with caution.

Provides direct access to the internal rows array of the matrix.

This is a utility method used primarily by Array#condensed_matrices to manipulate matrix rows when merging matrices with shared boundaries.

Returns:

  • (Array<Array>)

    the internal @rows instance variable.



269
# File 'lib/musa-dsl/matrix/matrix.rb', line 269

class ::Matrix; end

#decompose(array, time_dimension) ⇒ Array<Array<Array>>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TODO:

POTENTIAL LOGIC INCONSISTENCY: Review the direction logic in backward and forward scans.

  • Line 300 comment: "Scan backward... while time is non-decreasing"
  • Line 306 code: while i >= 0 && array[i][time_dimension] >= xx
  • Line 316 comment: "Scan forward... while time is non-decreasing"
  • Line 322 code: while i < array.size && array[i][time_dimension] >= xx Both scans use >= xx, which seems contradictory. When scanning backward (decreasing indices), for "non-decreasing time" we might expect <= xx (times getting smaller or equal as we go back in indices). Currently both directions use the same comparison operator. IMPLEMENT TESTS to verify expected behavior with various input patterns and confirm whether this is intentional or a bug. Test cases should include:
  • Forward-only monotonic sequences
  • Backward-only monotonic sequences
  • Mixed direction sequences
  • The example documented above

Decomposes an array of points into directional segments based on a time dimension.

This private method analyzes the array to find monotonic (non-decreasing) sequences in the specified time dimension. It scans bidirectionally from each point to discover maximal segments where time progresses consistently.

The algorithm:

  1. Groups points by their time values
  2. Iterates through time values in sorted order
  3. For each unprocessed index, scans backward and forward
  4. Collects points while time is non-decreasing
  5. Returns segments with 2+ points

Examples:

# Points with time in dimension 0
points = [[0, 10], [1, 20], [0.5, 15], [2, 30]]
decompose(points, 0)
# => [[[1, 20], [0.5, 15], [0, 10]], [[0, 10], [0.5, 15], [1, 20], [2, 30]]]
# Two segments: one going backward in time, one forward

Parameters:

  • array (Array<Array>)

    array of point arrays (each point is an array of coordinates).

  • time_dimension (Integer)

    index of the dimension representing time.

Returns:

  • (Array<Array<Array>>)

    array of directional segments, each segment being an array of points.



316
# File 'lib/musa-dsl/matrix/matrix.rb', line 316

class ::Matrix; end

#to_p(time_dimension: , keep_time: nil) ⇒ Array<Musa::Datasets::P>

Note:

This method is added to Matrix via refinement. Requires using Musa::Extension::Matrix.

Converts a matrix to one or more P (point sequence) representations.

This method decomposes the matrix into directional segments based on the time dimension, then converts each segment into a P sequence format suitable for representing musical gestures in Musa DSL.

A P sequence is an array extended with the P module, containing alternating value arrays (extended with V module) and numeric time deltas: [value1, delta1, value2, delta2, ..., valueN].extend(P) where each value is an array extended with V module.

The decomposition process identifies monotonic segments in the time dimension, handling cases where the temporal ordering might have reversals or non-linearities.

Examples:

Basic conversion

using Musa::Extension::Matrix
matrix = Matrix[[0, 60], [1, 62], [2, 64]]
result = matrix.to_p(time_dimension: 0)
# => Array with one P object:
#    [[60], 1, [62], 1, [64]].extend(P)
# Each value like [60] is extended with V module

Keeping time dimension

using Musa::Extension::Matrix
matrix = Matrix[[0, 60, 100], [1, 62, 110], [2, 64, 120]]
result = matrix.to_p(time_dimension: 0, keep_time: true)
# => Array with one P object:
#    [[0, 60, 100], 1, [1, 62, 110], 1, [2, 64, 120]].extend(P)
# Time dimension kept in each value array

Parameters:

  • time_dimension (Integer) (defaults to: )

    index of the dimension representing time (typically 0).

  • keep_time (Boolean, nil) (defaults to: nil)

    if true, the time dimension is preserved in each point; if false/nil, it's removed and used only for computing deltas.

Returns:

See Also:



255
# File 'lib/musa-dsl/matrix/matrix.rb', line 255

class ::Matrix; end