cppkh-interface 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/PKG-INFO +5 -1
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/README.md +4 -0
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/cppkh_interface/data/src/main.cpp +157 -56
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/pyproject.toml +1 -1
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/build_backend/cppkh_interface_build_backend.py +0 -0
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/cppkh_interface/__init__.py +0 -0
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/cppkh_interface/__main__.py +0 -0
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/cppkh_interface/main.py +0 -0
- {cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/cppkh_interface/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cppkh-interface
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Python interface for cppkh Khovanov homology computation with runtime C++ compilation.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Author: GGN_2015
|
|
@@ -26,6 +26,10 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
`cppkh-interface` is a Python package for computing integer Khovanov homology
|
|
27
27
|
with the C++ `cppkh` implementation.
|
|
28
28
|
|
|
29
|
+
Version `0.1.2` resolves link crossing signs by tracing directed PD edge
|
|
30
|
+
incidences with the SageMath convention. It does not infer signs from numeric
|
|
31
|
+
arc-label ordering.
|
|
32
|
+
|
|
29
33
|
The package is compatible with the main `javakh-interface` function:
|
|
30
34
|
|
|
31
35
|
```python
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
`cppkh-interface` is a Python package for computing integer Khovanov homology
|
|
4
4
|
with the C++ `cppkh` implementation.
|
|
5
5
|
|
|
6
|
+
Version `0.1.2` resolves link crossing signs by tracing directed PD edge
|
|
7
|
+
incidences with the SageMath convention. It does not infer signs from numeric
|
|
8
|
+
arc-label ordering.
|
|
9
|
+
|
|
6
10
|
The package is compatible with the main `javakh-interface` function:
|
|
7
11
|
|
|
8
12
|
```python
|
|
@@ -2758,9 +2758,12 @@ std::string Komplex::KhForZ() {
|
|
|
2758
2758
|
return ret;
|
|
2759
2759
|
}
|
|
2760
2760
|
|
|
2761
|
-
static int chooseXingRecursive(const std::vector<int>& edges, const std::vector<std::vector<int> >& pd,
|
|
2762
|
-
std::vector<char>& in, std::vector<char>& done, int depth, std::vector<int>& retmax) {
|
|
2763
|
-
|
|
2761
|
+
static int chooseXingRecursive(const std::vector<int>& edges, const std::vector<std::vector<int> >& pd,
|
|
2762
|
+
std::vector<char>& in, std::vector<char>& done, int depth, std::vector<int>& retmax) {
|
|
2763
|
+
// Choose the next crossing for the growing tangle. The heuristic maximizes
|
|
2764
|
+
// already-attached boundary arcs, with a short lookahead to keep later
|
|
2765
|
+
// intermediate girth smaller. It affects runtime, not the homology result.
|
|
2766
|
+
int nedges = static_cast<int>(edges.size());
|
|
2764
2767
|
int best = -1, nconbest = -1;
|
|
2765
2768
|
std::vector<int> rbest(depth, 0);
|
|
2766
2769
|
for (size_t i = 0; i < pd.size(); ++i) if (!done[i]) {
|
|
@@ -2819,15 +2822,91 @@ static int takeNextCrossing(const std::vector<int>&, const std::vector<std::vect
|
|
|
2819
2822
|
throw std::runtime_error("no crossing left");
|
|
2820
2823
|
}
|
|
2821
2824
|
|
|
2822
|
-
static std::vector<int> getSigns(const std::vector<std::vector<int> >& pd) {
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2825
|
+
static std::vector<int> getSigns(const std::vector<std::vector<int> >& pd) {
|
|
2826
|
+
const int nodeCount = static_cast<int>(pd.size() * 4);
|
|
2827
|
+
if (nodeCount == 0) return std::vector<int>();
|
|
2828
|
+
|
|
2829
|
+
int maxLabel = -1;
|
|
2830
|
+
for (size_t i = 0; i < pd.size(); ++i) {
|
|
2831
|
+
if (pd[i].size() != 4) throw std::runtime_error("PD crossing must have four entries");
|
|
2832
|
+
for (int label : pd[i]) {
|
|
2833
|
+
if (label < 0) throw std::runtime_error("PD arc labels must be positive");
|
|
2834
|
+
maxLabel = std::max(maxLabel, label);
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
std::vector<int> first(maxLabel + 1, -1), second(maxLabel + 1, -1);
|
|
2839
|
+
for (size_t i = 0; i < pd.size(); ++i) {
|
|
2840
|
+
for (int slot = 0; slot < 4; ++slot) {
|
|
2841
|
+
int label = pd[i][slot];
|
|
2842
|
+
int node = static_cast<int>(4 * i) + slot;
|
|
2843
|
+
if (first[label] == -1) first[label] = node;
|
|
2844
|
+
else if (second[label] == -1) second[label] = node;
|
|
2845
|
+
else throw std::runtime_error("PD arc label appears more than twice");
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
std::vector<int> other(nodeCount, -1);
|
|
2850
|
+
for (int label = 0; label <= maxLabel; ++label) {
|
|
2851
|
+
if (first[label] == -1) continue;
|
|
2852
|
+
if (second[label] == -1) throw std::runtime_error("PD arc label does not appear twice");
|
|
2853
|
+
other[first[label]] = second[label];
|
|
2854
|
+
other[second[label]] = first[label];
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
// 1 means that this edge leaves the crossing at this incidence, and 0
|
|
2858
|
+
// means that it enters. Opposite incidences at a crossing and the two
|
|
2859
|
+
// incidences of one edge always have opposite directions.
|
|
2860
|
+
std::vector<signed char> outgoing(nodeCount, -1);
|
|
2861
|
+
std::vector<int> queue;
|
|
2862
|
+
queue.reserve(nodeCount);
|
|
2863
|
+
auto orientComponent = [&](int seed, signed char direction) {
|
|
2864
|
+
if (outgoing[seed] != -1) {
|
|
2865
|
+
if (outgoing[seed] != direction) throw std::runtime_error("inconsistent PD orientation");
|
|
2866
|
+
return;
|
|
2867
|
+
}
|
|
2868
|
+
queue.clear();
|
|
2869
|
+
outgoing[seed] = direction;
|
|
2870
|
+
queue.push_back(seed);
|
|
2871
|
+
for (size_t head = 0; head < queue.size(); ++head) {
|
|
2872
|
+
int node = queue[head];
|
|
2873
|
+
int crossing = node / 4;
|
|
2874
|
+
int slot = node % 4;
|
|
2875
|
+
int neighbors[2] = {4 * crossing + ((slot + 2) % 4), other[node]};
|
|
2876
|
+
for (int next : neighbors) {
|
|
2877
|
+
if (next < 0) throw std::runtime_error("broken PD edge incidence");
|
|
2878
|
+
signed char nextDirection = static_cast<signed char>(1 - outgoing[node]);
|
|
2879
|
+
if (outgoing[next] == -1) {
|
|
2880
|
+
outgoing[next] = nextDirection;
|
|
2881
|
+
queue.push_back(next);
|
|
2882
|
+
} else if (outgoing[next] != nextDirection) {
|
|
2883
|
+
throw std::runtime_error("inconsistent PD orientation");
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
};
|
|
2888
|
+
|
|
2889
|
+
// In SageMath's PD convention slot 0 is the incoming under-edge and slot
|
|
2890
|
+
// 2 is the outgoing under-edge. These seeds orient every component that
|
|
2891
|
+
// passes under at least once.
|
|
2892
|
+
for (size_t i = 0; i < pd.size(); ++i) orientComponent(static_cast<int>(4 * i + 2), 1);
|
|
2893
|
+
|
|
2894
|
+
// A component which is over at every crossing has no orientation encoded
|
|
2895
|
+
// by the PD tuples. Match SageMath's deterministic traversal by taking the
|
|
2896
|
+
// first occurrence of the smallest still-unoriented edge as a tail.
|
|
2897
|
+
for (int label = 0; label <= maxLabel; ++label) {
|
|
2898
|
+
if (first[label] != -1 && outgoing[first[label]] == -1) orientComponent(first[label], 1);
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2901
|
+
std::vector<int> xsigns(pd.size());
|
|
2902
|
+
for (size_t i = 0; i < pd.size(); ++i) {
|
|
2903
|
+
const std::vector<int>& crossing = pd[i];
|
|
2904
|
+
if (crossing[0] == crossing[3] || crossing[2] == crossing[1]) xsigns[i] = -1;
|
|
2905
|
+
else if (crossing[3] == crossing[2] || crossing[0] == crossing[1]) xsigns[i] = 1;
|
|
2906
|
+
else xsigns[i] = outgoing[4 * i + 3] ? -1 : 1;
|
|
2907
|
+
}
|
|
2908
|
+
return xsigns;
|
|
2909
|
+
}
|
|
2831
2910
|
|
|
2832
2911
|
static bool sanityPD(const PDCode& pd) {
|
|
2833
2912
|
std::map<int, int> counts;
|
|
@@ -2910,15 +2989,17 @@ static PDCode renumberR1Order(PDCode pd) {
|
|
|
2910
2989
|
return pd;
|
|
2911
2990
|
}
|
|
2912
2991
|
|
|
2913
|
-
static PDCode eraseR1(PDCode pd) {
|
|
2914
|
-
if (!sanityPD(pd)) throw std::runtime_error("invalid PD code: every arc label must appear exactly twice");
|
|
2915
|
-
|
|
2992
|
+
static PDCode eraseR1(PDCode pd, std::vector<int>* signs) {
|
|
2993
|
+
if (!sanityPD(pd)) throw std::runtime_error("invalid PD code: every arc label must appear exactly twice");
|
|
2994
|
+
if (signs && signs->size() != pd.size()) throw std::runtime_error("crossing sign count does not match PD code");
|
|
2995
|
+
bool hasR1 = true;
|
|
2916
2996
|
while (hasR1) {
|
|
2917
2997
|
hasR1 = false;
|
|
2918
2998
|
for (size_t i = 0; i < pd.size(); ++i) {
|
|
2919
2999
|
if (uniqueCount(pd[i]) <= 3) {
|
|
2920
|
-
std::vector<int> crossing = pd[i];
|
|
2921
|
-
pd.erase(pd.begin() + static_cast<std::ptrdiff_t>(i));
|
|
3000
|
+
std::vector<int> crossing = pd[i];
|
|
3001
|
+
pd.erase(pd.begin() + static_cast<std::ptrdiff_t>(i));
|
|
3002
|
+
if (signs) signs->erase(signs->begin() + static_cast<std::ptrdiff_t>(i));
|
|
2922
3003
|
std::vector<int> singles;
|
|
2923
3004
|
for (int v : crossing) {
|
|
2924
3005
|
if (std::count(crossing.begin(), crossing.end(), v) == 1) singles.push_back(v);
|
|
@@ -3073,8 +3154,9 @@ static PDCode renumberFullDfs(PDCode pd) {
|
|
|
3073
3154
|
return pd;
|
|
3074
3155
|
}
|
|
3075
3156
|
|
|
3076
|
-
static PDCode eraseOneNugatory(PDCode pd, size_t index) {
|
|
3077
|
-
if (uniqueCount(pd[index]) != 4) throw std::runtime_error("nugatory erase requires R1-free PD code");
|
|
3157
|
+
static PDCode eraseOneNugatory(PDCode pd, size_t index, std::vector<int>* signs) {
|
|
3158
|
+
if (uniqueCount(pd[index]) != 4) throw std::runtime_error("nugatory erase requires R1-free PD code");
|
|
3159
|
+
if (signs && signs->size() != pd.size()) throw std::runtime_error("crossing sign count does not match PD code");
|
|
3078
3160
|
int ax = pd[index][0];
|
|
3079
3161
|
int bx = pd[index][1];
|
|
3080
3162
|
int cx = pd[index][2];
|
|
@@ -3096,22 +3178,23 @@ static PDCode eraseOneNugatory(PDCode pd, size_t index) {
|
|
|
3096
3178
|
if (!loopSet.count(ax) || !loopSet.count(bx) || !loopSet.count(cx) || !loopSet.count(dx)) {
|
|
3097
3179
|
throw std::runtime_error("nugatory crossing arcs are not in one component");
|
|
3098
3180
|
}
|
|
3099
|
-
PDCode bad = pd;
|
|
3100
|
-
bad.erase(bad.begin() + static_cast<std::ptrdiff_t>(index));
|
|
3181
|
+
PDCode bad = pd;
|
|
3182
|
+
bad.erase(bad.begin() + static_cast<std::ptrdiff_t>(index));
|
|
3183
|
+
if (signs) signs->erase(signs->begin() + static_cast<std::ptrdiff_t>(index));
|
|
3101
3184
|
bad = replaceArcValue(bad, ax, cx);
|
|
3102
3185
|
bad = replaceArcValue(bad, dx, bx);
|
|
3103
3186
|
return renumberFullDfs(bad);
|
|
3104
3187
|
}
|
|
3105
3188
|
|
|
3106
|
-
static PDCode simplifyPDCode(PDCode pd) {
|
|
3107
|
-
pd = eraseR1(pd);
|
|
3108
|
-
while (true) {
|
|
3109
|
-
int index = findNugatory(pd);
|
|
3110
|
-
if (index < 0) break;
|
|
3111
|
-
pd = eraseOneNugatory(pd, static_cast<size_t>(index));
|
|
3112
|
-
}
|
|
3113
|
-
return pd;
|
|
3114
|
-
}
|
|
3189
|
+
static PDCode simplifyPDCode(PDCode pd, std::vector<int>* signs = nullptr) {
|
|
3190
|
+
pd = eraseR1(pd, signs);
|
|
3191
|
+
while (true) {
|
|
3192
|
+
int index = findNugatory(pd);
|
|
3193
|
+
if (index < 0) break;
|
|
3194
|
+
pd = eraseOneNugatory(pd, static_cast<size_t>(index), signs);
|
|
3195
|
+
}
|
|
3196
|
+
return pd;
|
|
3197
|
+
}
|
|
3115
3198
|
|
|
3116
3199
|
static int komplexSize(const Komplex& k) {
|
|
3117
3200
|
int total = 0;
|
|
@@ -3119,8 +3202,8 @@ static int komplexSize(const Komplex& k) {
|
|
|
3119
3202
|
return total;
|
|
3120
3203
|
}
|
|
3121
3204
|
|
|
3122
|
-
static Komplex generateFast(const std::vector<std::vector<int> >& pd, const std::vector<int>& xsigns) {
|
|
3123
|
-
KH_PROFILE(generateFast);
|
|
3205
|
+
static Komplex generateFast(const std::vector<std::vector<int> >& pd, const std::vector<int>& xsigns) {
|
|
3206
|
+
KH_PROFILE(generateFast);
|
|
3124
3207
|
if (pd.empty()) {
|
|
3125
3208
|
Komplex kom(1);
|
|
3126
3209
|
kom.columns[0] = SmoothingColumn(1);
|
|
@@ -3128,11 +3211,13 @@ static Komplex generateFast(const std::vector<std::vector<int> >& pd, const std:
|
|
|
3128
3211
|
kom.reduce();
|
|
3129
3212
|
return kom;
|
|
3130
3213
|
}
|
|
3131
|
-
std::vector<char> in(pd.size() * 4, 0), done(pd.size(), 0);
|
|
3132
|
-
std::vector<std::vector<int> > pd1(1, std::vector<int>{0,1,2,3});
|
|
3133
|
-
Komplex kplus(pd1, std::vector<int>{1}, 4);
|
|
3134
|
-
Komplex kminus(pd1, std::vector<int>{-1}, 4);
|
|
3135
|
-
|
|
3214
|
+
std::vector<char> in(pd.size() * 4, 0), done(pd.size(), 0);
|
|
3215
|
+
std::vector<std::vector<int> > pd1(1, std::vector<int>{0,1,2,3});
|
|
3216
|
+
Komplex kplus(pd1, std::vector<int>{1}, 4);
|
|
3217
|
+
Komplex kminus(pd1, std::vector<int>{-1}, 4);
|
|
3218
|
+
// Build the full complex by composing one crossing complex at a time and
|
|
3219
|
+
// reducing after every composition, following JavaKh's tangle-growth path.
|
|
3220
|
+
std::vector<int> edges;
|
|
3136
3221
|
int firstdepth = pd.size() > 4 ? 3 : static_cast<int>(pd.size()) - 1;
|
|
3137
3222
|
std::vector<int> firstdummy(firstdepth + 1, 0);
|
|
3138
3223
|
int first = g_options.reorderCrossings ? chooseXingRecursive(edges, pd, in, done, firstdepth, firstdummy)
|
|
@@ -3312,16 +3397,17 @@ static std::vector<std::string> listInputFiles(const std::string& dir) {
|
|
|
3312
3397
|
return files;
|
|
3313
3398
|
}
|
|
3314
3399
|
|
|
3315
|
-
static std::string computePD(const std::vector<std::vector<int> >& pd) {
|
|
3316
|
-
flushCobCache();
|
|
3317
|
-
g_smallArena.reset();
|
|
3318
|
-
|
|
3319
|
-
|
|
3400
|
+
static std::string computePD(const std::vector<std::vector<int> >& pd) {
|
|
3401
|
+
flushCobCache();
|
|
3402
|
+
g_smallArena.reset();
|
|
3403
|
+
std::vector<int> signs = getSigns(pd);
|
|
3404
|
+
PDCode working = g_options.simplifyPD ? simplifyPDCode(pd, &signs) : pd;
|
|
3405
|
+
Komplex k = generateFast(working, signs);
|
|
3320
3406
|
ProfileScope khScope(g_profile.kh);
|
|
3321
3407
|
return k.KhForZ();
|
|
3322
3408
|
}
|
|
3323
3409
|
|
|
3324
|
-
static std::string formatPDCode(const PDCode& pd) {
|
|
3410
|
+
static std::string formatPDCode(const PDCode& pd) {
|
|
3325
3411
|
std::ostringstream out;
|
|
3326
3412
|
out << "PD[";
|
|
3327
3413
|
for (size_t i = 0; i < pd.size(); ++i) {
|
|
@@ -3334,10 +3420,22 @@ static std::string formatPDCode(const PDCode& pd) {
|
|
|
3334
3420
|
out << "]";
|
|
3335
3421
|
}
|
|
3336
3422
|
out << "]";
|
|
3337
|
-
return out.str();
|
|
3338
|
-
}
|
|
3339
|
-
|
|
3340
|
-
static std::string
|
|
3423
|
+
return out.str();
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
static std::string formatCrossingSigns(const PDCode& pd) {
|
|
3427
|
+
std::vector<int> signs = getSigns(pd);
|
|
3428
|
+
std::ostringstream out;
|
|
3429
|
+
out << "[";
|
|
3430
|
+
for (size_t i = 0; i < signs.size(); ++i) {
|
|
3431
|
+
if (i) out << ",";
|
|
3432
|
+
out << signs[i];
|
|
3433
|
+
}
|
|
3434
|
+
out << "]";
|
|
3435
|
+
return out.str();
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
static std::string simplifiedPDString(const PDCode& pd) {
|
|
3341
3439
|
PDCode working = g_options.simplifyPD ? simplifyPDCode(pd) : pd;
|
|
3342
3440
|
return formatPDCode(working);
|
|
3343
3441
|
}
|
|
@@ -3464,7 +3562,7 @@ CPPKH_API char* cppkh_simplify_pd(const char* pd_code) {
|
|
|
3464
3562
|
|
|
3465
3563
|
#ifndef CPPKH_SHARED_LIBRARY
|
|
3466
3564
|
static void usage() {
|
|
3467
|
-
std::cout << "Usage:
|
|
3565
|
+
std::cout << "Usage: cppkh [--pd-file FILE] [--pd-dir DIR] [--pd-code CODE] [--ordered] [--threads N|auto] [--quiet] [--profile] [--no-simplify-pd] [--print-simplified-pd] [--print-crossing-signs]\n";
|
|
3468
3566
|
std::cout << "Thread backend: " << KH_THREAD_BACKEND_NAME << "\n";
|
|
3469
3567
|
std::cout << "Detected CPU threads: " << kh::detectHardwareThreads() << "\n";
|
|
3470
3568
|
std::cout << "PD simplification: R1 removal then nugatory crossing removal is enabled by default.\n";
|
|
@@ -3472,9 +3570,10 @@ static void usage() {
|
|
|
3472
3570
|
|
|
3473
3571
|
int main(int argc, char** argv) {
|
|
3474
3572
|
try {
|
|
3475
|
-
std::vector<std::string> files;
|
|
3476
|
-
std::vector<std::pair<std::string, std::vector<std::vector<int> > > > jobs;
|
|
3477
|
-
bool printSimplifiedPD = false;
|
|
3573
|
+
std::vector<std::string> files;
|
|
3574
|
+
std::vector<std::pair<std::string, std::vector<std::vector<int> > > > jobs;
|
|
3575
|
+
bool printSimplifiedPD = false;
|
|
3576
|
+
bool printCrossingSigns = false;
|
|
3478
3577
|
for (int i = 1; i < argc; ++i) {
|
|
3479
3578
|
std::string a = argv[i];
|
|
3480
3579
|
if (a == "--help" || a == "-h") { usage(); return 0; }
|
|
@@ -3493,8 +3592,9 @@ int main(int argc, char** argv) {
|
|
|
3493
3592
|
else if (a == "--quiet" || a == "-q") kh::g_options.progress = false;
|
|
3494
3593
|
else if (a == "--profile") kh::g_options.profile = true;
|
|
3495
3594
|
else if (a == "--no-simplify-pd" || a == "--raw-pd") kh::g_options.simplifyPD = false;
|
|
3496
|
-
else if (a == "--simplify-pd") kh::g_options.simplifyPD = true;
|
|
3497
|
-
else if (a == "--print-simplified-pd") printSimplifiedPD = true;
|
|
3595
|
+
else if (a == "--simplify-pd") kh::g_options.simplifyPD = true;
|
|
3596
|
+
else if (a == "--print-simplified-pd") printSimplifiedPD = true;
|
|
3597
|
+
else if (a == "--print-crossing-signs") printCrossingSigns = true;
|
|
3498
3598
|
else if (a == "--threads" || a == "-j") {
|
|
3499
3599
|
if (++i >= argc) throw std::runtime_error("--threads needs a number");
|
|
3500
3600
|
std::string v = argv[i];
|
|
@@ -3521,9 +3621,10 @@ int main(int argc, char** argv) {
|
|
|
3521
3621
|
kh::g_profile.reset();
|
|
3522
3622
|
profileStart = kh::profileNowNs();
|
|
3523
3623
|
}
|
|
3524
|
-
if (label) std::cout << jobs[i].first << "\t";
|
|
3525
|
-
if (printSimplifiedPD) std::cout << kh::simplifiedPDString(jobs[i].second) << "\n";
|
|
3526
|
-
else std::cout <<
|
|
3624
|
+
if (label) std::cout << jobs[i].first << "\t";
|
|
3625
|
+
if (printSimplifiedPD) std::cout << kh::simplifiedPDString(jobs[i].second) << "\n";
|
|
3626
|
+
else if (printCrossingSigns) std::cout << kh::formatCrossingSigns(jobs[i].second) << "\n";
|
|
3627
|
+
else std::cout << "\"" << kh::computePD(jobs[i].second) << "\"\n";
|
|
3527
3628
|
if (kh::g_options.profile) {
|
|
3528
3629
|
kh::g_profile.totalNs = kh::profileNowNs() - profileStart;
|
|
3529
3630
|
kh::printProfile();
|
{cppkh_interface-0.1.1 → cppkh_interface-0.1.2}/build_backend/cppkh_interface_build_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|