3
$\begingroup$

This is a follow up to my question posted here I am trying to run the code posted here as an answer in the above-mentioned link here from Python

I tried,

from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr, Global

edges = [(1, 2), (1, 3), (1, 4), (2, 5), (2, 6), (5, 6), (3, 4), (3, 7), (6, 7), (7, 8), (2, 9)]
ew = {(1, 2): 49.6, (1, 3): 74.4, (1, 4): 49.6, (2, 5): 37.2, (2, 6): 74.4, (5, 6): 49.6, (3, 4): 37.2, (3, 7): 24.8, (6, 7): 62, (7, 8): 37.2, (2, 9): 24.8}
with WolframLanguageSession() as s:
     s.evaluate(wl.Get('wolfram_input.m'))
     s.evaluate(Global.solution3d(edges, ew))

wolfram_input.m contains Mathematica expressions

solution3d[uedges_, edgeweight_] := Module[{
   edges = UndirectedEdge @@@ uedges;
   ew = KeyMap[UndirectedEdge @@ # &, edgeweight];

   verts, graph, dmat, hmat, dist2mat, bmat, dim, newcoords, newLayout, EdgeLabels, VertexSize, vars, weights, objective,
   min, vals, newercoords},

   verts = Union[Flatten[edges /. UndirectedEdge -> List]];

   graph = Graph3D[verts, edges, EdgeWeight -> ew, VertexLabels -> Placed["Name", Center],
           EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, VertexSize -> .3, VertexStyle -> Red];

   dmat = GraphDistanceMatrix[graph];
   DistanceMatrixDimensionReduce[(dmat_)?MatrixQ, dim_: 3] :=
    With[{len = Length[dmat]},
    Module[{diffs, dist2mat, onevec, hmat, bmat, uu, ww, vv},
    onevec = ConstantArray[{1}, len];

    hmat = IdentityMatrix[len] - onevec.Transpose[onevec]/len;

    dist2mat = -dmat/2;

    bmat = hmat.dist2mat.hmat; {uu, ww, vv} =
    SingularValueDecomposition[bmat, dim]; uu.Sqrt[ww]] /;

    dim <= Length[dmat[[1]]] && MatchQ[Flatten[dmat], {_Real ..}]];

    newcoords = DistanceMatrixDimensionReduce[dmat];

    newLayout = Graph[verts, edges, VertexCoordinates -> vcoords2, EdgeWeight -> ew,
    VertexLabels -> Placed["Name", Center];

    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]};

    VertexSize -> .3, VertexStyle -> Red];

    vars = Array[xyz, {Length[verts], 3}];

    weights = Normal[WeightedAdjacencyMatrix[graph]];

    objective =
    Sum[If[weights[[i, j]] >
    0, ((vars[[i]] - vars[[j]]).(vars[[i]] - vars[[j]]) -
    weights[[i, j]]^2)^2, 0], {i, Length[weights] - 1}, {j, i + 1,
    Length[weights]}];

   {min, vals} =
   FindMinimum[objective,
   Flatten[MapThread[List, {vars, newcoords}, 2], 1]];
   Print[min];
   newercoords = vars /. vals;
]

I think there is a problem with the local variable specification.

    Local variable specification {CompoundExpression[Set[edges, Apply[UndirectedEdge, {{1, 2}, {1, 3},
 {1, 4}, {2, 5}, {2, 6}, {5, 6}, {3, 4}, {3, 7}, {6, 7}, {7, 8}, {2, 9}}, {1}]], Set[ew, 
KeyMap[Function[Apply[UndirectedEdge, Slot[1]]], Association[{{1, 2} -> 49.6, {1, 3} -> 74.4, {1, 4} -> 
49.6, {2, 5} -> 37.2, {2, 6} -> 74.4, {5, 6} -> 49.6, {3, 4} -> 37.2, {3, 7} -> 24.8, {6, 7} -> 62, {7, 
8} -> 37.2, {2, 9} -> 24.8}]]], verts], graph, dmat, hmat, dist2mat, bmat, dim, newcoords, newLayout, 
EdgeLabels, VertexSize, vars, weights, objective, min, vals, newercoords} contains 
CompoundExpression[Set[edges, Apply[UndirectedEdge, {{1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {5, 6}, {3, 
4}, {3, 7}, {6, 7}, {7, 8}, {2, 9}}, {1}]], Set[ew, KeyMap[Function[Apply[UndirectedEdge, Slot[1]]],
 Association[{{1, 2} -> 49.6, {1, 3} -> 74.4, {1, 4} -> 49.6, {2, 5} -> 37.2, {2, 6} -> 74.4, {5, 6} -> 
49.6, {3, 4} -> 37.2, {3, 7} -> 24.8, {6, 7} -> 62, {7, 8} -> 37.2, {2, 9} -> 24.8}]]], verts], which is 
not a symbol or an assignment to a symbol.

Could someone help me with this?

EDIT:

solution3d[uedges_, edgeweight_] := Module[{
   edges = UndirectedEdge @@@ uedges,
          ew = KeyMap[UndirectedEdge @@ # &, edgeweight],
   verts = Union[Flatten[edges /. UndirectedEdge -> List]],
   graph, dmat, newcoords, vcoords3, newLayout, vars, weights, 
   objective, min, vals, newercoords, xyz},
  
        graph = 
   Graph3D[verts, edges, EdgeWeight -> ew, 
    VertexLabels -> Placed["Name", Center], 
    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
    VertexSize -> .3, VertexStyle -> Red];
   dmat = GraphDistanceMatrix[graph];
   DistanceMatrixDimensionReduce[(dmat_)?MatrixQ, dim_: 3] := 
   With[{len = Length[dmat]}, 
    Module[{diffs, dist2mat, onevec, hmat, bmat, uu, ww, vv}, 
      onevec = ConstantArray[{1}, len];
      hmat = IdentityMatrix[len] - onevec.Transpose[onevec]/len;
      dist2mat = -dmat/2;
      bmat = hmat.dist2mat.hmat; {uu, ww, vv} = 
       SingularValueDecomposition[bmat, dim]; uu.Sqrt[ww]] /; 
     dim <= Length[dmat[[1]]] && MatchQ[Flatten[dmat], {_Real ..}]];
  newcoords = DistanceMatrixDimensionReduce[dmat];
  newLayout = 
   Graph[verts, edges, VertexCoordinates -> newcoords, 
    EdgeWeight -> ew, VertexLabels -> Placed["Name", Center], 
    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
    VertexSize -> .3, VertexStyle -> Red];
  vars = Array[xyz, {Length[verts], 3}];
  weights = Normal[WeightedAdjacencyMatrix[graph]];
  objective = 
   Sum[If[weights[[i, j]] > 
      0, ((vars[[i]] - vars[[j]]).(vars[[i]] - vars[[j]]) - 
        weights[[i, j]]^2)^2, 0], {i, Length[weights] - 1}, {j, i + 1,
      Length[weights]}];
  
  {min, vals} = 
   FindMinimum[objective, 
    Flatten[MapThread[List, {vars, newcoords}, 2], 1]];
  newercoords = vars /. vals;
      vcoords3 = MapIndexed[#2[[1]] -> # &, newercoords];
      newLayout = 
   Graph3D[verts, edges, VertexCoordinates -> vcoords3, 
    EdgeWeight -> ew, VertexLabels -> Placed["Name", Center], 
    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
    VertexSize -> .3, VertexStyle -> Red];
  Return[<|"newcoords" -> newcoords|>];
  ]

I have tried to correct the syntax errors in the code. But the run is not successful yet. I have added the output logs here.

I look forward to suggestions that will help me in resolving these errors.

$\endgroup$
6
  • 1
    $\begingroup$ Print(min) at the end - you need Print[min]; (a semicolon and square brackets are both necessary). $\endgroup$ – flinty Oct 4 '20 at 15:53
  • $\begingroup$ @flinty I made the change and the same message is still displayed $\endgroup$ – Natasha Oct 4 '20 at 16:26
  • 2
    $\begingroup$ No semi-colons in Module variable specifications, e.g. the variable here: edges = UndirectedEdge @@@ uedges; $\endgroup$ – b3m2a1 Oct 4 '20 at 16:55
  • $\begingroup$ ^ yes b3m2a1 is right - you need commas. You should really review your syntax and paste your code into a mathematica notebook to look at the syntax highlighting - it has all kinds of errors. $\endgroup$ – flinty Oct 4 '20 at 17:27
  • $\begingroup$ @b3m2a1 Thank you. Please check my edit $\endgroup$ – Natasha Oct 5 '20 at 4:30
3
$\begingroup$

I have re-written your code with as few changes as possible just to make it work:

Clear[solution3d];
solution3d[uedges_, edgeweight_] := 
 Module[{ew, graph, dmat, newcoords, vcoords3, newLayout, vars, 
   weights, objective, min, vals, newercoords, xyz, 
   DistanceMatrixDimensionReduce},
  ew = KeyMap[UndirectedEdge @@ # &, edgeweight];
  graph = 
   Graph3D[Keys[ew], EdgeWeight -> Normal[ew], 
    VertexLabels -> Placed["Name", Center], 
    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
    VertexSize -> .3, VertexStyle -> Red];
  dmat = GraphDistanceMatrix[graph];
  DistanceMatrixDimensionReduce[(dmat_)?MatrixQ, dim_ : 3] := 
   With[{len = Length[dmat]}, 
    Module[{diffs, dist2mat, onevec, hmat, bmat, uu, ww, vv}, 
      onevec = ConstantArray[{1}, len];
      hmat = IdentityMatrix[len] - onevec.Transpose[onevec]/len;
      dist2mat = -dmat/2;
      bmat = hmat.dist2mat.hmat; {uu, ww, vv} = 
       SingularValueDecomposition[bmat, dim]; uu.Sqrt[ww]] /; 
     dim <= Length[dmat[[1]]] && MatchQ[Flatten[dmat], {_Real ..}]];
  newcoords = DistanceMatrixDimensionReduce[dmat];
  newLayout = 
   Graph[Keys[ew], VertexCoordinates -> newcoords, EdgeWeight -> ew, 
    VertexLabels -> Placed["Name", Center], 
    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
    VertexSize -> .3, VertexStyle -> Red];
  vars = Array[xyz, {VertexCount[graph], 3}];
  weights = Normal[WeightedAdjacencyMatrix[graph]];
  objective = 
   Sum[If[weights[[i, j]] > 
      0, ((vars[[i]] - vars[[j]]).(vars[[i]] - vars[[j]]) - 
        weights[[i, j]]^2)^2, 0], {i, Length[weights] - 1}, {j, i + 1,
      Length[weights]}];
  {min, vals} = Quiet@FindMinimum[objective, 
    Flatten[MapThread[List, {vars, newcoords}, 2], 1]];
  newercoords = vars /. vals;
  vcoords3 = MapIndexed[#2[[1]] -> # &, newercoords];
  newLayout = 
   Graph3D[Keys[ew], VertexCoordinates -> vcoords3, EdgeWeight -> ew, 
    VertexLabels -> Placed["Name", Center], 
    EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
    VertexSize -> .3, VertexStyle -> Red];
  Return[<|"newcoords" -> newcoords|>]]



(* test it out: *)
edges = {{1, 2}, {1, 3}, {1, 4}, {2, 5}, {2, 6}, {5, 6}, {3, 4}, {3, 7}, {6, 7}, {7, 8}, {2, 9}};
ew = <|{1, 2} -> 49.6, {1, 3} -> 74.4, {1, 4} -> 49.6, {2, 5} -> 
    37.2, {2, 6} -> 74.4, {5, 6} -> 49.6, {3, 4} -> 37.2, {3, 7} -> 
    24.8, {6, 7} -> 62, {7, 8} -> 37.2, {2, 9} -> 24.8|>;

solution3d[edges, ew]

(** result: 
<|"newcoords" -> {{-1.67377, 4.63647, 1.37539}, {-5.6866, 0.575728, 
    0.0714674}, {4.71118, 1.7079, -2.10904}, {2.55599, 
    4.83333, -1.12337}, {-4.47255, -3.45886, 
    0.799296}, {-0.471663, -5.30871, -2.43743}, {5.16612, -1.4306, \
-0.875186}, {6.39076, -2.33059, 3.91076}, {-6.51947, 0.775332, 
    0.388113}}|> 
**)

You are constructing graphs with presentational elements like labels and styling, but this is kind of pointless if you are only returning newcoords. You should consider removing all those unused styling properties. You also need to print the return value of s.evaluate(Global.solution3d(edges, ew)) in Python to see any output, so that you get:

{'newcoords': PackedArray([[-1.67377155,  4.63646567,  1.37539104],
             [-5.68660341,  0.57572758,  0.0714674 ],
             [ 4.71118143,  1.70789586, -2.10903571],
             [ 2.55599235,  4.83333027, -1.12337187],
             [-4.47254779, -3.45885521,  0.79929634],
             [-0.47166292, -5.30870618, -2.43743431],
             [ 5.16612254, -1.43059762, -0.87518615],
             [ 6.39076194, -2.33059232,  3.91075979],
             [-6.51947259,  0.77533196,  0.38811348]])}
$\endgroup$

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