The concept of feasible computation aims at those features and capacities of methods and algorithms for computing that are effective, applicable and reliable in the ordinary conditions of life. In practical circumstances, we care not only that a problem has an algorithmic solution in principle, but that it is solvable within the context in which the problem arises. This means that within natural variations of conditions, the solutions generated must continue to be valid or correct, and that solutions are produced sufficiently quickly for the context. It is efficient and reliable computability under the practical constraints of the context that feasible computation connotes.

Given a computational problem, contextual needs place certain constraints on what constitutes an acceptable solution and an acceptable computational cost. The nature of the problem will determine what counts as an acceptable solution. Algorithmic theorem verification, for instance, requires that a rigorous proof be constructed. Mathematical models of real world phenomena, however, being subject to various forms of error, can accept a range of valid approximate solutions. What counts as an acceptable computational cost is determined by the nature of the problem-solving context, which introduces various types of constraints. These constraints include conceptual, mathematical, programming, hardware, electricity use, financial and human resource limitations, as well as what other algorithms are already available for the given problem.

Thus, whether a problem is feasibly solvable depends on what counts as feasible (sufficiently reliable and efficient) given the constraints of a problem-solving context. What counts as a reliable computation can also vary depending on the context. In some cases, with image recognition for example, it may be acceptable to have a machine learning algorithm that is 80% accurate on images of a certain type, since, say, the algorithm will only be used on images of that type and an 80% success rate is deemed acceptable. For financial software distributed globally, on the other hand, no level of error is acceptable, and the result of computation must be independent of context.

Moreover, a problem that is infeasiblly solvable can become feasible by reformulating the problem. Since the computational problem itself is also a product of a context, it can be influenced by contextual constraints. Initially it might seem desirable to use exact methods of solution for a computational design problem. But if the available exact algorithms are too expensive, and a computationally cheaper approximate method is available that introduces sufficiently small error, the practical problem becomes feasibly computable by changing its formulation as a computational problem.

We see, therefore, that feasible computation picks out an experiential condition on computational reliability and complexity, in the sense that a feasible problem-solving method ensures the experience of reliable and efficient solutions where that method is deployed. Taking efficiency and reliability into account in the process of algorithm design and implementation is then seen to promote such experiences.

As computers become more and more embedded in every aspect of our global society, and users increasingly tend to trust the results of computation, the results of computation have greater and greater influence on our beliefs and decisions. As a result, the need for feasible algorithms is becoming increasingly important in our lives.

We will generate the fractal from the Mandlebrot set by iterating the map

\[ f(z)=z^2-\tau, \]

for a range of complex numbers \(\tau\), taking \(z=-\tau\) as the initial value. The colouring of a particular value of \(\tau\) is determined by the rate at which the iteration diverges, i.e., such that the size of \(z\) gets larger and larger without bound, where the size of a complex number \(z=x+iy\)) is measured by \(|x|^2+|y|^2\).

For those unfamiliar with complex numbers, for our purposes here it may suffice to think of a complex number \(z=x+iy\) as a point \((x,y)\) in the plane, so that \(x\) and \(y\) are the coordinates of the complex number in the plane and the size of a complex number is its distance from the origin.

We generate the fractal by choosing values of \(tau\) on an \(n\times n\) grid (I chose \(\texttt{n}=600\)) and then computing how many iterations of \(f\) it takes for \(z\) to become larger than some large number, the tolerance \(\texttt{tol}\) (I chose \(\texttt{tol}=10^6\)).

So that this computation doesn't go on for ever, we stop if \(z\) hasn't gotten larger than \(\texttt{tol}\) after some maximum number of iterations (I chose \(\texttt{its}=80\)). If it never passes this value it is taken to be a "fixed point" and is coloured at one end of the colour scale. If it passes the tolerance \(\texttt{tol}\) for some number of iterations \(\texttt{m}\) less than \(\texttt{its}\) then we colour the point based on the value of \(\texttt{m}\).

The faster the divergence the smaller \(\texttt{m}\) is, and the more red (in our chosen colour space) the point will be.

Overall, then, for a complex number \(\tau=x+iy\) (point \((x,y)\) in the plane), where we restrict attention to that part of the plane such that \(x\) is in the range \([-1,2.25]\) and \(y\) is in the range \([-1.5,1.5]\), we compute the number of iterations \(\texttt{m}\) it takes for \(z=z^2-\tau\) (starting with \(z=-\tau\)) to grow larger in size, i.e., larger in distance from the origin, than the tolerance \(\texttt{tol}\), which determines the colour of the point.

Executing the script to make the fractal image is easy. To execute the script below, copy the code below into a text editor and save the file as "mandelbrot.m". Then, open a command line terminal and, when you are in the directory where you saved the file, type

octave mandelbrot.m

and wait for the computation to complete. You may want to reduce the number \(\texttt{n}\) of points the first time you run it to be sure that everything is working.

Once the script completes, which will take a while depending on your machinery, you should find a pdf copy of the image you computed called "mandelbrot.pdf". It should look like this:

If you would prefer a jpg output, you can change the last line of the script to

\(\texttt{print -djpg "mandelbrot.jpg"}\)

Now you can explore the Mandelbrot set by changing the \(x\) and \(y\) ranges and creating new images. Remeber to change the pdf filename so you don't copy over your old images!

As an illustration of the manner in which you can explore by changing the range of the points you compute, here is an animated gif of images generated by modifying this script that "zooms in" to the Mandelbrot set.

Keep in mind that the more you zoom in the slower, generally, the convergence, so you need to make adjustments so that your computations do not take too long.