Skip to content

Commit

Permalink
tweaked hyperDyadic() to zip matching atoms based on comparing their …
Browse files Browse the repository at this point in the history
…dimensions backwards (as in NumPy)
  • Loading branch information
jmoenig committed Jan 3, 2024
1 parent 24b2391 commit 13eef2d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 50 deletions.
2 changes: 2 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## in development:
* **Notable Changes:**
* hyperized ITEM OF
* tweaked hyperDyadic() to zip matching atoms based on comparing their dimensions backwards (as in NumPy)
* **Notable Fixes:**
* fixed a RESHAPE edge case when passing in a single zero dimension
* made sure ITEM OF returns data matching the shape specified by the query struct
Expand All @@ -13,6 +14,7 @@
* lists: made sure ITEM OF returns data matching the shape specified by the query struct
* lists: hyperized ITEM OF
* threads: refactored reportRank()
* threads: tweaked hyperDyadic() to zip matching atoms based on comparing their dimensions backwards (as in NumPy)

## 9.1.1:
* **Notable Fixes:**
Expand Down
71 changes: 21 additions & 50 deletions src/threads.js
Original file line number Diff line number Diff line change
Expand Up @@ -4507,62 +4507,33 @@ Process.prototype.hyperMonadic = function (baseOp, arg) {
return baseOp(arg);
};

Process.prototype.hyperDyadic = function (baseOp, a, b, atoma, atomb) {
Process.prototype.hyperDyadic = function (baseOp, a, b, atoma = 0, atomb = 0) {
// enable dyadic operations to be performed on lists and tables
// atoma and atomb are optional monadic callback predicates indicating
// whether a or b are to be treated as scalar atoms despite being
// atoma and atomb are optional integers indicating the rank at which
// a or b are to be treated as scalar atoms despite being
// lists. This is currenly used for treating 2-item numerical lists as
// atomic points of x-/y-coordinates in some primitives.
var len, i, result;
if (this.isMatrix(a)) {
if (this.isMatrix(b)) {
// zip both arguments ignoring out-of-bounds indices
a = a.itemsArray();
b = b.itemsArray();
len = Math.min(a.length, b.length);
result = new Array(len);
for (i = 0; i < len; i += 1) {
result[i] = this.hyperDyadic(baseOp, a[i], b[i], atoma, atomb);
}
return new List(result);
}
return a.map(each => this.hyperDyadic(baseOp, each, b, atoma, atomb));
}
if (this.isMatrix(b)) {
return b.map(each => this.hyperDyadic(baseOp, a, each, atoma, atomb));
}
return this.hyperZip(baseOp, a, b, atoma, atomb);
};

Process.prototype.hyperZip = function (baseOp, a, b, atoma, atomb) {
// enable dyadic operations to be performed on lists and tables
// atoma and atomb are optional monadic callback predicates indicating
// whether a or b are to be treated as scalar atoms despite being
// lists. This is currenly used for treating 2-item numerical lists as
// atomic points of x-/y-coordinates in some primitives.
var len, i, result;
if (!(atoma && atoma(a)) && a instanceof List) {
if (!(atomb && atomb(b)) && b instanceof List) {
// zip both arguments ignoring out-of-bounds indices
a = a.itemsArray();
b = b.itemsArray();
len = Math.min(a.length, b.length);
result = new Array(len);
for (i = 0; i < len; i += 1) {
result[i] = this.hyperZip(baseOp, a[i], b[i], atoma, atomb);
}
return new List(result);
var arank = this.reportRank(a),
brank = this.reportRank(b),
len, i, result;
if (arank === brank || (arank <= atoma && brank <= atomb)) {
if (arank + brank === 0) {
return baseOp(a, b);
}
// zip both arguments ignoring out-of-bounds indices
a = a.itemsArray();
b = b.itemsArray();
len = Math.min(a.length, b.length);
result = new Array(len);
for (i = 0; i < len; i += 1) {
result[i] = this.hyperDyadic(baseOp, a[i], b[i], atoma, atomb);
}
return a.map(each => this.hyperZip(baseOp, each, b, atoma, atomb));
return new List(result);
}
if (!(atomb && atomb(b)) && b instanceof List) {
return b.map(each => this.hyperZip(baseOp, a, each, atoma, atomb));
if (arank > brank || brank <= atomb) {
return a.map(each => this.hyperDyadic(baseOp, each, b, atoma, atomb));
}
return baseOp(a, b);
};

Process.prototype.isMatrix = function (data) {
return data instanceof List && data.at(1) instanceof List;
return b.map(each => this.hyperDyadic(baseOp, a, each, atoma, atomb));
};

// Process dyadic math primtives - arithmetic
Expand Down

0 comments on commit 13eef2d

Please sign in to comment.