PHP Classes

File: matrix.php

Recommend this page to a friend!
  Classes of Amilton Junior   PHP Threads Class   matrix.php   Download  
File: matrix.php
Role: Example script
Content type: text/plain
Description: Example of usage
Class: PHP Threads Class
Run multiple tasks in parallel using HTTP requests
Author: By
Last change:
Date: 9 years ago
Size: 5,881 bytes
 

Contents

Class file image Download
<?php
/*
    File: matrix.php
    Description: Matrix multiplication example using CThreads library.
    Usage: Call from the browser this file.
    URL Parameters:
        threads - (int) number of threads (2 default)
        size - (int) size of the matrix (size x size) (4 default)
        print - (int) 1 to print out, 0 to not
   
    Author: Amilton de Camargo Jr. <amilton@dicasemgeral.com>
   
    Copyright (cc) 2014 - Amilton de Camargo Jr. <amilton@dicasemgeral.com>
*/

// Include CThreads library
require_once('CThreads.php');

///////// FUNCTIONS //////////

// Function that generates a matrix
// Arguments:
// (int) $size - Size of the matrix (size x size)
// (int) $rand_from - First number range
// (int) $rand_to - Last number range
// Return:
// (array) $matrix - Generated matrix
function GenerateMatrix($size=0, $rand_from=1, $rand_to=2)
{
   
// If it got an invalid size
   
if ( $size < 2 )
        return array();
   
   
$matrix = array();
   
   
// Generate the matrix
   
for ( $i=0; $i<$size; $i++ )
        for (
$j=0; $j<$size; $j++ )
           
$matrix[$i][$j] = ($rand_from == $rand_to) ? $rand_from : mt_rand($rand_from, $rand_to);
   
    return
$matrix;
}

// Function that prints a matrix
// Arguments:
// (array) $matrix - Matrix to be printed
// (int) $size - Matrix size
// Return:
// (void)
function PrintMatrix($matrix=array(), $size=0)
{
   
// If invalid arguments
   
if ( !is_array($matrix) || $size < 0 )
        return;
   
   
// Print the matrix
   
for ( $i=0; $i<$size; $i++ )
    {
        for (
$j=0; $j<$size; $j++ )
            echo
$matrix[$i][$j] . '&nbsp;&nbsp;&nbsp;';
       
        echo
'<br>';
    }
}

// Function to calculate a piece of a matrix
// Arguments:
// (array/int/float/String) $args - Arguments for the function
// Return:
// (array) $ret - Array with startpoint, endpoint, and result matrix
function Multiply($args)
{
   
// If not a valid argument
   
if ( !is_array($args) )
        return;
   
   
// Get the arguments
   
$t_number = $args['t_number']; // Thread ID
   
$size = $args['size']; // Matrix size
   
$threads = $args['threads']; // Number of threads
   
$first = $args['first']; // First matrix
   
$second = $args['second']; // Second matrix
   
$result = array(); // Result matrix (local)
   
   
if ( $threads > 1 )
    {
       
// Calculate the thread's boundaries
       
$rows = (int) ($size / $threads);
       
$start = (int) ($rows * $t_number);
       
$end = (int) ($start + $rows);
       
$dif = (int) ($size - ( $threads * $rows ));
       
       
// If it is the first thread and the matrix size is odd
       
if ( $t_number == 0 && $size % 2 != 0 && $dif > 0 )
           
$end += $dif;
    }
    else
    {
       
$start = 0;
       
$end = $size;
    }
   
   
// Perform the calculation
   
for ( $i=$start; $i<$end; $i++ )
        for(
$j=0; $j<$size; $j++ )
            for(
$k=0; $k<$size; $k++ )
               
$result[$i][$j] += $first[$i][$k] * $second[$k][$j]; // Save the result to the resultant matrix
   
    // Return the values
   
$ret = array();
   
$ret['start'] = $start;
   
$ret['end'] = $end;
   
$ret['result'] = $result;
   
    return
$ret;
}

// Get the result form all calculations and make the final matrix
// Arguments:
// (array) $results - Results from threads
// (int) $threads - Number of threads
// (int) $size - Matrix size
// Return:
// (array) $result - Result matrix from multiplication
function FinalResult($results=array(), $threads=0, $size=0)
{
   
$result = array();
   
    for (
$t=0; $t<$threads; $t++ )
    {
       
$start = $results[$t]['start'];
       
$end = $results[$t]['end'];
       
$res = $results[$t]['result'];
       
        for (
$i=$start; $i<$end; $i++ )
            for (
$j=0; $j<$size; $j++ )
               
$result[$i][$j] = $res[$i][$j];
    }
   
    return
$result;
}

//////////// MAIN PROGRAM /////////////

$threads = (isset($_GET['threads'])) ? (int) $_GET['threads'] : 2; // Number of threads
$m_size = (isset($_GET['size'])) ? (int) $_GET['size'] : 4; // Matrix size
$matrix1 = GenerateMatrix($m_size); // First matrix
$matrix2 = GenerateMatrix($m_size); // Second matrix
$result = array(); // Result of the multiplication
$thread_handle = new CThreads(); // Thread handles object
$printOut = (isset($_GET['print'])) ? (int) $_GET['print'] : true; // Boolean variable whether to print or not

// Print tha matrices
if ( $printOut )
{
    echo
'<b>Matrix Multiplication</b><br><br>';
    echo
'<table><tr><td>';
    echo
'Matrix 1:<br><br>';
   
PrintMatrix($matrix1, $m_size);
    echo
'</td><td width="50">&nbsp;</td><td>';
    echo
'Matrix 2:<br><br>';
   
PrintMatrix($matrix2, $m_size);
    echo
'</td></tr></table>';
}

echo
"<br>> Using {$threads} thread(s) to calculate...<br>";

// Beginning timestamp
$parallel_start_time = microtime(true);

if (
$threads == 1 )
{
   
// Set the arguments
   
$args = array(); // Initialize the variable
   
$args['t_number'] = 0; // Thread ID
   
$args['size'] = $m_size; // Matrix size
   
$args['threads'] = 1; // Number of threads
   
$args['first'] = $matrix1; // First matrix
   
$args['second'] = $matrix2; // Second matrix
   
    // Perform the calculation and get the result
   
$threads_results[0] = Multiply($args);
}
else
{
   
// Create the threads
   
for ( $i=0; $i<$threads; $i++ )
    {
       
// Set the arguments
       
$args = array(); // Initialize the variable
       
$args['t_number'] = $i; // Thread ID
       
$args['size'] = $m_size; // Matrix size
       
$args['threads'] = $threads; // Number of threads
       
$args['first'] = $matrix1; // First matrix
       
$args['second'] = $matrix2; // Second matrix
       
        // Create the thread and set the function to call and its arguments
       
$thread_handle->AddThread('Multiply', $args, true);
    }
   
   
// Run all threads
   
$thread_handle->Run();
   
   
// Get the result from all threads
   
$threads_results = $thread_handle->GetResults();
}

// End timestamp
$parallel_end_time = microtime(true);

// Get the final result
$result = FinalResult($threads_results, $threads, $m_size);

// Print out the result
if ( $printOut )
{
    echo
'<br>Result:<br><br>';
   
PrintMatrix($result, $m_size);
}

echo
'<br>Parallel part done in '.round($parallel_end_time-$parallel_start_time, 3).' seconds<br>';

?>