maciej-bendkowski / paganini

Multiparametric tuner for combinatorial specifications
BSD 3-Clause "New" or "Revised" License
5 stars 1 forks source link

Paganini output for Pólya operators #7

Closed Kerl13 closed 2 years ago

Kerl13 commented 2 years ago

As far as I understand, in a specification involving Pólya operators, I can get the values of my generating functions at z, , , … in the ._diag field of the Specification object after tuning. For instance:

from paganini import *

T, z = Variable(), Variable()
spec = Specification()
spec.add(T, z * MSet(T))
spec.run_singular_tuner(z, method=Method.FORCE)

for j, var in spec._diag[T].items():
    print(f"T(z^{j}) = {var.value}")

Is this reliable? This is an undocumented feature and I guess the _diag field is “private” (in Python's sense). Unless I'm missing something this is essential for the associated Boltzmann sampler. It would be nice to document how we should proceed to get these values.

Sergey-A-Dovgal commented 2 years ago

Theoretically, you can write up a manual specification for Polya structures as a finite truncated context-free grammar. That's basically what we do, but at the time, the data was hidden in the internal field. I think you can use it if your goal is to compare benchmarks - or you can alternatively rewrite the system. Be sure to check the truncation level though! We were using a hard-coded value which was good enough to get a high precision.

Kerl13 commented 2 years ago

I think I understand what's happening under the hood with the truncated grammar. My concern is that we are using paganini as a dependency in usainboltz and accessing values stored in a private undocumented field in third party code seems fragile to me. It feels like I should not rely on this. So my questions are:

Sorry if my first message was not clear.

And regarding the truncation level, if I understand correctly, it's possible to tweak it using the series_truncate argument of the Specification class, which is nice :+1:

maciej-bendkowski commented 2 years ago

The ._diag values were not exposed because they are, in a manner of speaking, a private implementation detail. You cannot declare them in the public api. That being said, I assume you want the values of the respective generating function at these powers because you are interested in creating a Boltzmann sampler (as defined in Boltzmann Sampling of Unlabelled Structures by Philippe Flajolet, Eric Fusy, and Carine Pivoteau). We could expose them through a read method so that it feels less "hacky" to access them. Would that suffice?

Kerl13 commented 2 years ago

This would perfectly suit my needs yes!

maciej-bendkowski commented 2 years ago

67bf4139ee2a55308c28e45a10a224cf2ca57d37 exposes diagonals, as requested.