Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

The functions SetProperty and PropertyValue can only set a single property of a single vertex, as far as I know. How do I set a property for multiple vertices simultaneously?

In the documentation, they recommend using Do to set multiple properties, but I've heard that Do is not the most efficient way to do things in Mathematica. Are there any alternatives?

EDIT : The only approach seems to make several calls to SetProperty or PropertyValue (which is faster), one call for each distinct vertex property I want to set. From the answers so far it seems that there is no Mathematica equivalent to SetProperty or PropertyValue that sets several properties of distinct vertices at once. But I'd still hope that something could be done directly on the Graph object, bypassing SetProperty and PropertyValue.

share|improve this question
    
A meta question: Is the version-8 tag necessary here? PropertyValue is new in version 8, but when mma 9 comes along this tag will become redundant... –  Ajasja May 20 '12 at 20:27
    
@Ajasja I think the version-8 tag is important here. Especially because in Mathematica 8 there are three distinct ways of dealing with graphs: two are the Combinatorica package and the GraphPlot et al, which have been there at least since version 6; the other is the Graph object, which is new to version 8. The tag graphs-and-networks alone would not make this distinction. –  becko May 20 '12 at 23:32
add comment

2 Answers

up vote 8 down vote accepted

It may be not clear from documentation but SetProperty and PropertyValue can take "global to graph" specifications to apply simultaneously to all objects

Row@{g = CompleteGraph[4, PlotRangePadding -> .2], 
  PropertyValue[g, VertexLabels] = "Name"; g}

enter image description here

and even sets of "global to graph" specifications put in a list:

Row@{g = CompleteGraph[12, PlotRangePadding -> .3, ImageSize -> 300], 
  SetProperty[
   g, {VertexSize -> .4, VertexLabels -> "Name", 
    VertexStyle -> Directive[Opacity[.4], Green], 
    EdgeStyle -> Directive[Thickness[.02], Opacity[.2], Red]}]}

enter image description here

Also, if you have unique-to-object options you can specify them by other than Do means. The documentation has examples of functional programming. For instance, slightly modifying this example using Fold:

Row@{g = CompleteGraph[8, VertexSize -> Large],
  Fold[SetProperty[{#1, #2}, VertexStyle -> ColorData[45, #2]] &, g, Range[1, 8]]}

enter image description here

Or this example with Do that you've seen, can be done with Map:

Row@{g = CompleteGraph[15, VertexSize ->Large], 
    (PropertyValue[{g, #[[1]]}, VertexStyle] = #[[2]]) & /@ 
     Transpose[{Range[15], ColorData[1, "ColorList"]}]; g}

enter image description here

share|improve this answer
1  
I don't think this will improve efficiency, in this paricular case. FP offers speed advantage when array indexing or similar frequent operations are involved, since it pushes more of that into the kernel. This does not seem to be the case here. –  Leonid Shifrin May 20 '12 at 18:56
    
@LeonidShifrin The question has reference to Do, and for now my sole intent was to show other functions usage. –  Vitaliy Kaurov May 20 '12 at 19:15
1  
The question's title implies that efficiency is central here, which is why I made this comment. –  Leonid Shifrin May 20 '12 at 19:16
    
Scan might be even better than Map, since the only use if map is for the side effects. –  Ajasja May 20 '12 at 19:50
1  
I had tried similar approaches. What I was looking for was an alternative that didn't involve several distinct calls to SetProperty or PropertyValue, perhaps by avoiding those functions altogether and doing some rule-replacement combo on the Graph directly. Why isn't something like that implemented in Mathematica? –  becko May 21 '12 at 23:20
show 1 more comment

I don't think you will get much better performance using functional approaches here, since the call to SetProperty is the bottleneck instead of the Do loop. Anyway it says in the documentation that PropertyValue is much faster than SetProperty. We can check both assumptions:

g = CycleGraph[1000];
Timing@Do[
  PropertyValue[{g, v}, VertexWeight] = RandomReal[], {v, 
   VertexList[g]}]

(* ==> {0.016, Null} *)

g = CycleGraph[1000];
Timing@Do[
  SetProperty[{g, v}, VertexWeight -> RandomReal[]], {v, 
   VertexList[g]}]

(* ==> {2.25, Null} *)

(*Try scan*)
g = CycleGraph[1000];
Timing@Scan[(PropertyValue[{g, #}, VertexWeight] = RandomReal[]) &, 
  VertexList[g]]

(* ==> {0.031, Null} *)

g = CycleGraph[1000];
Timing@Scan[(SetProperty[{g, #}, VertexWeight -> RandomReal[]]) &, 
  VertexList[g]]

(* ==> {2.625, Null} *)

From this we see that for this example PropertyValue is indeed much better and that using Scan has no benefits.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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