well i have a problem with logic of matrices multiplication in php; the data comes from the database in the form of an one dimension array (Array ( [0] => 1.0000 [1] => 0.5000 [2] => 3.0000 [3] => 2.0000 [4] => 1.0000 [5] => 5.0000 [6] => 0.3333 [7] => 0.2000 [8] => 1.0000 ) ), that I need to transform into a matrice. The dimension of the original array is a square number (in this case 9), so the result matrice will have two equal dimensions, both equal to the square root (3) of the original data array.
The result matrice has to be multiplied by itself, using the pattern in the image below:
I have made some research before, but none of them were right.
i have the following code i used in the model to create the algorithm:
function hitung_matriks(){
$query = $this->db->query("select * from banding b
inner join kriteria a on a.Kd_Kriteria1 = b.Kd_Kriteria1");
$dt_matriks = $query->result();
$data = array();
foreach($dt_matriks as $a){
$data[] = $a->Nilai_Banding;
}
echo "<pre>";
print_r($data);
echo "</pre>";
$c = array();
for($i=1;$i<=sqrt(count($data));$i++){
$d = array();
$isi=0;
for($j=1;$j<=sqrt(count($data));$j++){
$isi = $data[$i][$j] * $data[$j][$i];
$d[] = $isi;
}
$c[] = $d;
}
echo "<pre>";
print_r($c);
echo "</pre>";die();
}
and the result of each array comes 0.
I want to make this code works to be like this :
please help me :'(
Updated answer:
Way to transform $data array into a matrice:
$data = array(1.0000, 0.5000, 3.0000, 2.0000, 1.0000, 5.0000, 0.3333, 0.2000, 1.0000);
$data2 = array();
$j = 0;
$k = 0;
for($i=0;$i<count($data);$i++){
if($j < sqrt(count($data)) ){
$data2[$j][$k] = $data[$i];
$j++;
}else{$j = 0; $k++;}
}
About matrix multiplication, I found this interesting post: http://sickel.net/blogg/?p=907
Using the exact function found there:
function matrixmult($m1,$m2){
$r=count($m1);
$c=count($m2[0]);
$p=count($m2);
if(count($m1[0])!=$p){throw new Exception('Incompatible matrixes');}
$m3=array();
for ($i=0;$i< $r;$i++){
for($j=0;$j<$c;$j++){
$m3[$i][$j]=0;
for($k=0;$k<$p;$k++){
$m3[$i][$j]+=$m1[$i][$k]*$m2[$k][$j];
}
}
}
return($m3);
}
$c = matrixmult($data2, $data2);
foreach($c as $k => $v){
$i = 0;
foreach($v as $kk => $vv){
echo $vv . ' | ';
$i++;
if($i == count($v))
echo '<br/>';
}
}
The result is quite close to the needed pattern:
2.9999 | 1.6 | 8.5 |
5.6665 | 3 | 16 |
1.0666 | 0.56665 | 2.9999 |
The slight difference comes from the rounding method. If that's an issue, see round() function.
sqrt() function is for calculating square root. If you want to loop all elements in array then remove sqrt() call.
In PHP, array usually zero-based index, so you need to replace $i=1, $j=1 to start from 0 in your for loop.
See Matrix multiplication
Related
Problem 1:
array(670006151,670006152,670006251)
output: 670006151,152,251
Problem 2:
array(670006151,670006154,670006158)
output: 670006151,4,8
Problem 3:
array(670006151,670006154,670006161)
output: 670006151,54,61
anyone know how to get output from different arrays, I need to find a common number from start then append other elements in the above problems 670006 is common in all this can be any number...
One way to do this is to divide each of the numbers by increasing powers of 10, stopping when the result is the same for each of them. Then subtract that result multiplied by the power from the 2nd to last entries in the array:
function common_parts($data) {
for ($b = 1; ; $b *= 10) {
$base = intdiv($data[0], $b);
$matches = array_filter($data, function ($v) use ($b, $base) { return intdiv($v, $b) != $base; });
if (count($matches) == 0) break;
}
$base *= $b;
for ($i = 1; $i < count($data); $i++) {
$data[$i] = $data[$i] - $base;
}
return $data;
}
print_r(common_parts(array(670006151,670006152,670006251)));
print_r(common_parts(array(670006151,670006154,670006158)));
print_r(common_parts(array(670006151,670006154,670006161)));
Output:
Array
(
[0] => 670006151
[1] => 152
[2] => 251
)
Array
(
[0] => 670006151
[1] => 4
[2] => 8
)
Array
(
[0] => 670006151
[1] => 54
[2] => 61
)
Demo on 3v4l.org
Loop over all elements of the array.
Convert each number to a string.
Compare the current longest prefix you have with the current number at hand.
Break immediately and update longest common prefix once you find a mismatch.
Loop over the dataset again and remove the longest prefix you calculated and add the residue of the current number in iteration to result.
Snippet:
<?php
function getPrefixedData($arr){
if(count($arr) == 0) return [];
$longest_prefix = strval($arr[0]);
foreach($arr as $val){
$val = strval($val);
$len = strlen($longest_prefix);
for($i=0;$i<$len;++$i){
if($longest_prefix[$i] != $val[$i]){
$longest_prefix = substr($longest_prefix,0,$i);
break;
}
}
}
$res = [];
$len = strlen($longest_prefix);
foreach($arr as $index => $val){
if($index == 0) $res[] = $longest_prefix . substr(strval($val),$len);
else $res[] = substr(strval($val),$len);
}
return $res;
}
Fiddle here
Multiple values in a single array (some value similar)
how to get
One of them is to get the array that is similar values
minimum 1 and maximum 2 times repeat
for Example This array -
$array_value = array('ab','ab','cd','de','ab','cd','ab','de','xy');
foreach($array_value as $value){
}
I want output - ab, ab,cd, cd, de, xy
array_count_values return the repetition of specific value in array. So, you can use it to simplify the code and quickly implement it.
$array_value = array('ab','ab','cd','de','ab','cd','ab','de','xy');
// Get count of every value in array
$array_count_values = array_count_values($array_value);
$result_array = array();
foreach ($array_count_values as $key => $value) {
// Get $value as number of repetition of value and $key as value
if($value > 2) {
$value = 2;
array_push($result_array, $key);
array_push($result_array, $key);
} else {
for ($i=0; $i < $value; $i++) {
array_push($result_array, $key);
}
}
}
print_r($result_array);
I think your output shuold have two de not one?
Anyway here is the code with explanations in comments:
<?php
$array_value = array('ab','ab','cd','de','ab','cd','ab','de','xy');
$arr_count = []; //we use this array to keep track of how many times we've added this
$new_arr = []; //we add elements to this array, or not.
foreach($array_value as $value){
// we've added it before
if (isset($arr_count[$value])) {
// we only add it again one more time, no more.
if ($arr_count[$value] < 2) {
$arr_count[$value]++;
$new_arr[] = $value;
}
}
// we haven't added this before
else {
$arr_count[$value] = 1;
$new_arr[] = $value;
}
}
sort($new_arr);
print_r($new_arr);
/*
(
[0] => ab
[1] => ab
[2] => cd
[3] => cd
[4] => de
[5] => de
[6] => xy
) */
PHP Demo
I have a variable in php that has the following value:
var $line="'PHYSICAL':3.8,'ORGANIZATIONAL':4,'TECHNICAL':2.9";
From that line variable, I want to extract each word and values in php, so basically I want something like below:
var $word1=PHYSICAL;
var $word1value=3.8;
var $word2=ORGANIZATIONAL;
var $word2value=4;
var $word3=TECHNICAL;
var $word3value=2.9;
I want to capture all the words and values separately in different variables, so that later I can process them. Can anyone please assist me on this. Thanks.
The simplest way to do this is with preg_split. You can use the PREG_SPLIT_DELIM_CAPTURE flag to enable capturing the word without the surrounding quotes, and PREG_SPLIT_NO_EMPTY to remove the empty values that arise from this particular split pattern.
$line="'PHYSICAL':3.8,'ORGANIZATIONAL':4,'TECHNICAL':2.9";
$array = preg_split("/'([^']+)':|,/", $line, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
print_r($array);
Output:
Array
(
[0] => PHYSICAL
[1] => 3.8
[2] => ORGANIZATIONAL
[3] => 4
[4] => TECHNICAL
[5] => 2.9
)
You can then post-process the array (for example using array_filter and array_combine) to produce something which might be more useful:
$newarray = array_combine(array_filter($array, function ($i) { return !($i % 2); }, ARRAY_FILTER_USE_KEY),
array_filter($array, function ($i) { return $i % 2; }, ARRAY_FILTER_USE_KEY));
print_r($newarray);
Output:
Array
(
[PHYSICAL] => 3.8
[ORGANIZATIONAL] => 4
[TECHNICAL] => 2.9
)
If you really want the individual variables you can do this:
for ($i = 0; $i < count($array); $i += 2) {
${'word' . intdiv($i+2, 2)} = $array[$i];
${'word' . intdiv($i+2, 2) . 'value'} = $array[$i+1];
}
echo "word1 = $word1\n";
echo "word1value = $word1value\n";
echo "word2 = $word2\n";
echo "word2value = $word2value\n";
echo "word3 = $word3\n";
echo "word3value = $word3value\n";
Output:
word1 = PHYSICAL
word1value = 3.8
word2 = ORGANIZATIONAL
word2value = 4
word3 = TECHNICAL
word3value = 2.9
I have 2 arrays - the first one is output first in full. The 2nd one may have some values that were already used/output with the first array. I want to "clean up" the 2nd array so that I can output its data without worrying about showing duplicates. Just to be sure I have the terminology right & don't have some sort of "array within an array", this is how I access each one:
1st Array
$firstResponse = $sth->fetchAll();
foreach ($firstResponse as $firstResponseItem) {
echo $firstResponseItem['samecolumnname']; // Don't care if it's in 2nd array
}
2nd Array
while( $secondResponseRow = $dbRequest->fetch_assoc() ){
$secondResponseArray = array($secondResponseRow);
foreach ($secondResponseArray as $secondResponseItem){
echo $secondResponseItem['samecolumnname']; //This can't match anything above
}
}
Thanks!
For example:
$response_names = array();
$firstResponse = $sth->fetchAll();
foreach ($firstResponse as $firstResponseItem)
$response_names[] = $firstResponseItem['samecolumnname'];
while( $secondResponseRow = $dbRequest->fetch_assoc() ){
$secondResponseArray = array($secondResponseRow);
foreach ($secondResponseArray as $secondResponseItem) {
if (!in_array($secondResponseItem['samecolumnname'], $response_names))
$response_names[] = $secondResponseItem['samecolumnname'];
}
}
array_walk($response_names, function($value) { echo $value . '<br />' });
If I understand what you're looking to do and the arrays are in the same scope, this should work.
$secondResponseArray = array($secondResponseRow);
$secondResponseArray = array_diff($secondResponseArray, $firstResponse);
//secondResponseArray now contains only unique items
foreach ($secondResponseArray as $secondResponseItem){
echo $secondResponseItem['samecolumnname'];
}
If you know that the keys of duplicate values will be the same you could use array_diff_assoc to get the items of the first array that aren't in the other supplied arrays.
This code
<?php
$a = array('abc', 'def', 'ghi', 'adg');
$b = array('abc', 'hfs', 'toast', 'adgi');
$r = array_diff_assoc($b, $a);
print_r($a);
print_r($r);
produces the following output
[kernel#~]php so_1.php
Array
(
[0] => abc
[1] => def
[2] => ghi
[3] => adg
)
Array
(
[1] => hfs
[2] => toast
[3] => adgi
)
[kernel#~]
Hope you are fine. My question :
In MYSQL i have a table with this type of field
Field Name: TAGS
Value : xavier,celine,marise,leon,john,cathy,polux,maurice
In PHP i do this
$xwords = array();
function array_rpush(&$arr, $item)
{
$arr = array_pad($arr, -(count($arr) + 1), $item);
}
$tags = requete("SELECT tags FROM tbl_tags LIMIT 1;");
while($dtags = mysql_fetch_assoc($tags)){
$words .= array_rpush($xwords, $dtags['tags']);
}
// MY ARRAY XWORDS FOR DEBUG
//
// Array ( [0] => xavier, celine, marise, leon, john, cathy, polux, maurice
//
My script need to find the first letter of each word in this list and check if he match with A / B / C (i create an A-Z index page)
// COUNT $XWORDS VALUE
$total = count($xwords);
// total =1
for($i=0; $i < $total; $i++)
{
$wtags = explode(",",$xwords[$i]);
// wtags = Array ( [0] => xavier [1] => celine [2] => marise... )
while (list($idx,$val) = each($wtags)) {
echo $val{0}."<br>";
echo substr($val,0,1)."<br>";
}
}
echo $val{0}."<br>"; OR echo substr($val,0,1)."<br>" give me just x and nothing after (while give me only the first letter for the first record in array... amazing :))
Perhaps you can help me find a solution. Thanks
The problem with your code is that it generates:
Array ( [0] => "xavier" [1] => " celine" [2] => " marise"... )
So $val[0] = " ". Try to trim($val):
$val = trim($val);
print $val[0];
$sum = array();
foreach($wtags as $tag){
$tag = trim($tag);
empty($sum[$tag{0}]) ? // if we don't have a $sum element for this letter
$sum[$tag{0}] = 1 : // we initialize it
$sum[$tag{0}]++; // else, we sum 1 element to the count.
//$tag{0} is the first letter.
}
// the array $sum has the total of tags under each letter
//
// $sum[x] = 1
// $sum[c] = 2
// $sum[m] = 2
// $sum[l] = 1
// $sum[j] = 1
// $sum[p] = 1