-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Oscillation #70
Comments
It is important to distinguish two things. First there is the computation of an optimal volume splitting, which is an iterative process that uses the result of one iteration to adapt the splitting of the next iteration. Then there is the CrossReferenceHandler which keeps information about the previous iteration in order to do two things:
The two processes happen at the same time but are not really related. The "dirty" state only concerns the CrossReferenceHandler part and has not so much to do with the volume optimization (except for the information about the volume count and volume sizes which is also stored in the CRH). The volume optimization has some kind of guard against oscillations build in. The CRH parts doesn't so it's more likely this is where the problem lies. On the other hand the fact that you end up with an oscillation only as of the 140th iteration, as you mentioned on the call, is more likely to be due to a slow convergence in the volume splitting algorithm. |
The statement that the CRH doesn't have an oscillation guard doesn't make any sense. Oscillation occurs when the algorithm keeps trying the same solutions over and over. The CRH simply detects that the solutions are faulty. However, I doubt that it's correct that the CRH is clean when oscillation occurs. |
I'm looking at the seemingly simple example from Paul that takes more than 50 iterations. I've gathered this trace info. It seems to me that the estimation of the split is reasonable, but the actual splitter does something unexpected, which results in ever more volumes being added but there are never enough.
|
The fact that these block can not possibly fit on a page has something to do with it (page is 8 wide and 5 high): <block keep="page">
⠉⠉⠉⠉⠉ ⠉⠉⠉⠉⠉ ⠉⠉⠉⠉⠉ ⠉⠉⠉⠉⠉ ⠉⠉⠉⠉⠉ ⠉⠉⠉⠉⠉
</block> |
I'm working on this branch, in case you want to follow along. You can see I further simplified the test. Both the |
Without the
@joeha480 Can you make sense of this? |
On second thought, the EvenSizeVolumeSplitter does not work well! It keeps adding extra volumes instead of just increasing the sizes of existing volumes. Because for every iteration the total number of sheets increases, this is a never ending circle. |
I'm going to try to improve the algorithm a bit now, but in the long run I want to get rid of EvenSizeVolumeSplitter altogether, like I suggested in #50 (comment). |
The oscillation is a different and AFAICS unrelated part of the problem. It looks like the oscillation is caused by the feedback of TransitionProperties st = rcontext.getRefs().getTransitionProperties(thisPageId);
- double v1 = st.getVolumeKeepPriority().orElse(10) + (st.hasBlockBoundary()?0.5:0);
+ double v1 = st.getVolumeKeepPriority().orElse(10) + (st.hasBlockBoundary()?0:0);
st = rcontext.getRefs().getTransitionProperties(next.get().getPageId());
- double v2 = st.getVolumeKeepPriority().orElse(10) + (st.hasBlockBoundary()?0.5:0);
+ double v2 = st.getVolumeKeepPriority().orElse(10) + (st.hasBlockBoundary()?0:0);
if (v1>v2) { Maybe it would be better if we could use the up to date value of hasBlockBoundary? I don't know. @joeha480 Would you mind having a look? @PaulRambags If not taking into account hasBlockBoundary, at least for the time being, is acceptable for you, we could already use this as a temporary solution. Basically what hasBlockBoundary does, if I understand this correctly, is to make sure that if a big block starts on the right-hand page right before a volume split and does not fit within the sheet, the volume split is more likely do be done after the right-hand page. |
Note that when there are |
This has the negative result that Dotify will not consider a volume break opportunity between to blocks on a right-hand page unless the blocks have volume-keep-priority attributes. However the positive part is that it fixes Paul's oscillation (brailleapps#70).
Without this change it is possible that we end up in an endless alternation between two volume renderings. (In other words, brailleapps#70 was not completely fixed yet.) I proposed this change in brailleapps#97 already but we did not include it at the time.
Without this change it is possible that we end up in an endless alternation between two volume renderings. (In other words, brailleapps/dotify.formatter.impl#70 was not completely fixed yet.) I proposed this change in brailleapps/dotify.formatter.impl#97 already but we did not include it at the time.
Without this change it is possible that we end up in an endless alternation between two volume renderings. (In other words, brailleapps/dotify.formatter.impl#70 was not completely fixed yet.) I proposed this change in brailleapps/dotify.formatter.impl#97 already but we did not include it at the time.
Without this change it is possible that we end up in an endless alternation between two volume renderings. (In other words, brailleapps/dotify.formatter.impl#70 was not completely fixed yet.) I proposed this change in brailleapps/dotify.formatter.impl#97 already but we did not include it at the time.
In the process of generating volumes, the formatter uses iterations to come to a stable state where nothing is dirty anymore. This process of trying again may end up oscillating, that is, iteration n is doing exactly the same as iteration n - 2 for some n > 0.
This should be changed so that the volume generating process always ends successfully.
Currently I only have a very large example where this happens.
@todo: Provide a small example.
The text was updated successfully, but these errors were encountered: