Algorithm to Determine Width of Text - algorithm

In a program I'm writing in an unnamed language, I have a block of text for which the width is unknown, and all I know is the maximum width that this block of text could be. Given this information, I need to find out the smallest possible width that this text could be (assume that I can't use the metrics of the characters / glyphs or the character count). So far I just have a brute force solution which looks like follows:
for (int i = .1; i < maxTextWidth; i += .1)
{
if (textFitsInGivenWidth(text, i))
{
textWidth = i;
break;
}
}
I'd like to try and optimize this as much as I can. My first thought was to use a binary search, but I'm having trouble implementing this in the proper way (and am not sure if it's even possible). Does anyone have any suggestions on what I could do here to improve the run time using only what I've given in the above solution?

Binary Search is the answer indeed.
http://en.wikipedia.org/wiki/Binary_search_algorithm
for integer binary search, it can be:
minW=0, maxW=maxTextWidth
while(minW<=maxW){
mid=(minW+maxW)/2;
if (textFitsInGivenWidth(text, mid)){
maxW=mid-1;
}else{
minW=mid+1;
}
}
textWidth=minW
The idea is, if you have textFitsInGivenWidth(text, mid) == True,
then you must have textFitsInGivenWidth(text, i) == True for all i>=mid,
and if it's False, then you have textFitsInGivenWidth(text, i) == False for all i<=mid
so each time we check the middle of the interval to be checked, and reduce the interval into half . The time is O(logN), in which N=maxTextWidth
update: for float support, see the example below :
float minW=0, maxW=maxTextWidth
while(1){
if (maxW-minW<0.05)
break;
float mid=(minW+maxW)/2;
if (textFitsInGivenWidth(text, mid)){
maxW=mid;
}else{
minW=mid;
}
}
textWidth=minW
and to get a precision of .1, simply change the last line to :
textWidth=int(minW*10)/10.0

Related

Is there any way to combine Funcs into a Func has one more dimension?

I started to learn Halide from last month.
And finally encounterd big problem for me.
I'm trying to implement function like following C-like code in Halide.
for( int y = 0; y < 3; ++y ){
for( int x = 0; x < 3; ++x ){
out(x, y) = out(x-1, y-1) + 1;
}
}
so assuming initial image is below.
0 0 0
0 0 0
0 0 0
output image will be …(0 out of bound)
1 1 1
1 2 2
1 2 3
so I thought two possible solutions.
・Solution1
Define above algorithm like this recursive function.
Func algorithm1(Func input, int n)
{
Func src, clamped, dst;
Var x, y;
if(n == 1){
src = input;
}else{
src = algorithm1(input, n-1);
src.compute_root();
}
clamped = BoundaryConditions::constant_exterior(src, 0, 0, SIZE, 0, SIZE);
dst(x, y) = clamped(x-1, y-1) + 1;
return dst;
}
And use above function like following code.
Func input, output;
input(x, y) = src(x, y);
output = algorithm1(input, SIZE);
output.realize(src);
This implementation barely works. But obviously rebundunt.
Because most of the computation result of the each stage(Func) are not match the final result although each Func computes across over entire image.
And I need to handle more large(normal) images.
So I thought another possible solution.
・Solution2
At first of second solution.
Declare a function defines relationship between one column and another one.
Func algorithm2(Func src)
{
Func clamped, dst;
Var x;
clamped = BoundaryConditions::constant_exterior(src, 0, 0, SIZE);
dst(x) = clamped(x-1) + 1;
return dst;
}
Then, let's combine this.
Func output[3];
output[0](x) = cast<uint32_t>(0);
for(int i = 1; i < SIZE; ++i){
output[i] = algorithm2(output[i-1]);
}
Alright... Here's the problem. How can I combine this array of Funcs as a Func?
Of cource, I can get an Image if I realize this array of Funcs at each func to an pointer of the column's head. But What if I want to pass it to the next Func?
I looked around entire Halide examples(test, apps) these days. But I think there's no similar example.
And you might already noticed my discomfort of English, actually I'm a japanese. So if there are useful example for this problem, I'm so sorry in advance. If so, please tell me where it is. If there's another good implementation idea, please teach me. Anyway I need someone's help!
I appreciate for your reading.
[edit 2]
edit 1 is my foolish question. I can schedule it compute_root().
I've decided to left them on here, really embarrassing though.
I hope this will be helpful to another foolish man.
[edit 1]
I'm appreciate to your fast and detailed response from bottom of my heart!
I'm sorry for late response, I wanted to reply to you after succeeding to implement my algorithm. However, my Halide code still doesn't work what I wanna do and got some things to confirm.
First off, I would like to tell you I realized my misunderstanding of Halide thanks to you. At first of my algorithm's implementation step, I wrote definition using only pure 'Var's.
So I got following error.
All of a functions recursive references to itself must contain the same pure variables in the same places as on the left-hand-side.
I thought this error occured because of scheduling flexibility. If such definition is allowed and schedule it to split, It means that scheduling changes algorithm. This comprehension is correct? From such comprehension, although I already read reduction part of Tutorials and blur example, I misunderstood that I cannot access neighbor pixels in all of Func definitions. I don't know why though.
And reduction domain couldn't be split because of same reason. I think I got it now.
Here's another question to your code. Thanks to your Halide implementation example, I've almost succeeded to implement what I wanna do with no consideration. However, this implementation is desperately slow although I'm handling 20x20 cropped image for ease of debugging.
I'm considering this slowness is caused by reduction domain. In your example, for example when calculating the value g(10, 10), Halide calculation is scheduled from f(0, 0) to f(0, 0) and finally get there value. In the other hand, C implementation just loads the value at g(9, 9) and just increment it though. We can confirm such calculation from printing loop nest.
produce g:
for y:
for x:
produce f:
for y:
for x:
f(...) = ...
for range:
for range:
f(...) = ...
consume f:
g(...) = ...
I would like to confirm that Avoiding this recomputation is impossible? and so you suggested it?
And I would like to ask you another simple question. If there is reverse-dependency like this,
for( int y = 2; y > 0; --y ){
for( int x = 2; x > 0; --x ){
out(x, y) = out(x+1, y+1) + 1;
}
}
Is Halide able to express this code?
The algorithm1 and algorithm2 parts here are not very clear to me. I understand the initial problem statement and the English seems fine so I will endeavor to provide some help answering the question I think you are asking. I'll do this by illustrating a few Halide mechanisms you may not know about or that aren't obvious for use here. Hopefully this will be helpful.
First off, to map a dimension of a Halide Func to different expressions, you pretty much have to use a select statement:
Var x, y, n;
Func f_0, f_1, f_both;
f_0(x, y) = ...;
f_1(x, y) = ...;
f_both(x, y, n) = select(n == 0, f_zero, f_one);
This can be expanded to more cases via adding arguments to the select. This is more useful for piecewise computations than for recursive structures but seems the most direct answer to the question in the title.
The second mechanism is Tuple. This allows a Func to have more than one value, which can be indexed with compile time constants. I don't think this is the answer you are looking for, but i tis convered in tutorial/lesson_13_tuples.cpp .
Finally, Halide supports reductions, which are designed to handle the case in the first code example. This looks like so:
Var x, y;
Func f, g;
RDom range(0, 3, 0, 3); // Form is min/extent, not start/end
f(x, y) = 0; // Initial condition
f(range.x, range.y) = f(range.x - 1, range.y - 1) + 1;
g(x, y) = f(x, y);
Buffer<int32t> result = g.realize(3, 3);
This should produce the output from your first example. Reductions, or "update definitions" are covered in tutorial/lesson_09_update_definitions.cpp .

Bad math (and code) while incrementing values

Warning: I'm a total beginner. Very rookie mistakes ahead. The language used is Processing (Java).
I'm using functions to add numbers consecutively (i.e. 1+2+3+4+5+6 and so on) up to 10. I use the float "num" represents how high it should count up in this incremental manner, which is 10.
Next, I'm calculating factorials (1*2*3*4*5*6 and so on) up to 10.
My teacher gave the example in class for adding the numbers consecutively, which looks like:
float Addition(float num) {
float val1=1;
float val=0;
while (val1 <=num){
val=val+val1;
val1++;
}
return val;
}
This adds to 55, as it should, since we're incrementing until we hit 10. Could someone please explain the concept of this for me? I'm working on a bit now that adds in increments of 4 (i.e. 0+4+8+12+16+20 and so on) up to 10, but my math is WAY is off; it should equal to 180, but instead equals 45:
float Addition2(float num) {
float val1=1;
float val=1;
while (val1 <=num){
val=val*val1;
val1=val1+val2+4;
}
return val;
}
I'm not looking for anyone to fix the math for me, but to explain the concept itself and how I would properly calculate this (if that makes sense).
Thanks in advance.
P.S.
As a bonus, here is my work on the factorial, again, also wrong. If someone could also explain the concept of this, that would be smashing:
float Multiplication1(float num) {
float val1=1;
float val=1;
while (val1 <=num){
val=val*val1;
val1=val1+2;
}
return val;
}
To understand code, try to take it line by line. It might help to add comments to it to understand. It might also help to use longer and more descriptive variable names. Let's try with the function that works:
//this function adds up 1+2+...maxNumberToAdd
float addition(float maxNumberToAdd) {
//start at 1
float currentNumberToAdd = 1;
//keep track of your total sum
float totalSoFar = 0;
//loop 1,2,3...maxNumberToAdd
while (currentNumberToAdd <= maxNumberToAdd){
//add the current number to the total
totalSoFar = totalSoFar + currentNumberToAdd;
//go to the next number to add
currentNumberToAdd++;
}
//return the total
return totalSoFar;
}
Now that you have that, you can think about modifying it to do your next task.
You say you want to start at 0 instead of 1. Find the line of code responsible for starting at 1. What happens if you change it to something else?
You say you want to add only every 4th number. Find the line of code responsible for going to the next number. What happens if you increase it by something other than 1?

Optimized search - can anyone help to calculate the complexity of this algorithm

when I looked at the binary search algorithm. I have a feeling that the search point might be optimized by not always looking at the middle point. For example, if we are looking up a word in dictionary without looking at the menu, we will not always turn to the middle page to compare. If the word starts with 'A', we will expect it at near the beginning. If it starts with 'Z', we will definitely try with the pages at the end.
But, always using the density of the current target array will cause some significant issue if the density of the array changes drastically, which will result the algorithm ends up with a near O(n) complexity in some instances. Thus I calculated the density based on previous search, and always calculates density from the smaller divide. And calculates the search point always from previous search point. In that, it mitigates the impact of changing density.
So I wrote this code trying to generate an optimized search. I haven't tested it (not even compiled yet). But I guess it explains the algorithm:
public int OptimizedSearch(int a[], int target) {
return OptimizedSearch(a, target, 0, a.size(), 0, true);
}
public int OptimizedSearch(int a[], int target, int start, int end, double density, boolean fromStart) {
// Since density is different from the density in current target array, the search point calculated from density will
// always start from last search point. fromStart records whether the last search point happens at start or end of
// current array
if (0 == density) { //Initial density
density = (a[end] - a[start]) / (end - start);
}
int searchPoint;
if (fromStart) {
searchPoint = start + ((target - a[start]) / density).intValue();
}
else {
searchPoint = end - ((a[end] - target) / density).intValue();
}
if (a[searchPoint] == target) {
return searchPoint;
}
else if (target < a[searchPoint]) {
double currentDensity;
if (end - searchPoint > searchPoint - start) {
currentDensity = (a[searchPoint] - a[start]) / (searchPoint - start);
}
else {
currentDensity = (a[end] - a[searchPoint]) / (end - searchPoint);
} //Density is always calculated from the smaller part since it will be more accurate.
return OptimizedSearch(a, target, start, searchPoint - 1, currentDensity, false);
}
else {
double currentDensity;
if (end - searchPoint > searchPoint - start) {
currentDensity = (a[searchPoint] - a[start]) / (searchPoint - start);
}
else {
currentDensity = (a[end] - a[searchPoint]) / (end - searchPoint);
} //Density is always calculated from the smaller part since it will be more accurate.
return OptimizedSearch(a, target, searchPoint + 1, end, currentDensity, true);
}
}
But I really find it hard to calculate the complexity. I have a feeling it should be lower than log(N), but I can't prove it. Can someone help with it?
This an implementation of interpolation search and if the approximation of the distribution of the elements is good enough it has complexity log(log(n)). It is far from trivial to prove that, though.

Algorithm for line-breaking text (Wrap text to fit 'page')

I've developed a few GUI-oriented applications that implement their own text line-breaking algorithms. For example, consider that my applications consist of typical GUI "widgets" that can be laid out on a screen. Widgets such as checkboxes, textfields, simple labels, etc, are fairly easy to draw. However, a widget such as a "paragraph" (an arbitrary amount of multiline text, which should be fit into a specified box, with line-breaking occurring as necessary) is much more difficult owing to the, well, line-breaking part.
Every time I've implemented such an algorithm, I've used an approach that's worked but has been pretty inefficient. My general approach (to fit a string into a box with width w) has been to iteratively take a string s, use font metrics to measure its pixel length l, and whittle away at it until l <= w. Then the remainder is assigned to s, and I repeat the process until I'm left with a value of s that's less than or equal to w.
At the bottom of this is a Javascript example (which admittedly probably isn't the best environment in which to be doing this sort of thing). This code would be part of the aforementioned "paragraph" widget, and is written for the HTML5 Canvas API (ctx is the Canvas' graphics context). Clearly, the Big-O analysis of this approach is pretty poor. But... is there a better way to do this sort of thing? I'm assuming it depends somewhat on the environment in which we're working. But I also assume that given the number of text-editing tools that exist, an efficient solution exists out there.
// the paragraph widgets' main drawing function
this.drawText = function(ctx) {
...
var lines = this.text.split("\n"); // here we account for user-entered line breaks
var y = this.y;
for (var i=0; i<lines.length; i++) {
var currTxt = lines[i]; // a chunk of text in between user-entered line breaks
var miniLines = this.breakToLines(currTxt, this.textWidth(), ctx);
for (var j = 0; j < miniLines.length; j++) {
var miniTxt = miniLines[j];
var x = this.x + ( (this.round) ? this.cornerRadius : 0 );
x += this.textOffset();
y += this.fontSize;
ctx.save();
ctx.rect(this.x, this.y, this.width, this.height);
ctx.clip();
ctx.fillText(miniTxt, x, y);
ctx.restore();
}
};
};
// take a chunk of text and break it into lines that fit within width 'w'
this.breakToLines = function(txt, w, ctx) {
var arr = [];
while (true) {
var txt2 = this.popLine(txt, w, ctx);
if (txt2 == null)
break;
arr.push(txt2);
if (txt.length <= txt2.length)
break;
txt = txt.substring(txt2.length);
}
return arr;
};
this.popLine = function(txt, w, ctx) {
var m = ctx.measureText(txt); // 'm' represents the size of the text
if (m.length == 0)
return null; // 'm' is empty, so we're done
while (m.width > w) {
// remove a word from txt and re-measure it
txt = txt.substring(0, txt.lastIndexOf(' '));
m = ctx.measureText(txt);
}
return txt;
};
I wonder if the text metrics give reliable results when measuring the size of a word followed by a space. For example, does width( "aaa " ) + width( "bbb" ) = width( "aaa bbb" )? If so you can measure each word in the text, with and without a space after it, and figure the rest out from there. Plan B (assuming that text metrics for a word followed by a space doesn't give precise results) is to measure each word without the space, and use a fixed value to estimate the space between words.
The inefficiency in the current algorithm, as I see it, is that you're calling the measureText method O(n^2) times, and you're measuring the width of long strings. By breaking the text into words and measuring each word, you would only call measureText O(n) times, and you would be calling it on relatively short strings.
The proposed algorithm then is to start at the beginning of each line and add words until the wrap limit is reached. This additive approach to the problem reduces the number of strings that must be measured, as well as reducing the length of the strings that must measured.

Efficiently implementing erode/dilate

So normally and very inefficiently min/max filter is implemented by using four for loops.
for( index1 < dy ) { // y loop
for( index2 < dx ) { // x loop
for( index3 < StructuringElement.dy() ) { // kernel y
for( index4 < StructuringElement.dx() ) { // kernel x
pixel = src(index3+index4);
val = (pixel > val) ? pixel : val; // max
}
}
dst(index2, index1) = val;
}
}
However this approach is damn inefficient since it checks again previously checked values. So I am wondering what methods are there to implement this with using previously checked values on next iteration?
Any assumptions regarding structuring element size/point of origin can be made.
Update: I am especially keen to know any insights of this or kind of implementation: http://dl.acm.org/citation.cfm?id=2114689
I have been following this question for some time, hoping someone would write a fleshed-out answer, since I am pondering the same problem.
Here is my own attempt so far; I have not tested this, but I think you can do repeated dilation and erosion with any structuring element, by only accessing each pixel twice:
Assumptions: Assume the structuring element/kernel is a KxL rectangle and the image is a NxM rectangle. Assume that K and L are odd.
The basic approach you outlined has four for loops and takes O(K*L*N*M) time to complete.
Often you want to dilate repeatedly with the same kernel, so the time is again multiplied by the desired number of dilations.
I have three basic ideas for speeding up the dilation:
dilation by a KxL kernel is equal to dilation by a Kx1 kernel followed by dilation by a 1xL kernel. You can do both of these dilations with only three for loops, in O(KNM) and O(LNM)
However you can do a dilation with a Kx1 kernel much faster: You only need to access each pixel once. For this you need a particular data structure, explained below. This allows you to do a single dilation in O(N*M), regardless of the kernel size
repeated dilation by a Kx1 kernel is equal to a single dilation by a larger kernel. If you dilate P times with a Kx1 kernel, this is equal to a single dilation with a ((K-1)*P + 1) x 1 kernel.
So you can do repeated dilation with any kernel size in a single pass, in O(N*M) time.
Now for a detailed description of step 2.
You need a queue with the following properties:
push an element to the back of the queue in constant time.
pop an element from the front of the queue in constant time.
query the current smallest or largest element in the queue in constant time.
How to build such a queue is described in this stackoverflow answer: Implement a queue in which push_rear(), pop_front() and get_min() are all constant time operations.
Unfortunately not much pseudocode, but the basic idea seems sound.
Using such a queue, you can calculate a Kx1 dilation in a single pass:
Assert(StructuringElement.dy()==1);
int kernel_half = (StructuringElement.dx()-1) /2;
for( y < dy ) { // y loop
for( x <= kernel_half ) { // initialize the queue
queue.Push(src(x, y));
}
for( x < dx ) { // x loop
// get the current maximum of all values in the queue
dst(x, y) = queue.GetMaximum();
// remove the first pixel from the queue
if (x > kernel_half)
queue.Pop();
// add the next pixel to the queue
if (x < dx - kernel_half)
queue.Push(src(x + kernel_half, y));
}
}
The only approach I can think of is to buffer the maximum pixel values and the rows in which they are found so that you only have to do the full iteration over a kernel sized row/column when the maximum is no longer under it.
In the following C-like pseudo code, I have assumed signed integers, 2d row-major arrays for the source and destination and a rectangular kernel over [±dx, ±dy].
//initialise the maxima and their row positions
for(x=0; x < nx; ++x)
{
row[x] = -1;
buf[x] = 0;
}
for(sy=0; sy < ny; ++sy)
{
//update the maxima and their row positions
for(x=0; x < nx; ++x)
{
if(row[x] < max(sy-dy, 0))
{
//maximum out of scope, search column
row[x] = max(sy-dy, 0);
buf[x] = src[row[x]][x];
for(y=row[x]+1; y <= min(sy+dy, ny-1); ++y)
{
if(src[y][x]>=buf[x])
{
row[x] = y;
buf[x] = src[y][x];
}
}
}
else
{
//maximum in scope, check latest value
y = min(sy+dy, ny-1);
if(src[y][x] >= buf[x])
{
row[x] = y;
buf[x] = src[y][x];
}
}
}
//initialise maximum column position
col = -1;
for(sx=0; sx < nx; ++sx)
{
//update maximum column position
if(col<max(sx-dx, 0))
{
//maximum out of scope, search buffer
col = max(sx-dx, 0);
for(x=col+1; x <= min(sx+dx, nx-1); ++x)
{
if(buf[x] >= buf[col]) col = x;
}
}
else
{
//maximum in scope, check latest value
x = min(sx+dx, nx-1);
if(buf[x] >= buf[col]) col = x;
}
//assign maximum to destination
dest[sy][sx] = buf[col];
}
}
The worst case performance occurs when the source goes smoothly from a maximum at the top left to a minimum at the bottom right, forcing a full row or column scan at each step (although it's still more efficient than the original nested loops).
I would expect average case performance to be much better though, since regions containing increasing values (both row and column wise) will update the maximum before a scan is required.
That said, not having actually tested it I'd recommend that you run a few benchmarks rather than trust my gut feeling!
a theoretical way of improving the complexity would be to maintain a BST for the KxK pixels, delete previsous Kx1 pixels and add the next Kx1 pixels to it. The cost of this operation would be 2K log K and it would be repeated NxN times. Overall the computation time would become NxNxKxlog K from NxNxKxK
Same kind of optimizations can be used as "non maximum suppression" algorithms
http://www.vision.ee.ethz.ch/publications/papers/proceedings/eth_biwi_00446.pdf
In 1D, using morphological wavelet transform in O(N) :
https://gist.github.com/matovitch/11206318
You could get O(N * M) in 2D. HugoRune solution is way simpler and probably faster (though this one could probably be improved).

Resources