Which FFT algorithm does this code use? - php

I found it online and there are no comments.
It comes with a Complex.class that basically simulates complex numbers and their operations.
I'd like to comment it myself but I really can't identify which algorithm is being used. I went online and found that the Cooley-Tukey algorithm is the most widespread, but I'm not sure that this code uses it.
private $dim;
private $p;
private $ind;
private $func;
private $w1;
private $w1i;
private $w2;
public function __construct($dim) {
$this->dim = $dim;
$this->p = log($this->dim, 2);
}
public function fft($func) {
$this->func = $func;
// Copying func in w1 as a complex.
for ($i = 0; $i < $this->dim; $i++)
$this->w1[$i] = new Complex($func[$i], 0);
$w[0] = new Complex(1, 0);
$w[1] = new Complex(cos((-2 * M_PI) / $this->dim), sin((-2 * M_PI) / $this->dim));
for ($i = 2; $i < $this->dim; $i++)
$w[$i] = Complex::Cmul($w[$i-1], $w[1]);
return $this->calculate($w);
}
private function calculate($w) {
$k = 1;
$ind[0] = 0;
for ($j = 0; $j < $this->p; $j++) {
for ($i = 0; $i < $k; $i++) {
$ind[$i] *= 2;
$ind[$i+$k] = $ind[$i] + 1;
}
$k *= 2;
}
for ($i = 0; $i < $this->p; $i++) {
$indw = 0;
for ($j = 0; $j < pow(2, $i); $j++) {
$inf = ($this->dim / pow(2, $i)) * $j;
$sup = (($this->dim / pow(2, $i)) * ($j+1)) - 1;
$comp = ($this->dim / pow(2, $i)) / 2;
for ($k = $inf; $k <= floor($inf+(($sup-$inf)/2)); $k++)
$this->w2[$k] = Complex::Cadd(Complex::Cmul($this->w1[$k], $w[0]), Complex::Cmul($this->w1[$k+$comp], $w[$ind[$indw]]));
$indw++;
for ($k = floor($inf+(($sup-$inf)/2)+1); $k <= $sup; $k++)
$this->w2[$k] = Complex::Cadd(Complex::Cmul($this->w1[$k], $w[$ind[$indw]]), Complex::Cmul($this->w1[$k-$comp], $w[0]));
$indw++;
}
for($j = 0; $j < $this->dim; $j++)
$this->w1[$j] = $this->w2[$j];
}
for ($i = 0; $i < $this->dim; $i++)
$this->w1[$i] = $this->w2[$ind[$i]];
return $this->w1;
}

This is a radix 2 FFT implementation based on the Cooley-Tukey algorithm, with the work being done in the function "compute". It will only work with FFT lengths that are a power of 2, although I don't see any parameter checking in the function itself.
$i iterates over the multiple FFT passes (of which there are log2(N) where N is the length of the FFT), and in each pass, the twiddle factors (stored in $w) are multiplied by the output from the previous stage before finding the complex sum and difference.
There are much better implementations of FFTs out there, such as FFTW, that implement a mixed radix approach, which allow an arbitrary length of FFT to be computed.

Related

Convert array outputted from DCT to an image in PHP

Using the following code I can get the DCT of an image in PHP. Then I need to convert this back in to the compressed image. How can I achieve that?
<?php
$results = array();
$image1 = "baboon.jpg";
$ima = ImageCreateFromJPEG($image1);
$N1 = imagesx($ima);
$N2 = imagesy($ima);
$rows = array();
$row = array();
for ($j = 0; $j < $N2; $j++) {
for ($i = 0; $i < $N1; $i++)
$row[$i] = imagecolorat($ima, $i, $j);
$rows[$j] = dct1D($row);
}
for ($i = 0; $i < $N1; $i++) {
for ($j = 0; $j < $N2; $j++)
$col[$j] = $rows[$j][$i];
$results[$i] = dct1D($col);
}
print_r($results);
function dct1D($in) {
$results = array();
$N = count($in);
for ($k = 0; $k < $N; $k++) {
$sum = 0;
for ($n = 0; $n < $N; $n++) {
$sum += $in[$n] * cos($k * pi() * ($n + 0.5) / ($N));
}
$sum *= sqrt(2 / $N);
if ($k == 0) {
$sum *= 1 / sqrt(2);
}
$results[$k] = $sum;
}
return $results;
}
?>
Also I need to know how can I add some extra details like another message to this image too.. (image steganography). Please help. Thanks

Gaussian elimination has to give back multiple solutions php

