Matrices need some love

I am surprised to find so little reference to matrices in this forum.
But looking closer at how they are created and the lack of useful features, it kind of makes sense.
Using a flat list to fill in a matrix seems very primitive indeed, and not being able to use common operations renders them almost useless.

I had put hope on the “Falcon” plugin, but it only seems to deal with 4x4 matrices.

Am I missing something here , or have matrices been thrown in there just to look fancy ?

1 Like

Yeah, I was surprised to find out that the basic Addition and Multiplication components do not support matrices, even though the underlying type Rhino.Matrix clearly has support for overloaded + and * operators.

P.S. that means with zero scripting knowledge you can do something like this:

a = x + y * z 

image

I suspect the issue is that matrices are a way to express many “parallel” things in some form or another, and in Grasshopper that is usually achieved with data trees.

Hi Qythium,

Thanks for this tip.
I notice that it works properly for multiplication.
I used the values given as example in this remarquable “Matrices for dummies” page :

It seems indeed odd that the common operators cannot be used, but even more so to feed a flat list instead of a tree.

It is also apparent here that the Matrix tools from the “Falcon” plugin don’t work with other than 4x4 matrices.

What version are you on? Multiplication works here:

As does addition:

2 Likes

Hi David,

It works indeed in GH 1 ! But since there is very little talk about matrices on the forum, I stuck with a statement of old and assumed it still didn’t work.
Maybe I should have read the changelog :wink:

What was the idea behind a flat list being used as input for the values ?
Wouldn’t it make more sense to use trees with a single level of branches to make the rows and column explicit ?

Also, it seems that a Matrix toolbar should include a “determinant” tool.

Easiest way to supply them. You can always flatten a tree, but it’s generally harder to put a list into rows and columns.

The matrix toolbar is a desert. There’s loads of useful matrix operations that could be included, although when I added the data type, Matrix support in RhinoCommon was very limited, I think it’s a bit better now.

I don’t know however how matrices are used in Grasshopper. What are you using them for?

1 Like

Hi David,

A flat list is indeed “Simple”, but I would assume that the user has a structured list of the values in rows and colums ; otherwise, he would be just dumping values in the matrix randomly.
By allowing a flat list, nothing is gained in fact, except that you are forcing the user to flatten his tree.

I was exploring the possibility of using matrices as part of an interest for Graph theory.
Graphs can indeed be represented by an “Adjacency matrix”, or an “Incidence Matrix”.

1 Like

That’s interesting, I was expecting mostly algebraic applications for matrices, not data encoding. That does change the set of potentially useful components quite a lot.

Graph theory seems to be of much use in computing science, including neural networks, optimization,…
Heck, I tried all the tools in the “sets” tab to solve my problem with finding the lists of tangentially connected faces on a Brep , and finaly, the most straight-forward way I found to do it is use a graph.
I wish I knew how to convert this “face connectivity” graph into an adjacency matrix and compute the lists through operations on matrices.
Instead, I had to resort to drawing actual geometry and using “tricks” to get my lists.

Adjacency matrices are really nothing but a computer-centric low-level implementation, basically huge look up tables optimized for access speed.

In my opinion there is nothing inherent about graphs that lends them to represented as an adjacency matrix - and implementing such a structure in a “general-purpose” Rhinocommon matrix (dense, double-precision values) defeats most of the efficiency advantages it had in the first place.

Grashopper could definitely do with better native support for graphs (something like Python’s NetworkX would be nice), but shoving them into matrices is probably not the best way for that…

I’ll have a look on the other thread, there might be a more “idiomatic” Grasshopper way of solving your tangency problem :slight_smile:

Hi Qythium,
I’m curious about this NetworkX thing. I’m just scratching the surface on these things ; just went through the first videos on Sarada Herke’s great playlist on graphs, that’s all.
The “Tangency” problem is not so much about tangency but about merging lists who contain common elements.
I was baffled to find that despite all the GH “Set” tools, it required an iterative process to be solved completely.
Anyway, TomTom has come up with the perfect component for me.
I realize that I need to pick a language and start learning if I want to do more advanced and efficient tools in GH.
Python ? C# ? VB Dot.net ? … it seems hard to choose, but maybe this “NetworkX” thing could help me decide.

Thanks for this information !

Unfortunately it’s not a simple task to get networkx working inside Grasshopper, due to some IronPython incompatibilities- there’s a thread somewhere else on the forum detailing all the steps and things other people have tried.

If I understand it correctly, your problem was about partitioning a graph into mutually unconnected subgraphs, that’s something involving (iterative) depth-first search.

In networkx it would be a single function call:

import networkx as nx

G = nx.Graph() # initialize empty undirected graph
for edge in tangent_edges: # tuple of (face1, face2) indices
    G.add_edge(*edge)

# list of sets of indices corresponding to subgraphs
nx.connected_components(G)  

David, would you consider a “Graphs” tab in GH 2 ?

Do you want some components with useful graph-related functionality to go with the tab, or would an empty one do? :wink:

I was certainly thinking about adding a graph type. Not sure about the specifics yet, and I have a fairly limited set of ideas of what people would use it for, but once there it’s always possible to add functionality.

“Ivy” is a example of how graphs can be useful when dealing with geometry connectivity.
My “sets of tangent Brep faces” problem could have been solved directly with graph tools such as these, except Ivy only deals with meshes.
Similarly, “Falcon” has many Matrix tools, but focuses on transformation matrices only.
A more generic set of matrix and graph tools seems appealing in principle, as there is no static definition of Grasshopper’s purpose.

I believe this is the discussion qythium was referring on how to use Networkx on Python.

https://discourse.mcneel.com/t/networkx-module-on-ghpython/53588/6?u=antonio_cersosimo

As it were, it is indeed possible and pretty straight forward to implement networkx in GHPython for algorithms the depend on mesh graphs. An old example here:

With some basic implementation snippets here:

Note the versioning issues discussed in the thread Antonio links to above (i.e. use networkx 1.5 if things get fucky).