Skip to content

Conversation

@gwhitney
Copy link
Collaborator

This is a work-in-progress, proof-of-concept PR that allows one to calculate e.g. the 10th rising factorial of bignumber 8.5 by math.prod(math.range(math.bignumber(8.5), math.bignumber(19.5)). The major highlights include:

  • Making Range an implementation of Matrix. (This change breaks important ground to pave the way for alternate Matrix implementations besides DenseMatrix and SparseMatrix, given that there have been discussions of flat matrices and ones based on JavaScript's type arrays.)

  • Allowing Range to encode arbitrary arithmetic progressions of arbitrary mathjs entities.

  • Complete reimplementation of prod.

  • Several indexing extensions, and addition of new scalarDivide(V, W), one(x), and zero(x) methods.

In addition, there is a significant reduction in the number of failing doc example tests.

This PR is being submitted for feedback on the approach and scope. It needs at least extensive addition of tests and documentation before being merge-ready.

  With this commit, Range is now a full-fledged implementation of Matrix,
  representing an arbitrary arithmetic sequence (of any type supported
  by mathjs) in a "lazy" way, i.e. its entries are generated on demand.
  (Thus, even infinite Ranges are supported.)

  Note that Range therefore has many new dependencies, and the `matrix()`
  convertor/constructor function must be able to create Ranges. Therefore,
  to avoid a circular dependency on `matrix`, many mathjs methods have
  their dependence on `matrix()` removed. Often this dependence was
  very superficial, and removing it was essentially trivial; in all other
  cases, the dependence could be shifted to DenseMatrix rather than matrix,
  removing the possibility of circularity.

  In addition, as it seemed very confusing (almost to the point of a bug)
  that `math.parse('2:5')` produced a representation of 2, 3, 4, 5 while
  `Range.parse('2:5')` produced a representation of 2, 3, 4. Therefore, this
  commit changes the interpretation so that both `parse` command include the
  endpoint.

  Finally, this commit fixes the remaining doc examples tests in the
  src/type directory.
…et()

  * A single number is now interpreted as the entire "layer" at that position;
    adds `layer` method to Matrix for efficient support of this convention.
  * An array is just passed to index
  * A string form of a Range is now allowed in the index; the lower and upper
    limits may be elided, allowing `':'` as a wildcard for an entire dimension.
  * Also removes unnecessary dependence of set functions on Index.
  * Now passes all doc example testing for `subset`
  The prod function now first reduces its argument to a 1d
  vector, then uses binary splitting without allocating any new matrices
  or arrays.

  Also implements the previously unimplemented second "dimension"
  argument to prod (albeit not as efficiently).

  As these changes added new dependencies to `prod`, some other minor
  refactors were necessary to avoid circular dependencies and/or keep
  unwanted dependencies from the number bundle.

  Also fixes a couple more instances of doc example tests.
@gwhitney
Copy link
Collaborator Author

The most "controversial" change in this PR is that I couldn't wrap my mind around the following: previously, if you took the exact same string, say '2:5', and passed it through either math.parse() or Range.parse(), you got different results -- the former included 5 and the latter did not. That was just so confusing, since both functions were called "parse", that I changed it, so that they both include 5. That change does make this a breaking PR.

On the other hand, I left math.range('2:5') to not include the 5 because (a) it doesn't say it is "parsing" the string, it's just a function argument, (b) that way it matches math.range(2, 5), and (c) there is already a final boolean argument includeEnd to math.range that gives you explicit control over whether the 5 ends up in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant