|
|
|
| Долго искал в интернете, нашёл несколько решений, но там как-то неправильно (пример одного из них напишу внизу). Завтра сдавать лабораторную в которой одно из условий - реализация этой фигни, а я никак не могу это сам сделать (((
Пример из интернета:
<?php
//$a-это исходная матрица 3*3
$a = array(array(0,1,1), array(1,0,1), array(1,1,0));
for ($k=1;$k<=3;$k++)
{
for ($i=1;$i<=3;$i++)
{
for ($j=1;$j<=3;$j++)
{
if ($i==$k and $j==$k) $b[$i][$j]=1/$a[$i][$j];
if ($i==$k and $j!=$k) $b[$i][$j]=-$a[$i][$j]/$a[$k][$k];
if ($i!=$k and $j==$k) $b[$i][$j]=$a[$i][$k]/$a[$k][$k];
if ($i!=$k and $j!=$k) $b[$i][$j]=$a[$i][$j]-$a[$k][$j]*$a[$i][$k]/$a[$k][$k];
}
}
$a=$b;
}
echo "<pre>";
print_r($a);
?>
|
В этом примере есть деление на элементы матрицы, но некоторые равны нулю и что тогда делать? По моим подсчётам матрица на выходе должна иметь вид:
array(
array(-0.5, 0.5, 0.5),
array(0.5, -0.5, 0.5),
array(0.5, 0.5, -0.5)
)' | |
|
|
|
|
|
|
|
для: DEM
(03.01.2012 в 19:23)
| | Вам именно обратная матрица нужна? Или просто нужно решить систему уравнений http://softtime.ru/scripts/matrix.php? | |
|
|
|
|
|
|
|
для: cheops
(03.01.2012 в 19:47)
| | Именно обратную матрицу и она может быть размера не 3*3, а, к примеру, 10*10 или больше... | |
|
|
|
|
|
|
|
для: DEM
(03.01.2012 в 19:53)
| | Нашёл ещё один способ. Он был на С++ написан, но переписал его на РНР:
<?php
function q($matrix){
$a = $matrix;
$e = array();
$count = count($a);
for($i=0;$i<$count;$i++)
for($j=0;$j<$count;$j++)
$e[$i][$j]=($i==$j)? 1 : 0;
for($i=0;$i<$count;$i++){
$tmp = $a[$i][$i];
for($j=$count-1;$j>=0;$j--){
$e[$i][$j]/=$tmp;
$a[$i][$j]/=$tmp;
}
for($j=0;$j<$count;$j++){
if($j!=$i){
$tmp = $a[$j][$i];
for($k=$count-1;$k>=0;$k--){
$e[$j][$k]-=$e[$i][$k]*$tmp;
$a[$j][$k]-=$a[$i][$k]*$tmp;
}
}
}
}
for($i=0;$i<$count;$i++)
for($j=0;$j<$count;$j++)
$a[$i][$j]=$e[$i][$j];
return $a;
}
?>
|
Но, опять же, там есть деление на элементы матрицы, а у нас есть равные нулю((( | |
|
|
|
|
|
|
|
для: DEM
(03.01.2012 в 23:14)
| | >Но, опять же, там есть деление на элементы матрицы, а у нас есть равные нулю(((
Проверяйте деление на нуль (не каждая матрица имеет обратную). Хотел написать алгоритм, но увлекся решением методом Гаусса-Жордана, возможно, кому-то пригодится (по крайней мере будет вариант для системы с более чем тремя неизвестными). | |
|
|
|
|
|
|
|
для: cheops
(04.01.2012 в 00:58)
| | Дело в том, что моя матрица имеет обратную, перепроверил уже много раз :) Даже воспользовался Mathematica для такого)))
Просто у меня уже голова не варит, вообще ничего не понимаю :(
Но всё равно спасибо большое! Буду думать дальше, целая ночь впереди :) | |
|
|
|
|
|
|
|
для: DEM
(04.01.2012 в 01:02)
| | Заглядывайте сюда, может совершу подвиг и распотрошу какую-нибудь Fortran-библиотеку с интересным алгоритмом. | |
|
|
|
|
|
|
|
для: cheops
(04.01.2012 в 01:04)
| | буду очень благодарен :) | |
|
|
|
|
|
|
|
для: DEM
(04.01.2012 в 01:02)
| | Там кстати, в этом методе Гаусса-Жордана, тоже в конце получается обратная матрица $a (я её просто не вывожу) и она отличается от вашей первым столбцом, сейчас постараюсь проверить точно где ошибка. | |
|
|
|
|
|
|
|
для: cheops
(04.01.2012 в 01:17)
| | а как мне узнать параметр $b? У меня же просто матрица, а не уравнения... | |
|
|
|
|
|
|
|
для: DEM
(04.01.2012 в 01:26)
| | Эээ... там на хитрость идут, используют все переменные равные 1, поэтому в нормальном алгоритме их даже вычислять не надо.
Слушайте, вы наверное недавно алгебру слушали, правильно я помню, что умножение матрицы на обратную дает единичную матрицу (это собственно и к абзацу выше)? Помоему ни у вас ни у меня ни фига не обратная матрица, перемножаю и матрицы и обратную матрицу на коэффициенты - фигня получается... а должны получаться исходные данные. Ведь метод Гаусса он там не совсем обратную матрицу кажется делает, он делает матрицу треугольной, за счет чего можно быстро получить детерминант, а можно вообще без него...
Вам в любом случае сначала нужно вычислить детерминант - если он 0 дальше считать нет смысла, если он отличен от нуля - обратная матрица есть обязательно, я в принципе с этого и начал, да вот у несло меня в другую степь...
Надо наверное систему попроще брать - двумерную, вычислять вручную и смотреть где и что происходит, а потом уже обощать на трехмерную. | |
|
|
|
|
|
|
|
для: DEM
(04.01.2012 в 01:26)
| | Суть в том, что вы можете подставить вместо $b единицы и в ходе решения должна появится обратная матрица и она вроде появляется, только их перемножение с исходной не дает единичную. | |
|
|
|
|
|
|
|
для: cheops
(04.01.2012 в 01:17)
| | И у Вас там есть условие:
if($a[$icol][$icol] == 0) return "Матрица сингулярна";
|
А у моей матрицы все элементы диагонали будут всегда равны 0 | |
|
|
|
|
|
|
|
для: DEM
(04.01.2012 в 01:28)
| | >А у моей матрицы все элементы диагонали будут всегда равны 0
Это значения не имет, главное, чтобы детерминант не был равен 0, а метод Гаусса он же строки складывает и вычитает, там от этих нулей в первом же проходе ничего не останется.
Дайте вашу матрицу, если не сложно. | |
|
|
|
|
|
|
|
для: cheops
(04.01.2012 в 01:37)
| | У меня такое условие задачи:
Есть файл вида:
2 4
1 5
2 7
2 8
3 1
1 7
Это координаты точек (только целые). Надо составить матрицу из расстояния от одной точки до других (первый ряд от первой точки, второй - от второй и т.д.), и ещё добавляется один ряд и столбец в которых элементы равны 1 (кроме диагонального, он равен единице)
Значения там могут быть какие угодно (только не повторяющиеся). В матрице которую я привёл были значения точек:
2 1
2 2
и с ней надо делать всякую фигню, но вот застопорился с ОБРАТНОЙ МАТРИЦЕЙ, всё остальное легко делается... | |
|
|
|
|
|
|
|
для: DEM
(03.01.2012 в 23:14)
| | Взял, как Вы и сказали массив $b равный единице и постаивл, что бы возвращала матрицу $a. Всё посчиталось правильно.
СПАСИБО БОЛЬШОЕ!!!! :) | |
|
|
|
|
|
|
|
для: DEM
(04.01.2012 в 01:57)
| | Ага, тоже вручную посчитал, и ваш, и мой алгоритмы дают одно и тоже на простейшей двухмерной матрице. | |
|
|
|
|
|
|
|
для: DEM
(03.01.2012 в 23:14)
| | Немного вашу функцию облагорожу (в PHP с памятью проще - можно не копировать результат из единичной матрицы в исходную), чтобы потом на тему можно было ссылаться (мой вариант неправильный результат с первым столбцом выдает - почему-то в обратном порядке его выводит)
<?php
function q($matrix)
{
$a = $matrix;
$e = array();
$count = count($a);
for($i = 0; $i < $count; $i++)
for($j = 0; $j< $count; $j++)
$e[$i][$j] = ($i==$j) ? 1 : 0;
for($i = 0; $i < $count; $i++)
{
$tmp = $a[$i][$i];
for($j = $count - 1; $j >= 0; $j--)
{
$e[$i][$j] /= $tmp;
$a[$i][$j] /= $tmp;
}
for($j = 0; $j < $count; $j++)
{
if($j != $i)
{
$tmp = $a[$j][$i];
for($k = $count - 1; $k >= 0; $k--)
{
$e[$j][$k] -= $e[$i][$k]*$tmp;
$a[$j][$k] -= $a[$i][$k]*$tmp;
}
}
}
}
return $e;
}
?>
|
| |
|
|
|
|
|
|
|
для: DEM
(03.01.2012 в 19:23)
| | За одно и перемножение матриц сюда заброшу, чтобы уж все в одном месте было (это для квадратных матриц, для прямоугольных нужно проверять, что там с границами циклов).
<?php
function multi($x, $y)
{
for($i = 0; $i < count($x[0]); $i++)
{
for($j = 0; $j < count($y[0]); $j++)
{
for($k = 0; $k < count($x[0]); $k++)
{
if(!isset($z[$i][$j])) $z[$i][$j] = 0;
$z[$i][$j] += $x[$i][$k] * $y[$k][$j];
}
}
}
return $z;
}
?>
|
| |
|
|
|