1
$\begingroup$

I'm working with binary protein interactions, and with the data that I have I use Mathematica to generate a Graph with all the interactions. Since most of the organisms have thousands of proteins and interactions, I'm dealing with quadratic matrices of order 2000 or higher, and my code takes too long to generate it (a 1993x1993 matrix takes more than an hour to be created, and the higher ones I couldn't measure the time yet, but it may take a day for a 5000x5000 matrix, maybe more. Btw, this is the time it took for me using 2 kernels on my computer). This is the code that I made:

Clear[matrizadj];
matrizadj[file_]:=
Block[{},
    int = Import[file, "Table"];
    int2 = Union[Flatten[int]];
    t1 = Table[{
        Extract[ Flatten[ Position[ int2, int[[i,1]]] ],{1}],
        Extract[ Flatten[ Position[ int2, int[[i,2]]] ],{1}]
    }, {i, Length[int]}];
    t2 = Join[ t1, Map[Reverse[t1]]];
    matr = ParallelTable[
        If[ MemberQ[ t2,{i,j}], 1, 0],
        {i, Length[int2]}, {j,Length[int2]}]
    ]

This is the code I use to read a .csv file with the interactions. (I'm uploading three files with the interactions: a 1993x1993 matrix and a 4529x4529 matrix). It will generate an adjacency matrix when I call the code using the following line and specifying the path of the file:

mat = matrizadj[ (* insert file path here *) ]

The only operation inside the code that really takes too long to be executed is the last one (the ParallelTable), where he generates the adjacency matrix. I'm sorry if I didn't make myself clear in some part of the text, but I would appreciate if someone could help me. Thanks :)

$\endgroup$
  • $\begingroup$ I think there is maybe something missing in your code; look at the line t2 = Join[...; it does not seem that your brackets are balanced, and this line is probably the origin of the problem. Also, you are at least missing a } in the ParallelTable iterators. $\endgroup$ – nben Jan 13 '17 at 16:48
  • $\begingroup$ Thanks for the review, but this is how I have written the original code and it executes without problem. My problem is the time needed for the operations $\endgroup$ – Augusto Bellinaso Jan 13 '17 at 16:51
  • $\begingroup$ I'm saying that the code you put in your question is not valid Mathematica code. It does not execute. You have an error in it. $\endgroup$ – nben Jan 13 '17 at 16:55
  • 1
    $\begingroup$ The code, as it stands, is un-runnable: there are missing brackets, and MMA doesn't execute even the definition. It's like {a, b}[[2 - there are missing brackets and the expression has no sense. Check your notebook - maybe you just dropped some part when copying it here, especially that you claim it works. The code in your notebook may indeed work, but the one you posted here is erroneous. $\endgroup$ – corey979 Jan 13 '17 at 16:55
  • $\begingroup$ Oh, I saw it and edited the code, now it is woking, sorry about that $\endgroup$ – Augusto Bellinaso Jan 13 '17 at 17:05
2
$\begingroup$

There are errors in your code, so I'm not sure that this is exactly what you are trying to do, but my suggestion would be to use Mathematica's Graph utilities rather than writing your own. The following works quickly for me:

Clear[matrizadj];
matrizadj[file_] := With[
  {int = Import[file, "Table"]},
  With[
   {int2 = Union@Flatten[int]},
   With[
    {t1 = Map[
       First@FirstPosition[int2, #] &,
       int,
       {2}]},
    AdjacencyMatrix@Graph@Join[t1, Reverse /@ t1]]]]

This ran in just a few seconds for me on your larger file. Note that it returns a sparse matrix and not a full matrix; the Normal function can turn this into a normal matrix.

A couple notes:

  • ParallelTable and related functions are multi-processing and not multi-threading utilities, so they require the creation of an entirely separate Wolfram Kernel instance; this duplicates memory and often takes a lot more time than expected. In general, I don't advise using them unless you have a problem that is suited for multi-processing.
  • Mathematica will frequently multi-thread things for you automatically anyway if it can. It can usually be encouraged to do so by using higher-level functions rather than manipulating the data yourself. For example, telling Mathematica to generate a Graph from a list of vertex pairs (edges) then to get its Adjacency Matrix is going to be much faster than you iterating through the list of edges by yourself.
  • Your code overwrites the global variables int, int2, etc. These variables are not localized to your function, so if you had defined an int in your notebook, it would change after calling matrizadj. To fix this, notice how my code nests the variable definitions in With[] forms (see also Block and Module). You can protect your local variables by putting their names in the {} list that is the first argument of the Block form in your code.
|improve this answer|||||
$\endgroup$
  • $\begingroup$ Thanks for your help! I'm still learning how to use Mathematica and I really didn't realize it has those specific utilities for Graphs. Thanks :) $\endgroup$ – Augusto Bellinaso Jan 13 '17 at 18:57
  • $\begingroup$ No problem; Mathematica has built-in tools for almost everything you would need in the course of most numerical analysis, so looking for those tools is usually a good place to start :-) (Also, please accept the answer.) $\endgroup$ – nben Jan 13 '17 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.