1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97:
<?php
namespace Chippyash\Math\Matrix\Formatter;
use Assembler\FFor;
use Chippyash\Math\Matrix\NumericMatrix;
use Chippyash\Math\Type\Comparator;
use Chippyash\Matrix\Interfaces\FormatterInterface;
use Chippyash\Matrix\Matrix;
use Chippyash\Type\TypeFactory;
use Graphp\GraphViz\GraphViz;
use Fhaculty\Graph\Graph;
use Monad\Collection;
class DirectedGraph implements FormatterInterface
{
public function format(Matrix $mA, array $options = array())
{
if (!$mA instanceof NumericMatrix) {
throw new \InvalidArgumentException('Matrix is not NumericMatrix');
}
return FFor::create(['mA' => $mA, 'graph' => new Graph(), 'options' => $options])
->attribs(function($options) {
$attribs = array_key_exists('attribs', $options) ? $options['attribs'] : new Collection([],'string');
if ($attribs instanceof Collection) {
return $attribs;
}
throw new \InvalidArgumentException('options[attribs]');
})
->edgeFunc(function($options) {
$edgeFunc = array_key_exists('edgeFunc', $options) ? $options['edgeFunc'] : function($w){return $w;};
if ($edgeFunc instanceof \Closure) {
return $edgeFunc;
}
throw new \InvalidArgumentException('pptions[edgeFunc]');
})
->output(function($options) {
return array_key_exists('output', $options) ? $options['output'] : 'script';
})
->vertices(function(Collection $attribs, Matrix $mA, Graph $graph) {
$vertices = [];
foreach(range(0, $mA->rows()-1) as $idx) {
if (array_key_exists($idx, $attribs)) {
$attribute = $attribs[$idx];
$vertices[$idx+1] = $graph->createVertex($attribute->getName());
foreach($attribute->getAttributes() as $key => $val) {
$vertices[$idx+1]->setAttribute($key, $val);
}
} else {
$vertices[$idx+1] = $graph->createVertex();
}
}
return $vertices;
})
->graphViz(function(Graph $graph, Matrix $mA, array $vertices, \Closure $edgeFunc, $output) {
$comp = new Comparator();
$zero = TypeFactory::createInt(0);
$rows = $mA->rows();
for ($row = 1; $row <= $rows; $row++) {
for ($col = 1; $col <= $rows; $col++) {
if ($comp->compare($zero, $mA->get($row, $col)) != 0) {
$vertices[$row]->createEdgeTo($vertices[$col])
->setWeight($edgeFunc($mA->get($row, $col)->get()));
}
}
}
return $output == 'script' ? (new GraphViz())->createScript($graph) : $graph;
})
->fyield('graphViz');
}
}