-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcpnet.h
More file actions
385 lines (344 loc) · 19.7 KB
/
Copy pathmcpnet.h
File metadata and controls
385 lines (344 loc) · 19.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#ifndef MCPNET_H
#define MCPNET_H
#include <cstddef>
#include <cstdint>
#include "rust/cxx.h"
// =============================================================================
// Adaptive partitioning mutual information
// (mcp::kernel::AdaptivePartitionRankMIKernel2)
// =============================================================================
//
// Compute mutual information between two rank-transformed vectors. Both
// inputs must have the same length and contain integer ranks in
// `[0, count)`. The result is in bits (log base 2).
float adaptive_mi_kernel_f32(rust::Slice<const ::std::size_t> x_ranks,
rust::Slice<const ::std::size_t> y_ranks);
double adaptive_mi_kernel_f64(rust::Slice<const ::std::size_t> x_ranks,
rust::Slice<const ::std::size_t> y_ranks);
// =============================================================================
// Rank transform (splash::kernel::Rank<IT, std::size_t, 0, false>)
// =============================================================================
//
// Descending rank (matches MCPNet `mi.cpp`), first rank = 0, output type
// `size_t`. `out_vec` must be at least `in_vec.size()` long.
void rank_f32(rust::Slice<const float> in_vec,
rust::Slice<::std::size_t> out_vec);
void rank_f64(rust::Slice<const double> in_vec,
rust::Slice<::std::size_t> out_vec);
// =============================================================================
// Cumulative histogram (mcp::kernel::IntegralCumulativeHistogramKernel)
// =============================================================================
//
// Builds a cumulative histogram over the integer ranks in `in_vec`. `out_vec`
// must be `in_vec.size() + 1` long and zero-initialized on entry.
void integral_cumulative_histogram(rust::Slice<const ::std::size_t> in_vec,
rust::Slice<::std::size_t> out_vec);
// =============================================================================
// BSpline weights (mcp::kernel::BSplineWeightsKernel)
// =============================================================================
//
// Computes the BSpline weight matrix for a single sample vector. The
// output vector must be at least `num_bins * num_samples + 1` elements long;
// the last element holds the 1D BSpline entropy of the weights.
void bspline_weights_f32(rust::Slice<const float> in_vec,
::std::int32_t num_bins,
::std::int32_t spline_order,
::std::int32_t num_samples,
rust::Slice<float> out_vec);
void bspline_weights_f64(rust::Slice<const double> in_vec,
::std::int32_t num_bins,
::std::int32_t spline_order,
::std::int32_t num_samples,
rust::Slice<double> out_vec);
// =============================================================================
// BSpline mutual information (mcp::kernel::BSplineMIKernel)
// =============================================================================
//
// Computes mutual information between two variables from their BSpline
// weight vectors as `H(X) + H(Y) - H(X, Y)`. Each input vector must be
// exactly `num_bins * num_samples + 1` elements long (the layout produced
// by `bspline_weights_*`).
float bspline_mi_kernel_f32(rust::Slice<const float> first,
rust::Slice<const float> second,
::std::int32_t num_bins,
::std::int32_t num_samples);
double bspline_mi_kernel_f64(rust::Slice<const double> first,
rust::Slice<const double> second,
::std::int32_t num_bins,
::std::int32_t num_samples);
// =============================================================================
// Z-score / standard score (splash::kernel::StandardScore)
// =============================================================================
//
// Population standard score (SampleStats = false), matching MCPNet's
// pearson.cpp pipeline so that pairing with `pearson_kernel_*` yields the
// usual Pearson correlation coefficient. `out_vec` must be at least
// `in_vec.size()` long.
void standard_score_f32(rust::Slice<const float> in_vec,
rust::Slice<float> out_vec);
void standard_score_f64(rust::Slice<const double> in_vec,
rust::Slice<double> out_vec);
// =============================================================================
// Pearson correlation (mcp::correlation::PearsonKernel)
// =============================================================================
//
// Computes the Pearson correlation coefficient. The two inputs are expected
// to already be standard-scored (see `standard_score_*`). Both inputs must
// have the same length.
float pearson_kernel_f32(rust::Slice<const float> first,
rust::Slice<const float> second);
double pearson_kernel_f64(rust::Slice<const double> first,
rust::Slice<const double> second);
// =============================================================================
// Element-wise combine kernels (mcp::kernel from mcp/transform/combine.hpp)
// =============================================================================
//
// All vector kernels write `count = min(in_a.size(), in_b.size())` output
// elements (or `in.size()` for the unary `scale_kernel`). The output buffer
// must be at least that large.
void add_kernel_f32 (rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
rust::Slice<float> out);
void add_kernel_f64 (rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
rust::Slice<double> out);
void sub_kernel_f32 (rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
rust::Slice<float> out);
void sub_kernel_f64 (rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
rust::Slice<double> out);
void multiply_kernel_f32(rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
rust::Slice<float> out);
void multiply_kernel_f64(rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
rust::Slice<double> out);
void ratio_kernel_f32 (rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
rust::Slice<float> out);
void ratio_kernel_f64 (rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
rust::Slice<double> out);
void max_kernel_f32 (rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
rust::Slice<float> out);
void max_kernel_f64 (rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
rust::Slice<double> out);
void min_kernel_f32 (rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
rust::Slice<float> out);
void min_kernel_f64 (rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
rust::Slice<double> out);
// out = a + coeff * b
void madd_kernel_f32 (rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
double coeff,
rust::Slice<float> out);
void madd_kernel_f64 (rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
double coeff,
rust::Slice<double> out);
// out = alpha * a + beta * b
void weighted_mean_kernel_f32(rust::Slice<const float> in_a,
rust::Slice<const float> in_b,
double alpha,
double beta,
rust::Slice<float> out);
void weighted_mean_kernel_f64(rust::Slice<const double> in_a,
rust::Slice<const double> in_b,
double alpha,
double beta,
rust::Slice<double> out);
// out = coeff * in
void scale_kernel_f32 (rust::Slice<const float> in,
double coeff,
rust::Slice<float> out);
void scale_kernel_f64 (rust::Slice<const double> in,
double coeff,
rust::Slice<double> out);
// =============================================================================
// Stouffer kernels (mcp/transform/stouffer.hpp)
// =============================================================================
//
// The auxiliary (mean, stdev) pairs used in MCPNet are passed here as two
// scalars or two parallel arrays.
float stouffer_kernel_f32(float value,
float mean1, float std1,
float mean2, float std2);
double stouffer_kernel_f64(double value,
double mean1, double std1,
double mean2, double std2);
void stouffer_vector_kernel_f32(rust::Slice<const float> in_vec,
float aux1_mean,
float aux1_std,
rust::Slice<const float> aux2_means,
rust::Slice<const float> aux2_stds,
rust::Slice<float> out);
void stouffer_vector_kernel_f64(rust::Slice<const double> in_vec,
double aux1_mean,
double aux1_std,
rust::Slice<const double> aux2_means,
rust::Slice<const double> aux2_stds,
rust::Slice<double> out);
// out[k] = (zi[k] + zj[k]) / sqrt(2)
void zscored_stouffer_kernel_f32(rust::Slice<const float> zi,
rust::Slice<const float> zj,
rust::Slice<float> out);
void zscored_stouffer_kernel_f64(rust::Slice<const double> zi,
rust::Slice<const double> zj,
rust::Slice<double> out);
float weighted_stouffer_kernel_f32(float value,
float mean1, float std1,
float mean2, float std2);
double weighted_stouffer_kernel_f64(double value,
double mean1, double std1,
double mean2, double std2);
// =============================================================================
// Context Likelihood of Relatedness (mcp/transform/clr.hpp)
// =============================================================================
float clr_kernel_f32(float value,
float mean1, float std1,
float mean2, float std2);
double clr_kernel_f64(double value,
double mean1, double std1,
double mean2, double std2);
void clr_vector_kernel_f32(rust::Slice<const float> in_vec,
float aux1_mean,
float aux1_std,
rust::Slice<const float> aux2_means,
rust::Slice<const float> aux2_stds,
rust::Slice<float> out);
void clr_vector_kernel_f64(rust::Slice<const double> in_vec,
double aux1_mean,
double aux1_std,
rust::Slice<const double> aux2_means,
rust::Slice<const double> aux2_stds,
rust::Slice<double> out);
// out[k] = sqrt(zi[k]^2 + zj[k]^2)
void zscored_clr_kernel_f32(rust::Slice<const float> zi,
rust::Slice<const float> zj,
rust::Slice<float> out);
void zscored_clr_kernel_f64(rust::Slice<const double> zi,
rust::Slice<const double> zj,
rust::Slice<double> out);
// =============================================================================
// Filter kernels (mcp/filter/threshold.hpp, mcp/filter/dpi.hpp, mcp/filter/mcp.hpp)
// =============================================================================
// ---- threshold.hpp ----------------------------------------------------------
// out[i] = (min <= in[i] <= max) ? in[i] : default_val
void threshold_kernel_f32(rust::Slice<const float> in_vec,
float min_thresh, float max_thresh,
float default_val,
rust::Slice<float> out);
void threshold_kernel_f64(rust::Slice<const double> in_vec,
double min_thresh, double max_thresh,
double default_val,
rust::Slice<double> out);
// out[i] = (in[i] <= min OR in[i] >= max) ? in[i] : default_val
void inverted_threshold_kernel_f32(rust::Slice<const float> in_vec,
float min_thresh, float max_thresh,
float default_val,
rust::Slice<float> out);
void inverted_threshold_kernel_f64(rust::Slice<const double> in_vec,
double min_thresh, double max_thresh,
double default_val,
rust::Slice<double> out);
// out[i] = (min <= aux[i] <= max) ? in[i] : default_val
void threshold2_kernel_f32(rust::Slice<const float> in_vec,
rust::Slice<const float> aux,
float min_thresh, float max_thresh,
float default_val,
rust::Slice<float> out);
void threshold2_kernel_f64(rust::Slice<const double> in_vec,
rust::Slice<const double> aux,
double min_thresh, double max_thresh,
double default_val,
rust::Slice<double> out);
// out[i] = (aux[i] <= min OR aux[i] >= max) ? in[i] : default_val
void inverted_threshold2_kernel_f32(rust::Slice<const float> in_vec,
rust::Slice<const float> aux,
float min_thresh, float max_thresh,
float default_val,
rust::Slice<float> out);
void inverted_threshold2_kernel_f64(rust::Slice<const double> in_vec,
rust::Slice<const double> aux,
double min_thresh, double max_thresh,
double default_val,
rust::Slice<double> out);
// out[i] = ((negate ^ (mask[i] != 0)) ? in[i] : default_val
// `mask` is a u8 slice where 0 means false and any non-zero means true.
void mask_kernel_f32(rust::Slice<const float> in_vec,
rust::Slice<const ::std::uint8_t> mask,
bool negate, float default_val,
rust::Slice<float> out);
void mask_kernel_f64(rust::Slice<const double> in_vec,
rust::Slice<const ::std::uint8_t> mask,
bool negate, double default_val,
rust::Slice<double> out);
// ---- dpi.hpp ----------------------------------------------------------------
// Returns true when the edge (x, z) should be deleted under DPI: there is some
// y for which mi_xy and mi_yz both meet the i_xz tolerance bound.
// EQUALITY_EXCLUSION is set to true (the default in the C++ code).
bool dpi_kernel_f32(::std::size_t x, ::std::size_t z,
rust::Slice<const float> row_x,
rust::Slice<const float> row_z,
double tolerance);
bool dpi_kernel_f64(::std::size_t x, ::std::size_t z,
rust::Slice<const double> row_x,
rust::Slice<const double> row_z,
double tolerance);
// As above but with a per-node TF mask (TFs[i] > 0 marks node `i` as a TF).
bool dpi_tf_kernel_f32(::std::size_t x, ::std::size_t z,
rust::Slice<const float> row_x,
rust::Slice<const float> row_z,
rust::Slice<const float> tfs,
double tolerance);
bool dpi_tf_kernel_f64(::std::size_t x, ::std::size_t z,
rust::Slice<const double> row_x,
rust::Slice<const double> row_z,
rust::Slice<const double> tfs,
double tolerance);
// ---- mcp.hpp ----------------------------------------------------------------
// max_y(min(row_x[y], row_z[y])) excluding y in {x, z}; if `tfs` is non-empty,
// it is used as a per-node mask (only y with tfs[y] > 0 are considered).
float mcp2_maxmin_kernel_f32(::std::size_t x, ::std::size_t z,
rust::Slice<const float> row_x,
rust::Slice<const float> row_z,
rust::Slice<const float> tfs);
double mcp2_maxmin_kernel_f64(::std::size_t x, ::std::size_t z,
rust::Slice<const double> row_x,
rust::Slice<const double> row_z,
rust::Slice<const double> tfs);
// row_x[z] / max_y(min(row_x[y], row_z[y]))
float mcp_ratio_kernel_f32(::std::size_t x, ::std::size_t z,
rust::Slice<const float> row_x,
rust::Slice<const float> row_z,
rust::Slice<const float> tfs);
double mcp_ratio_kernel_f64(::std::size_t x, ::std::size_t z,
rust::Slice<const double> row_x,
rust::Slice<const double> row_z,
rust::Slice<const double> tfs);
// 1 - ratio (with optional clamping into [0, 1]).
float mcp_tolerance_kernel_f32(::std::size_t x, ::std::size_t z,
rust::Slice<const float> row_x,
rust::Slice<const float> row_z,
rust::Slice<const float> tfs,
bool clamped);
double mcp_tolerance_kernel_f64(::std::size_t x, ::std::size_t z,
rust::Slice<const double> row_x,
rust::Slice<const double> row_z,
rust::Slice<const double> tfs,
bool clamped);
// row_x[z] - max_y(min(row_x[y], row_z[y]))
float mcp_diff_kernel_f32(::std::size_t x, ::std::size_t z,
rust::Slice<const float> row_x,
rust::Slice<const float> row_z,
rust::Slice<const float> tfs);
double mcp_diff_kernel_f64(::std::size_t x, ::std::size_t z,
rust::Slice<const double> row_x,
rust::Slice<const double> row_z,
rust::Slice<const double> tfs);
#endif // MCPNET_H