I want to use gaussian elimination to solve the following matrix Matrix and this is the answer I'm expecting. I would like to get back an equation in the form as is displayed in answer but i can't figure out how to do it.
public function gauss($A, $x) {
# Just make a single matrix
for ($i=0; $i < count($A); $i++) {
$A[$i][] = $x[$i];
}
$n = count($A);
for ($i=0; $i < $n; $i++) {
# Search for maximum in this column
$maxEl = abs($A[$i][$i]);
$maxRow = $i;
for ($k=$i+1; $k < $n; $k++) {
if (abs($A[$k][$i]) > $maxEl) {
$maxEl = abs($A[$k][$i]);
$maxRow = $k;
}
}
# Swap maximum row with current row (column by column)
for ($k=$i; $k < $n+1; $k++) {
$tmp = $A[$maxRow][$k];
$A[$maxRow][$k] = $A[$i][$k];
$A[$i][$k] = $tmp;
}
# Make all rows below this one 0 in current column
for ($k=$i+1; $k < $n; $k++) {
$c = -$A[$k][$i]/$A[$i][$i];
for ($j=$i; $j < $n+1; $j++) {
if ($i==$j) {
$A[$k][$j] = 0;
} else {
$A[$k][$j] += $c * $A[$i][$j];
}
}
}
}
# Solve equation Ax=b for an upper triangular matrix $A
$x = array_fill(0, $n, 0);
for ($i=$n-1; $i > -1; $i--) {
$x[$i] = $A[$i][$n]/$A[$i][$i];
for ($k=$i-1; $k > -1; $k--) {
$A[$k][$n] -= $A[$k][$i] * $x[$i];
}
}
return $x;
}
I hope someone can help me to rewrite this code so it gives the solution i've provided or recommend a library which is capable of doing this.
I've searched for possible solutions on Google but haven't been able to find one yet.
Thanks in advance.

PHP calculate combinations of a string depends on a character string

This is the scenario:
There is characterstring like this:
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
And I have a method that generates a random string with a variable length depends on the characters variable:
public function generateCodes($length, $qty)
{
$codes = [];
if ($length > 0 && $qty > 0) {
for ($i = 0; $i < $qty; $i++) {
$code = '';
for ($i = 0; $i < $length; $i++) {
$code .= $characters[mt_rand(0, strlen($characters) - 1)];
if (!in_array($code, $codes)) {
$codes[] = $code;
}
}
}
}
}
What I want is to calculate the possible unique codes for a specific $length. But how can I reach this?
This is my attempt so far - but I do not consider something important.
public function calculateCombinations($length)
{
$combinations = 0;
if ($length > 0) {
for ($i = 0; $i < $length; $i++) {
$combinations = $combinations + pow(2, $length -1);
}
}
return $combinations;
}
What is the right formula for this?
Thanks in advance!

Levenshtein distance with back tracing in PHP

