Progressions are sequences of numbers that are calculated based on the values of previous numbers in the sequence.
There are several types of math progressions.Sometimes the data collected by the programmer doesn't depend on his entire will.
His program thus most of time deal with sequences of numbers that he doesn't choose.Progressions can be useful for many applications
and PHP doesn't have a native progressions support.
This class can, not only allow to deal with progressions provided by the programmers themselves, but it can also take any sequence
of values and detect the type of its progression to make easy any further manipulations or analyzes.
The package can actually help to detect whether or not a sequence of numbers is arithmetic,geometric,arithmetico-geometric
Cauchy sequence ,Conway sequence ,Fibonacci,harmonic or Collatz sequence and reversed Conway natively.
It also provides the mean via an interface to add other detectors as plug-in to detect as many types of progression as wished.
One can add or remove detectors one by one or as array of detectors.
It also provides the mean to generate sequences for test or for education purposes: it actually provides static methods to generate custom
arithmetic,geometric,arithmetico-geometric ,Cauchy sequence ,Conway and reversed Conway sequence ,Fibonacci,harmonic or Collatz sequence natively.
How to use :
First be sure to include the right files where you want to handle progressions then you can create a new progression this way:
$x=new progression(1,2,3,4,5,6,7,8);
/*
or $x=progression(1,2,3,4,5,6,7,8)
or with array or even any iterable, provided that the values are numeric:
$x=progression(array(1,2,3,4,5,6,7,8));
$x=new progression([1,2,3,4,5,6,7,8)]); you can also use one of the static methods for specific type of progression;
$x=progression() or $x=new progression() will create an empty progression you can then use
$x(1,2,3,[12,5,6],$iterable) anyway to add values or the method $x->fill_with($iterable_only);
*/
then you can try to detect the type but first we must add the wished detectors as array of detectors or one by one :
$x->addDetector([
new reversed_conway($x),
new Conway($x),
new geometric($x),
new cauchy($x),
new collatz($x),
new fibonacci($x),
new arithmetic($x),
new arithmetico_geometric($x),
new harmonic($x)
]);
/* or
$x->addDetector(new reversed_conway($x));
$x->addDetector(new Conway($x));
$x->addDetector(new geometric($x));
$x->addDetector(new cauchy($x));
$x->addDetector(new collatz($x));
$x->addDetector(new fibonacci($x));
$x->addDetector(new arithmetic($x));
$x->addDetector(new arithmetico_geometric($x));
$x->addDetector(new harmonic($x));
you can add in one line all native detectors this way :
progression::add_native_detectors($x); //here $x is a reference to the progression of your choice;
you can also include all the native detectors file and the dependencies in one line this way :
progression::include_native_detectors(); //of course if you use an appropriate autoloader you don't need this nor include them one by one.
*/
You can also simply removed an previously added detector this way:
$x->removedDetector($detector_classname_in_lowercase);
Also note that even if you try to add the same detector multiple times it will only be added once
All detectors take in argument the current progression .Add other progression in argument of a detector
dedicated to another one, will produce no effect.
echo $x->detect_type();// this will print arithmetic
when no implemented type has been detected the detect_type method will just return 'unimplemented type';
just after the part you add your detectors
You can at any time use the other methods depending of the detection of the type of the progression object on any type of progression
without stress.Note that the native methods for generating common type of progression and even the randomNative method automatically
set the good type and automatically add the good detector class if the class exists in the script which called those methods.
The type if not manually detected is detected when needed only and cached and will be refreshed only if
some value have manually been inserted or added to the progression or a new detector has been added or if the current progression type has been removed.
These methods are :
$x->getNext() will predict and push if specified the next element of the progression
or return null if the current type of progression is unimplemented;
$x->getNth() will predict the nth element of the progression
or return null if the current type of progression is unimplemented;
$x->buildtoNth() will complete the progression until the nth element of the progression
or return null if the current type of progression is unknown;
$x->commondifference() will return the value of the eventual common difference
(specially in the cases arithmetic ,arithmetico-geometric,harmonic the value is not null
but for the other native implemented types yes.
if other types of detector are added, there is the mean to specify the common difference during the
detection in the method is() of each detector.
)
$x->commonratio() will return the value of the eventual common ratio
(specially in the cases arithmetico-geometric,geometric the value is not null
but for the other native implemented types yes.
if other types of detector are added, there is the mean to specify the common ratio during the
detection in the method is() of each detector.
)
The other methods are not dependent of the detection and can be used any time as wished
eg:
is_increasing() return true if the progression is increasing false if not (eg: 1,1,1,1,2,2,2,3,4,5,5,6,7,7 will return true)
is_strictly_increasing() (eg:1,1,1,1,2,2,2,3,4,5,5,6,7,7 will return false and 1,2,3,4,5,6,7,8,9 will return true)
is_decreasing() return true if the progression is decreasing false if not(eg:4,4,3,1,0 will return true)
is_strictly_decreasing() (eg:4,4,3,1,0 will return false but 4,3,1,0 will return true)
neitherDecreasingNorIncreasing same as neitherIncreasingNorDecreasing (will return true if the values are neither decreasing nor increasing)
max()
min()
avg() return the average of all values in the progression
sum()
product()
insert($offset,...$values) insert a value of a list of values anywhere in the progression
contains(...$values) return true only if the progression contains the specified values
fill_with(iterable $values)
etc....
You can get partial documentation on every methods directly in your script by using progression::help() to print all the methods
and their purpose in alphabetical or a partial documentation on a specific method using progression::help('the_method_name_here');
the progression object supports the conversion to string and will return a Json object
you can also use the PHP json_encode function directly on it .
Progression implements countable,SeekableIterator,ArrayAccess,JsonSerializable.
For a true how to use example see the file example.php
In order to make your custom detector works well please read carefully the other detectors implementations
as the parts you really need to change are few.Take the native implementations as models or you may encountered
some issues.
keep in my mind that even if it is really rare, a sequence of values can be of many different progression types and thus the order
of detectors count a lot:
eg:
$x=progression(1/8,1/16,1/32);
progression::add_native_detectors($x);
echo $x->detect_type()// print geometric; common ratio=0.5
$x->removeDetector('geometric');
echo $x->detect_type()// print collatz; common ratio=null common difference=null but 1/8%2===0 => 1/16%2===0 => 1/32%2===0 =>collatz without odd number
$x->removeDetector('collatz');
echo $x->detect_type()// print arithmetico-geometric; common ratio=0.5 common difference=0
So choose carefully the order of detectors to add them.
A good trick for you : the progression class allows you to use some aliased methods which do not really exist in the class statement but
which appear as long as you add new detectors. The semantic is simple
$object->is_{Name of your detector in lower case}();
eg:
suppose that you have just added the detector New_Curious_detector to your progression object
you can use as example
echo $object->is_new_curious_detector();//will print true on the screen if your progression is of this type.
The functioning is simple.When you call is_new_curious_detector() method, as it doesn't exists the __call method
is called at the place and there we just used the previous called method as a dynamic alias to call the method New_Curious_detector::is().
The only real limitation is that you can't use reference to get the common ratio or difference.The detector must really exist
and been added to your object to allow its usage otherwise the method will always return false without error.
Keep in mind that use this type of methods doesn't have any incidence on the progression properties and is just useful to
test just one detector instead of all while the other normal methods will eventually change properties like
type, common ratio and common difference.
Nb: never try to export a detector plug-in with var_export as the behavior implemented is only useful for the progression Class
You may also prefer to use the export method of the class progression instead of var_export to avoid eventual warning about
circular reference due to detectors added or just add the operator @ before the var_export statement.
Nb: Actually,the detection can be achieved only on progression containing at least 3 entries except for conway and reversed conway...
Nb:As every PHP developers know ,most of time, calculations with float numbers lead to precision lost and can then make the detection
failed .The package thus allows to use BC Math functions to preserve some precision in progression generation and detection
.To use BC Math in your calculation use this progression::use_bcmath(yourscalehere); Keep in mind that there is no way to disable
it in the script except by removing this line. So once activated all the calculations and detections methods usage after this statement
will use BC MAth functions .The default scale value is 32.
NB: you must keep in mind that some collected data can be corrupted while collecting them,so detection may failed in those cases due
to precision lost as mentioned above.To collect efficient data when the collected values are too large or too small it may be better
to use string notation to avoid imprecise roundness by PHP.You can thus in detection use BC Math as shown below. But with simple values
which are neither too small nor too large detection never failed provided that the good detector is added.
The Reversed Conway progression is uncommon and specific to this package.It is an experimental progression to show how to implement any Detector
plug-in to extend the package and thus allow more detected types.
You can use the forum for bug reporting and other.And don't forget to rate the package.
|