public interface IterativeArrayProcessor<T> extends ArrayProcessor
An iterative algorithm processing some AlgART array (arrays) or matrix (matrices).
This abstraction describes any algorithm, processing AlgART arrays or matrices..
Processing starts from creating an instance of this interface, usually associated with
some source array or matrix and implementing some processing algorithm.
Then the loop of iterations
is performed,
until the booleam flag done
will be set to true.
Usually, each iteration modifies some AlgART array or matrix, and the flag done means
that further modifications are impossible.
Last, the result of calculations is returned by result()
method.
The type of the result is the generic parameter of this interface; usually it is UpdatableArray
or Matrix
<? extends UpdatableArray
>.
Using of this interface is more convenient than manual programming the loop of iterations. Typical scheme of using this interface is the following:
IterativeArrayProcessor
<UpdatablePArray
> imp = some_generation_method(array_context
, processed_array, algorithm_settings);UpdatablePArray
result = imp.process()
; imp.freeResources
(null); // not necessary usually
The process()
method organizes necessary loop and performs all "boring" work
connected with controling the context. In particular, it tries to estimate necessary number of iterations
and calls performIteration(ArrayContext)
method with the corresponding
subcontext
of the processor's context
,
that allows correct showing the progress bar in the application.
Moreover, there is an ability to automatically create "chains
" of several algorithms.
To implement new iterative algorithm, it is enough to implement the following methods:
performIteration(ArrayContext context)
,done()
,estimatedNumberOfIterations()
,result()
,freeResources(ArrayContext)
.All other methods are usually inherited from AbstractIterativeArrayProcessor
class.
Implementations of this interface are threadcompatible (allow manual synchronization for multithread access). Without external synchronization, the methods of this interface may return unspecified results while simultaneous accessing the same instance from several threads.
Modifier and Type  Method and Description 

IterativeArrayProcessor<T> 
chain(IterativeArrayProcessor<T> followingProcessor,
double weight)
Returns new object, implementing this interface, equivalent to the chain of this algorithm
and followingProcessor algorithm, executed after this.

boolean 
done()
Returns true if and only if the algorithm was successfully finished and there is
no sense to perform further iterations.

long 
estimatedNumberOfIterations()
Estimates the number of iterations, that should be performed from this moment to finish the algorithm.

void 
freeResources(ArrayContext context)
If there are some resources, allocated by this object, which are not controlled
by Java garbage collectors — files, streams, sockets, locks, etc. —
this method tries to release them (for example, to close any files).

IterativeArrayProcessor<T> 
limitIterations(long maxNumberOfIterations)
Returns new object, implementing this interface, equivalent to this algorithm
with the only difference that the number of performed iterations does not exceed
the specified argument.

void 
performIteration(ArrayContext context)
Performs the next iteration of the iterative algorithm.

T 
process()
Performs a loop of calls of
performIteration method, while
done() method returns false. 
T 
result()
Returns the result of the previous iteration.

context
void performIteration(ArrayContext context)
done()
, the results are unspecified:
please never call this method if done()
returns true.
You usually don't need to call this method: please call
process()
instead.
If you need to perform only one or n iterations, you may use
limitIterations(n)
call.
Warning: this method should ignore the current execution context
of this object.
Instead, this method should use the context of execution specified by context argument.
This method is called by process()
method with the argument,
describing a subtrask
of the full algorithm.
The context argument may be null:
this method should work properly in this case (ignore the context).
This method must be implemented while creating a new iterative arrayprocessing algorithm.
context
 the context used by this instance for all operations; may be null.boolean done()
This method usually does not perform actual calculations and works very quickly (just returns and internal flag). However, this condition is not strict.
You usually don't need to call this method: it is automatically called by
process()
method.
This method must be implemented while creating a new iterative arrayprocessing algorithm.
long estimatedNumberOfIterations()
This method may require some time for its execution.
You usually don't need to call this method: it is automatically called from time to time by
process()
method.
It is used for creating subcontexts, describing a part
of the full task.
This method must be implemented while creating a new iterative arrayprocessing algorithm.
T result()
UpdatableArray
or
Matrix
<? extends UpdatableArray
>.
This method returns valid result even if no iterations were performed yet.
If done()
method returns true, the result of this method
is the final result of iterative processing performed by this instance.
This method may return null. In this case, the concrete implementation of this interface should provide additional methods for returning calculation results.
This method does not perform actual calculations and works very quickly.
This method must be implemented while creating a new iterative arrayprocessing algorithm.
void freeResources(ArrayContext context)
Usually, this method just calls
Array.freeResources(context)
and
Matrix.freeResources(context)
for all temporary arrays and matrices, allocated by this object for storing work data.
If result()
method returns AlgART array or matrix (typical situation),
this method calls Array.freeResources(context)
/
Matrix.freeResources(context)
methods
for this array / matrix.
This method may be used in situations when the instance of this object has long time life and will be reused in future.
This method must be implemented while creating a new iterative arrayprocessing algorithm.
context
 the context of execution; may be null, then it will be ignored.T process()