I'm trying to align strings in PHP using Levenshtein distance algorithm. The problem is that my back tracing code does not work properly for all cases. For example when the second array has inserted lines at the beginning. Then the back tracing will only go as far as when i=0.
How to properly implement back tracing for Levenshtein distance?
Levenshtein distance, $s and $t are arrays of strings (rows)
function match_rows($s, $t)
{
$m = count($s);
$n = count($t);
for($i = 0; $i <= $m; $i++) $d[$i][0] = $i;
for($j = 0; $j <= $n; $j++) $d[0][$j] = $j;
for($i = 1; $i <= $m; $i++)
{
for($j = 1; $j <= $n; $j++)
{
if($s[$i-1] == $t[$j-1])
{
$d[$i][$j] = $d[$i-1][$j-1];
}
else
{
$d[$i][$j] = min($d[$i-1][$j], $d[$i][$j-1], $d[$i-1][$j-1]) + 1;
}
}
}
// backtrace
$i = $m;
$j = $n;
while($i > 0 && $j > 0)
{
$min = min($d[$i-1][$j], $d[$i][$j-1], $d[$i-1][$j-1]);
switch($min)
{
// equal or substitution
case($d[$i-1][$j-1]):
if($d[$i][$j] != $d[$i-1][$j-1])
{
// substitution
$sub['i'][] = $i;
$sub['j'][] = $j;
}
$i = $i - 1;
$j = $j - 1;
break;
// insertion
case($d[$i][$j-1]):
$ins[] = $j;
$j = $j - 1;
break;
// deletion
case($d[$i-1][$j]):
$del[] = $i;
$i = $i - 1;
break;
}
}
This is not to be nit-picky, but to help you find the answers you want (and improve your implementation).
The algorithm you are using is the Wagner-Fischer algorithm, not the Levenshtein algorithm. Also, Levenshtein distance is not use to align strings. It is strictly a distance measurement.
There are two types of alignment: global and local. Global alignment is used to minimize the distance between two entire strings. Example: global align "RACE" on "REACH", you get "RxACx". The x's are gaps.
In general, this is the Needleman-Wunsch algorithm, which is very similar to the Wagner-Fischer algorithm. Local alignment finds a substring in a long string and minimizes the difference between a short string and a the substring of the long string.
Example: local align "BELL" on "UMBRELLA" and you get "BxELL" aligned on "BRELL". It is the Smith-Waterman algorithm which, again, is very similar to the Wagner-Fischer algorithm.
I hope that this is helpful in allowing you to better define the exact kind of alignment you want.
I think your bug is exactly what you say in your question that it is: you stop as soon as i==0, instead of going all the way to i==0 && j==0. Simply replace this condition:
while($i > 0 && $j > 0)
with
while ($i > 0 || $j > 0)
and you're halfway to your solution. The tricky bit is that if $i==0, then it's incorrect to use the array index $i-1 in the loop body. So you'll also have to change the body of the loop to something more like
while ($i || $j) {
$min = $d[$i][$j]; // or INT_MAX or something
if ($i && $j && $min > $d[$i-1][$j-1]) {
$newi = $i-1;
$newj = $j-1;
$min = $d[$newi][$newj];
}
if ($i && $min > $d[$i-1][$j]) {
$newi = $i-1;
$newj = $j;
$min = $d[$newi][$newj];
}
if ($j && $min > $d[$i][$j-1]) {
$newi = $i;
$newj = $j-1;
$min = $d[$newi][$newj];
}
// What sort of transformation is this?
if ($newi == $i && $newj == $j) {
assert(false); // should never happen
} else if ($newi == $i) {
// insertion
$ins[] = $j;
} else if ($newj == $j) {
// deletion
$del[] = $i;
} else if ($d[$i][$j] != $d[$newi][$newj]) {
// substitution
$sub['i'][] = $i;
$sub['j'][] = $j;
} else {
// identity
}
assert($newi >= 0); assert($newj >= 0);
$i = $newi;
$j = $newj;
}

Is there a PHP Fleiss' Kappa implementation?

I'm looking for a PHP implementation of Fleiss' Kappa that is publicly available. So far, I found some classes written in Java, Perl, Ruby and Python, but nothing in PHP.
Do you have any idea or suggestion?
Thanks!
Because I needed it too, I wrote this function:
function fleissKappa($table){
/*
* author Tom Aizenberg
*
* $table is an n x m array containing the classification counts
*
* adapted from the example in en.wikipedia.org/wiki/Fleiss'_kappa
*
*/
$subjects = count($table);
$classes = count($table[0]);
$raters = array_sum($table[0]);
for($q = 1; $q < count($table); $q++){
if(count($table[$q])!=$classes){
print("no equal number of classes.");
exit(0);
}
if(array_sum($table[$q])!=$raters){
print("no equal number of raters.");
exit(0);
}
}
$pj = array();
$pi = array();
for($j = 0; $j < $subjects; $j++){
$pi[$j] =0;
}
for($i = 0; $i < $classes; $i++){
$tpj = 0;
for($j = 0; $j < $subjects; $j++){
$tpj += $table[$j][$i];
$pi[$j] += $table[$j][$i]*$table[$j][$i];
}
$pj[$i] = $tpj/($raters*$subjects);
}
for($j = 0; $j < $subjects; $j++){
$pi[$j] = $pi[$j]-$raters;
$pi[$j] = $pi[$j]*(1/($raters*($raters-1)));
}
$pcarret = array_sum($pi)/$subjects;
$pecarret = 0;
for($i = 0; $i < count($pj);$i++){
$pecarret += $pj[$i]*$pj[$i];
}
$kappa = ($pcarret-$pecarret)/(1-$pecarret);
return $kappa;
}
Test it:
$test = array(
array(0,0,0,0,14),
array(0,2,6,4,2),
array(0,0,3,5,6),
array(0,3,9,2,0),
array(2,2,8,1,1),
array(7,7,0,0,0),
array(3,2,6,3,0),
array(2,5,3,2,2),
array(6,5,2,1,0),
array(0,2,2,3,7));
print(fleissKappa($test));

Categories