Skip to content

Commit d849e54

Browse files
authored
Merge pull request #157 from codereport/dev
Port TAKE & DROP (Part 1)
2 parents 0675ed8 + 189bb53 commit d849e54

File tree

4 files changed

+76
-51
lines changed

4 files changed

+76
-51
lines changed

jsrc/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ target_sources(j PRIVATE
7272
verbs/vrep.c
7373
verbs/vs.c
7474
verbs/vsb.c
75-
verbs/vt.c
7675
verbs/vx.c
7776
verbs/vz.c
7877
verbs/monadic/rank.cpp
7978
verbs/monadic/same.cpp
8079
verbs/monadic/shape.cpp
8180
verbs/monadic/tally.cpp
81+
verbs/dyadic/take_drop.cpp
8282
debugging/d.c
8383
debugging/dc.c
8484
debugging/dss.c
Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
/* Copyright 1990-2007, Jsoftware Inc. All rights reserved. */
2-
/* Licensed use only. Any other use is in violation of copyright. */
3-
/* */
4-
/* Verbs: Take and Drop */
51

6-
#include "j.h"
2+
#include <algorithm>
3+
#include <iterator>
4+
5+
#include "array.hpp"
6+
7+
/** @file */
78

89
A
910
jtbehead(J jt, A w) {
@@ -42,12 +43,11 @@ jttk0(J jt, B b, A a, A w) {
4243
return z;
4344
}
4445

45-
static A
46-
jttks(J jt, A a, A w) {
46+
static array
47+
jttks(J jt, array a, array w) { // take_sparse
4748
PROLOG(0092);
48-
A a1, q, x, y, z;
49-
B b, c;
50-
I an, m, r, *s, *u, *v;
49+
array x, y, z;
50+
I an, r, *s, *u, *v;
5151
P *wp, *zp;
5252
an = AN(a);
5353
u = AV(a);
@@ -57,31 +57,37 @@ jttks(J jt, A a, A w) {
5757
v = AS(z);
5858
DO(an, v[i] = ABS(u[i]););
5959
zp = PAV(z);
60-
wp = PAV(w);
60+
wp = PAV(w); // pointer to array values
61+
6162
if (an <= r) {
6263
RZ(a = vec(INT, r, s));
6364
MCISH(AV(a), u, an);
6465
} // vec is not virtual
65-
a1 = SPA(wp, a);
66-
RZ(q = jtpaxis(jt, r, a1));
67-
m = AN(a1);
66+
67+
auto [m, q] = [&] {
68+
array const a1 = SPA(wp, a);
69+
return std::pair{AN(a1), jtpaxis(jt, r, a1)};
70+
} ();
71+
6872
RZ(a = jtfrom(jt, q, a));
6973
u = AV(a);
7074
RZ(y = jtfrom(jt, q, shape(jt, w)));
7175
s = AV(y);
72-
b = 0;
73-
DO(r - m, if (b = u[i + m] != s[i + m]) break;);
74-
c = 0;
75-
DO(m, if (c = u[i] != s[i]) break;);
76+
77+
// TODO: rename b when we figure out what it is doing
78+
auto const b = std::mismatch(u + m, u + r, s + m).first != u + r;
79+
7680
if (b) {
7781
jt->fill = SPA(wp, e);
78-
x = irs2(vec(INT, r - m, m + u), SPA(wp, x), 0L, 1L, -1L, jttake);
82+
x = irs2(vec(INT, r - m, m + u), SPA(wp, x), 0L, 1L, -1L, reinterpret_cast<AF>(jttake));
7983
jt->fill = 0;
8084
RZ(x);
8185
} // fill cannot be virtual
8286
else
8387
x = SPA(wp, x);
84-
if (c) {
88+
89+
// TODO: rename b when we figure out what it is doing
90+
if (auto const c = std::mismatch(u, u + m, s).first != u + m; c) {
8591
A j;
8692
C *xv, *yv;
8793
I d, i, *iv, *jv, k, n, t;
@@ -97,12 +103,22 @@ jttks(J jt, A a, A w) {
97103
yv = CAV(y);
98104
xv = CAV(x);
99105
for (i = 0; i < n; ++i) {
100-
c = 0;
101-
DO(m, t = u[i]; if (c = 0 > t ? iv[i] < t + s[i] : iv[i] >= t) break;);
102-
if (!c) {
106+
107+
// this is std::mismatch3 (or std::zip_find3)
108+
bool cc = 0;
109+
for (int64_t i = 0; i < m; ++i) {
110+
t = u[i];
111+
if (0 > t ? iv[i] < t + s[i] : iv[i] >= t) {
112+
cc = true;
113+
break;
114+
}
115+
}
116+
117+
if (!cc) {
103118
++d;
104119
memcpy(yv, xv, k);
105120
yv += k;
121+
// TODO: use algorithm created above
106122
DO(m, t = u[i]; *jv++ = 0 > t ? iv[i] - (t + s[i]) : iv[i];);
107123
}
108124
iv += m;
@@ -197,7 +213,7 @@ jttake(J jt, A a, A w) {
197213
wf = wr - wcr;
198214
RESETRANK;
199215
if (((af - 1) & (acr - 2)) >= 0) {
200-
s = rank2ex(a, w, UNUSED_VALUE, MIN(acr, 1), wcr, acr, wcr, jttake); // if multiple x values, loop over them
216+
s = rank2ex(a, w, UNUSED_VALUE, MIN(acr, 1), wcr, acr, wcr, reinterpret_cast<AF>(jttake)); // if multiple x values, loop over them
201217
// af>0 or acr>1
202218
// We extracted from w, so mark it (or its backer if virtual) non-pristine. There may be replication (if there
203219
// was fill), so we don't pass pristinity through We overwrite w because it is no longer in use
@@ -212,7 +228,7 @@ jttake(J jt, A a, A w) {
212228
jtvib(jt, a)); // convert input to integer, auditing for illegal values; and convert infinities to IMAX/-IMAX
213229
// if the input was not INT/bool, we go through and replace any infinities with the length of the axis. If we do
214230
// this, we have to clone the area, because vib might return a canned value
215-
if (!(AT(a) & B01 + INT)) {
231+
if (!(AT(a) & (B01 + INT))) {
216232
I i;
217233
for (i = 0; i < AN(s); ++i) {
218234
I m = IAV(s)[i];
@@ -298,7 +314,7 @@ jtdrop(J jt, A a, A w) {
298314
// special case: if a is atomic 0, and cells of w are not atomic
299315
if ((-wcr & (ar - 1)) < 0 && (IAV(a)[0] == 0)) return w; // 0 }. y, return y
300316
if (((af - 1) & (acr - 2)) >= 0) {
301-
s = rank2ex(a, w, UNUSED_VALUE, MIN(acr, 1), wcr, acr, wcr, jtdrop); // if multiple x values, loop over them
317+
s = rank2ex(a, w, UNUSED_VALUE, MIN(acr, 1), wcr, acr, wcr, reinterpret_cast<AF>(jtdrop)); // if multiple x values, loop over them
302318
// af>0 or acr>1
303319
// We extracted from w, so mark it (or its backer if virtual) non-pristine. There may be replication, so we
304320
// don't pass pristinity through We overwrite w because it is no longer in use
@@ -411,7 +427,7 @@ jthead(J jt, A w) {
411427
return jtfrom(jtinplace, zeroionei(0), w); // could call jtfromi directly for non-sparse w
412428
}
413429
} else {
414-
return SPARSE & AT(w) ? irs2(num(0), jttake(jt, num(1), w), 0L, 0L, wcr, jtfrom)
430+
return SPARSE & AT(w) ? irs2(num(0), jttake(jt, num(1), w), 0L, 0L, wcr, reinterpret_cast<AF>(jtfrom))
415431
: jtrsh0(jt, w); // cell of w is empty - create a cell of fills jt->ranks is still set
416432
// for use in take. Left rank is garbage, but that's OK
417433
}
@@ -429,7 +445,7 @@ jttail(J jt, A w) {
429445
return !wcr || AS(w)[wf] ? jtfrom(jtinplace, num(-1), w)
430446
: // if cells are atoms, or if the cells are nonempty arrays, result is last cell(s) scaf
431447
// should generate virtual block here for speed
432-
SPARSE & AT(w) ? irs2(num(0), jttake(jt, num(-1), w), 0L, 0L, wcr, jtfrom)
448+
SPARSE & AT(w) ? irs2(num(0), jttake(jt, num(-1), w), 0L, 0L, wcr, reinterpret_cast<AF>(jtfrom))
433449
: jtrsh0(jt, w);
434450
// pristinity from other verbs
435451
}

learning/LIVESTREAM_LESSONS.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ palindrome =. (-: |.) NB. hook version
4949
* That Travis-CI is not free, you have 10,000 credits which get used per minute per OS
5050
* We learned the following about CI pricing:
5151

52-
| Platform | Free Linux Minutes |
53-
| :------------: | :----------------: |
54-
| Travis CI | 1000 |
55-
| Azure Pipelines| 1800 |
56-
| Github Actions | 2000 |
57-
| Buildkite | Infinity? |
58-
| Appveyor | Infinity? |
52+
| Platform | Free Linux Minutes |
53+
| :-------------: | :----------------: |
54+
| Travis CI | 1000 |
55+
| Azure Pipelines | 1800 |
56+
| Github Actions | 2000 |
57+
| Buildkite | Infinity? |
58+
| Appveyor | Infinity? |
5959

6060
* We learned for some reason macOS is 5-10x more costly when it comes to CI
6161
* ~~We should checkout GitHub actions~~
@@ -119,3 +119,11 @@ Prelude> let innerProduct = blackbird sum (zipWith (*))
119119
* Learned that MicroAPL refers to "tack" as pass (and Dyalog APL refers to it as same)
120120
* Learned about the [P Programming Language](https://github.com/p-org/P)
121121
* Learned for a multi-line J function to use `f =. 3 : 0` or `g =. 4 : 0`
122+
123+
### Livestream #8 2021-02-18
124+
125+
* `x y z | value` is the sparse array view
126+
* We learned `=` has lower precedence that equality comparision in C++
127+
* IRS = Integral/Integrated Rank Support (optimizations for certain verbs - see [this paper](https://www.jsoftware.com/papers/rank.htm))
128+
* Discrovered [Try J](http://tryj.freeddns.org/) site set up by Nathan
129+
* Used our first C++ Standard Algorithm (`std::mismatch` x2)

learning/REFACTORINGS.md

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,28 @@
99

1010
| Rule | Core Guideline | Count |
1111
| :---: | :----------------: | :---: |
12-
| CON.4 | Use `const` | 1 |
12+
| CON.4 | Use `const` | 4 |
1313
| ES.21 | Reduce scope | 3 |
14-
| ES.22 | Decl-Init Split | 2 |
15-
| ES.30 | No Text Macros | 4 |
14+
| ES.22 | Decl-Init Split | 5 |
15+
| ES.30 | No Text Macros | 6 |
1616
| ES.49 | Use explicit casts | 4 |
1717
| E.12 | Use `noexcept` | 3 |
1818

1919
### Refactoring Translations
2020

21-
| From | To |
22-
| :-------------------: | :--------------------------------------------: |
23-
| `A` | `array` |
24-
| `SETIC` 1 | `item_count()` |
25-
| `REPSGN` | `replicate_sign` 2 |
26-
| `AV` | `pointer_to_values` |
27-
| `IAV` | `pointer_to_values` |
28-
| `IAV(w)[i] = k` | `set_value_at(w, i, k)` |
29-
| `k & ~1` | `!zero_or_one(k)` |
30-
| `GAT0(z, TYPE, x, y)` | `z = make_array<TYPE, copy_shape_0>(jt, x, y)` |
31-
| `GA(...)` | `make_array` |
32-
| `sc` | `make_scalar_integer` |
21+
| From | To |
22+
| :-------------------: | :-------------------------------------------------: |
23+
| `A` | `array` |
24+
| `SETIC` 1 | `item_count()` |
25+
| `REPSGN` | `replicate_sign` 2 |
26+
| `AV` | `pointer_to_values` |
27+
| `IAV` | `pointer_to_values` |
28+
| `IAV(w)[i] = k` | `set_value_at(w, i, k)` |
29+
| `k & ~1` | `!zero_or_one(k)` |
30+
| `GAT0(z, TYPE, x, y)` | `z = make_array<TYPE, copy_shape_0>(jt, x, y)` |
31+
| `GA(...)` | `make_array` |
32+
| `sc` | `make_scalar_integer` |
33+
| `DO(m, s)` | `for (int i = 0; i < m; ++i) m` OR `std::algorithm` |
3334

3435
1. There could be exceptions where this doesn't work
3536
2. Will probably be renamed

0 commit comments

Comments
 (0)