Skip to content

Commit 832c14e

Browse files
authored
Merge pull request #2930 from finos/quartiles
Quartiles
2 parents 7ce0150 + 7c9dc45 commit 832c14e

File tree

16 files changed

+1570
-1160
lines changed

16 files changed

+1570
-1160
lines changed

cpp/perspective/src/cpp/aggspec.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ t_aggspec::agg_str() const {
143143
case AGGTYPE_ANY: {
144144
return "any";
145145
} break;
146+
case AGGTYPE_Q1: {
147+
return "q1";
148+
} break;
149+
case AGGTYPE_Q3: {
150+
return "q3";
151+
} break;
146152
case AGGTYPE_MEDIAN: {
147153
return "median";
148154
} break;
@@ -343,6 +349,8 @@ t_aggspec::get_output_specs(const t_schema& schema) const {
343349
case AGGTYPE_ANY:
344350
case AGGTYPE_UNIQUE:
345351
case AGGTYPE_DOMINANT:
352+
case AGGTYPE_Q1:
353+
case AGGTYPE_Q3:
346354
case AGGTYPE_MEDIAN:
347355
case AGGTYPE_FIRST:
348356
case AGGTYPE_LAST_BY_INDEX:

cpp/perspective/src/cpp/base.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,12 @@ str_to_aggtype(const std::string& str) {
489489
if (str == "any") {
490490
return t_aggtype::AGGTYPE_ANY;
491491
}
492+
if (str == "q1") {
493+
return t_aggtype::AGGTYPE_Q1;
494+
}
495+
if (str == "q3") {
496+
return t_aggtype::AGGTYPE_Q3;
497+
}
492498
if (str == "median") {
493499
return t_aggtype::AGGTYPE_MEDIAN;
494500
}

cpp/perspective/src/cpp/config.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ t_config::setup(
213213
case AGGTYPE_MEAN:
214214
case AGGTYPE_WEIGHTED_MEAN:
215215
case AGGTYPE_UNIQUE:
216+
case AGGTYPE_Q1:
217+
case AGGTYPE_Q3:
216218
case AGGTYPE_MEDIAN:
217219
case AGGTYPE_JOIN:
218220
case AGGTYPE_DOMINANT:

cpp/perspective/src/cpp/extract_aggregate.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ extract_aggregate(
5959
case AGGTYPE_COUNT:
6060
case AGGTYPE_ANY:
6161
case AGGTYPE_DOMINANT:
62+
case AGGTYPE_Q1:
63+
case AGGTYPE_Q3:
6264
case AGGTYPE_MEDIAN:
6365
case AGGTYPE_FIRST:
6466
case AGGTYPE_AND:

cpp/perspective/src/cpp/sparse_tree.cpp

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,42 @@ t_stree::update_agg_table(
13231323

13241324
dst->set_scalar(dst_ridx, new_value);
13251325
} break;
1326+
case AGGTYPE_Q1: {
1327+
old_value.set(dst->get_scalar(dst_ridx));
1328+
auto pkeys = get_pkeys(nidx);
1329+
new_value.set(
1330+
reduce_from_gstate<
1331+
std::function<t_tscalar(std::vector<t_tscalar>&)>>(
1332+
gstate,
1333+
expression_master_table,
1334+
spec.get_dependencies()[0].name(),
1335+
pkeys,
1336+
[&](std::vector<t_tscalar>& values) {
1337+
return get_aggregate_median(values, 0.25);
1338+
}
1339+
)
1340+
);
1341+
1342+
dst->set_scalar(dst_ridx, new_value);
1343+
} break;
1344+
case AGGTYPE_Q3: {
1345+
old_value.set(dst->get_scalar(dst_ridx));
1346+
auto pkeys = get_pkeys(nidx);
1347+
new_value.set(
1348+
reduce_from_gstate<
1349+
std::function<t_tscalar(std::vector<t_tscalar>&)>>(
1350+
gstate,
1351+
expression_master_table,
1352+
spec.get_dependencies()[0].name(),
1353+
pkeys,
1354+
[&](std::vector<t_tscalar>& values) {
1355+
return get_aggregate_median(values, 0.75);
1356+
}
1357+
)
1358+
);
1359+
1360+
dst->set_scalar(dst_ridx, new_value);
1361+
} break;
13261362
case AGGTYPE_MEDIAN: {
13271363
old_value.set(dst->get_scalar(dst_ridx));
13281364
auto pkeys = get_pkeys(nidx);
@@ -1335,7 +1371,7 @@ t_stree::update_agg_table(
13351371
spec.get_dependencies()[0].name(),
13361372
pkeys,
13371373
[&](std::vector<t_tscalar>& values) {
1338-
return get_aggregate_median(values);
1374+
return get_aggregate_median(values, 0.5);
13391375
}
13401376
)
13411377
);
@@ -2326,26 +2362,31 @@ t_stree::get_aggregate(t_index idx, t_index aggnum) const {
23262362
}
23272363

23282364
t_tscalar
2329-
t_stree::get_aggregate_median(std::vector<t_tscalar>& values) const {
2330-
int size = values.size();
2331-
bool is_even_size = size % 2 == 0;
2332-
2365+
t_stree::get_aggregate_median(std::vector<t_tscalar>& values, float n) const {
2366+
const auto size = values.size();
2367+
const float raw_size = static_cast<float>(size) * n;
2368+
bool is_even_size = fabsf(roundf(raw_size) - raw_size) <= 0.00001;
23332369
if (size == 0) {
23342370
return {};
23352371
}
2372+
23362373
if (size == 1) {
23372374
return values[0];
23382375
}
2376+
2377+
const auto split = static_cast<long>(raw_size);
23392378
if (is_even_size && values[0].is_floating_point()) {
23402379
t_tscalar median_average;
2341-
auto middle = values.begin() + (size / 2);
2380+
auto middle = values.begin() + split;
23422381
nth_element(values.begin(), middle, values.end());
23432382
median_average.set(
23442383
(*middle + *(middle - 1)) / static_cast<t_tscalar>(2)
23452384
);
2385+
23462386
return median_average;
23472387
}
2348-
auto middle = values.begin() + (size / 2);
2388+
2389+
auto middle = values.begin() + split;
23492390
std::nth_element(values.begin(), middle, values.end());
23502391
return *middle;
23512392
}

cpp/perspective/src/include/perspective/base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ enum t_aggtype {
259259
AGGTYPE_WEIGHTED_MEAN,
260260
AGGTYPE_UNIQUE,
261261
AGGTYPE_ANY,
262+
AGGTYPE_Q1,
263+
AGGTYPE_Q3,
262264
AGGTYPE_MEDIAN,
263265
AGGTYPE_JOIN,
264266
AGGTYPE_SCALED_DIV,

cpp/perspective/src/include/perspective/sparse_tree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ class PERSPECTIVE_EXPORT t_stree {
312312

313313
t_tscalar get_aggregate(t_index idx, t_index aggnum) const;
314314

315-
t_tscalar get_aggregate_median(std::vector<t_tscalar>& values) const;
315+
t_tscalar
316+
get_aggregate_median(std::vector<t_tscalar>& values, float n) const;
316317

317318
void get_child_indices(t_index idx, std::vector<t_index>& out_data) const;
318319

rust/perspective-client/src/rust/config/aggregates.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ pub enum SingleAggregate {
4949
#[serde(rename = "dominant")]
5050
Dominant,
5151

52+
#[serde(rename = "q1")]
53+
Q1,
54+
55+
#[serde(rename = "q3")]
56+
Q3,
57+
5258
#[serde(rename = "median")]
5359
Median,
5460

@@ -117,6 +123,8 @@ impl Display for SingleAggregate {
117123
Self::Unique => "unique",
118124
Self::Dominant => "dominant",
119125
Self::Median => "median",
126+
Self::Q1 => "q1",
127+
Self::Q3 => "q3",
120128
Self::First => "first",
121129
Self::FirstByIndex => "first by index",
122130
Self::LastByIndex => "last by index",
@@ -155,6 +163,8 @@ impl FromStr for SingleAggregate {
155163
"unique" => Ok(Self::Unique),
156164
"dominant" => Ok(Self::Dominant),
157165
"median" => Ok(Self::Median),
166+
"q1" => Ok(Self::Q1),
167+
"q3" => Ok(Self::Q3),
158168
"first by index" => Ok(Self::FirstByIndex),
159169
"first" => Ok(Self::First),
160170
"last by index" => Ok(Self::LastByIndex),
@@ -241,6 +251,8 @@ const STRING_AGGREGATES: &[SingleAggregate] = &[
241251
SingleAggregate::Last,
242252
SingleAggregate::LastByIndex,
243253
SingleAggregate::Median,
254+
SingleAggregate::Q1,
255+
SingleAggregate::Q3,
244256
SingleAggregate::Unique,
245257
];
246258

@@ -262,6 +274,8 @@ const NUMBER_AGGREGATES: &[SingleAggregate] = &[
262274
SingleAggregate::Last,
263275
SingleAggregate::Mean,
264276
SingleAggregate::Median,
277+
SingleAggregate::Q1,
278+
SingleAggregate::Q3,
265279
SingleAggregate::PctSumParent,
266280
SingleAggregate::PctSumGrandTotal,
267281
SingleAggregate::StdDev,
@@ -286,6 +300,8 @@ const DATETIME_AGGREGATES: &[SingleAggregate] = &[
286300
SingleAggregate::LastByIndex,
287301
SingleAggregate::Last,
288302
SingleAggregate::Median,
303+
SingleAggregate::Q1,
304+
SingleAggregate::Q3,
289305
SingleAggregate::Unique,
290306
];
291307

rust/perspective-js/src/rust/client.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ use wasm_bindgen::prelude::*;
2020
pub use crate::table::*;
2121
use crate::utils::{inherit_docs, ApiError, ApiResult, JsValueSerdeExt, LocalPollLoop};
2222

23-
#[wasm_bindgen(typescript_custom_section)]
24-
const TS_APPEND_CONTENT: &'static str = r#"
25-
import type {TableInitOptions} from "@finos/perspective";
26-
"#;
27-
2823
#[wasm_bindgen]
2924
extern "C" {
3025
#[derive(Clone)]

rust/perspective-js/src/rust/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ export type * from "../../src/ts/ts-rs/ViewOnUpdateResp.d.ts";
3939
export type * from "../../src/ts/ts-rs/OnUpdateOptions.d.ts";
4040
export type * from "../../src/ts/ts-rs/UpdateOptions.d.ts";
4141
42-
import type * as view_window from "../../src/ts/ts-rs/ViewWindow.d.ts";
43-
import type * as table_init_options from "../../src/ts/ts-rs/TableInitOptions.d.ts";
44-
import type * as view_config_update from "../../src/ts/ts-rs/ViewConfigUpdate.d.ts";
42+
import type {ViewWindow} from "../../src/ts/ts-rs/ViewWindow.d.ts";
43+
import type {TableInitOptions} from "../../src/ts/ts-rs/TableInitOptions.d.ts";
44+
import type {ViewConfigUpdate} from "../../src/ts/ts-rs/ViewConfigUpdate.d.ts";
4545
import type * as on_update_args from "../../src/ts/ts-rs/ViewOnUpdateResp.d.ts";
46-
import type * as on_update_options from "../../src/ts/ts-rs/OnUpdateOptions.d.ts";
47-
import type * as update_options from "../../src/ts/ts-rs/UpdateOptions.d.ts";
46+
import type {OnUpdateOptions} from "../../src/ts/ts-rs/OnUpdateOptions.d.ts";
47+
import type {UpdateOptions} from "../../src/ts/ts-rs/UpdateOptions.d.ts";
4848
"#;
4949

5050
#[cfg(feature = "export-init")]

0 commit comments

Comments
 (0)