performIteration
method, while
done()
method returns false.
It is the main method of this interface, used by application.
This method uses its current context
to create an array context, that will be passed
to performIteration(ArrayContext)
method. The new context is made by
ArrayContext.part(double, double)
method, according to information
returned by estimatedNumberOfIterations()
.
If the current context
is null, this method pass null
to performIteration(ArrayContext)
.
The maxNumberOfIterations argument allows to restrict the total number of
calls of performIteration
,
that can be useful when the algorithm can work for very long time
(thousands or millions iterations).
If this argument is zero or positive,
this method will perform, as a maximum, maxNumberOfIterations iterations
(or less, if done()
will return true before this).
If it is zero, this method does nothing and immediately returns the result()
.
If it is negative, this argument is ignored.
result()
method after the last performed iteration).IterativeArrayProcessor<T> limitIterations(long maxNumberOfIterations)
More precisely:
current context
in the returned instance is equal
to the current context of this instance.performIteration(ArrayContext context)
in the returned instance always calls
thisInstance.performIteration
(context).done()
in the returned instance is equivalent to
count>=maxNumberOfIterationsthisInstance.done()
,
where count is the total number of performed calls of
performIteration
method.estimatedNumberOfIterations()
in the returned instance always returns
max(0,maxNumberOfIterationscount),
where count is the total number of performed calls of
performIteration
method.result()
in the returned instance always returns
!thisInstance.result()
.freeResources(context)
in the returned instance calls
thisInstance.freeResources(context)
.As a result, the basic process()
method in the returned instance
will perform, as a maximum, maxNumberOfIterations only.
In particular, if maxNumberOfIterations==0, process()
method does nothing
and immediately returns result()
object.
If maxNumberOfIterations<0, this method just returns the reference to this instance. In other words, negative maxNumberOfIterations means unlimited number of iterations.
maxNumberOfIterations
 the number of iterations, after which the done()
method
in the returned instance always returns true.IterativeArrayProcessor<T> chain(IterativeArrayProcessor<T> followingProcessor, double weight)
process()
method of the returned instance performs
iterations of this instance, while its done()
method returns false,
and then performs iterations of followingProcessor, while
followingProcessor.done()
method returns false.
More precisely:
current context
in the returned instance is equal
to the current context of this instance.performIteration(ArrayContext context)
in the returned instance calls
thisInstance.performIteration
(context), if
!thisInstance.done()
, or calls
followingProcessor.performIteration
(context) in other case.done()
in the returned instance is equivalent to
thisInstance.done()
&&followingProcessor.done()
.estimatedNumberOfIterations()
in the returned instance calls
n1=thisInstance.estimatedNumberOfIterations()
and
n2=followingProcessor.estimatedNumberOfIterations()
,
and returns n2 if thisInstance.done()
,
or, in other case, n1+Math.round(weight*n2), where weight
is the 2nd argument if this method. (If n1==0 or n2==0, 0 is returned.)
The necessity of the weight here is connected with the fact, that
the followingProcessor may return illegal results,
because this processor did not process the matrix yet.result()
in the returned instance returns
!thisInstance.done()
? thisInstance.result()
:
followingProcessor.result()
.freeResources(context)
in the returned instance calls
thisInstance.freeResources(c1)
and
followingProcessor.freeResources(c2)
,
where c1 and c2 are parts
of the passed context.It is obvious that both instances of iterative algorithms, this and followingProcessor,
must share the same processed data. In other words, followingProcessor
(its performIteration(ArrayContext)
and done()
methods) must
be able to "see" the results of execution of this processor.
To provide this, the constructors (or generation methods) of both instances
usually get a reference to the same updatable AlgART array or matrix,
storing the intermediate calculation results.
followingProcessor
 the next iterative algorithm, that should be performed after this will be done.weight
 the weight for estimated number of iterations
of the next algorithm,
used while first (this) one is not finished yet.java.lang.NullPointerException
 if followingProcessor argument is null.java.lang.IllegalArgumentException
 if weight argument is negative.