Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue while evaluating MMA expression in Python #24

Closed
DeepaMahm opened this issue Sep 25, 2020 · 6 comments
Closed

issue while evaluating MMA expression in Python #24

DeepaMahm opened this issue Sep 25, 2020 · 6 comments
Labels
wolfram language bug A bug in the Wolfram Language.

Comments

@DeepaMahm
Copy link

DeepaMahm commented Sep 25, 2020

Hi All,
This is a follow up to the question posted here

I've the following MMA code

edges = {1 <-> 2, 1 <-> 3, 1 <-> 4, 2 <-> 5, 2 <-> 6, 5 <-> 6, 
   3 <-> 4, 3 <-> 7, 6 <-> 7, 7 <-> 8, 2 <-> 9};

vd = {{75., 25., 0}, {115., 45., 0}, {10., 5., 0}, {45., 0, 0}, 
  {90., 60., 0}, {45., 55., 0}, {0, 25., 0}, {10., 50., 0}, {115.,  25.,0}};

vl = Range[Length@vd];

vcoords = MapIndexed[#2[[1]] -> # &, vd];
ew = {1 \[UndirectedEdge] 2 -> 49.6, 1 \[UndirectedEdge] 3 -> 74.4, 
 1 \[UndirectedEdge] 4 -> 49.6, 2 \[UndirectedEdge] 5 -> 37.2, 
 2 \[UndirectedEdge] 6 -> 74.4, 5 \[UndirectedEdge] 6 -> 49.6, 
 3 \[UndirectedEdge] 4 -> 37.2, 3 \[UndirectedEdge] 7 -> 24.8, 
 6 \[UndirectedEdge] 7 -> 62, 7 \[UndirectedEdge] 8 -> 37.2, 
 2 \[UndirectedEdge] 9 -> 24.8}

g3d = Graph3D[vl, edges, VertexCoordinates -> vcoords, 
  EdgeWeight -> ew, VertexLabels -> Placed["Name", Center], 
  EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]}, 
  VertexSize -> .3, VertexStyle -> Red]
vars3d = Array[Through[{x, y, z}@#] &, Length @ vd];

λ = 1/100.;

obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /. ew)^2 & /@ 
  EdgeList[g3d]] +  λ Total[Norm /@ (vars3d - vd)];

lbnd = 0;
ubnd = 500;

solution3d = Last@Minimize[{obj3d, And @@ Thread[lbnd <= Join @@ vars3d <= ubnd]}, 
    Join @@ vars3d];

edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /. 
     solution3d & /@ EdgeList[g3d];

Grid[Prepend[{#, # /. ew, # /. edgeLengths3d} & /@ 
   EdgeList[g3d], {"edge", "EdgeWeight", "Edge Length"}], 
 Dividers -> All]

Following the suggestions offered in the link shared above I installed wolframclient and tried the following


from wolframclient.evaluation import WolframLanguageSession
session = WolframLanguageSession()
from wolframclient.language import wlexpr


session.evaluate(wlexpr(
'edges = {1 <-> 2, 1 <-> 3, 1 <-> 4, 2 <-> 5, 2 <-> 6, 5 <-> 6, 3 <-> 4, 3 <-> 7, 6 <-> 7, 7 <-> 8, 2 <-> 9};'

'vd = {{75., 25., 0}, {115., 45., 0}, {10., 5., 0}, {45., 0, 0},{90., 60., 0}, {45., 55., 0}, {0, 25., 0}, {10., 50., 0}, {115.,  25.,0}};'

'vl = Range[Length@vd];'
'vcoords = MapIndexed[#2[[1]] -> # &, vd];'
'ew = {1 \[UndirectedEdge] 2 -> 49.6, 1 \[UndirectedEdge] 3 -> 74.4,'
'1 \[UndirectedEdge] 4 -> 49.6, 2 \[UndirectedEdge] 5 -> 37.2,'
'2 \[UndirectedEdge] 6 -> 74.4, 5 \[UndirectedEdge] 6 -> 49.6,'
'3 \[UndirectedEdge] 4 -> 37.2, 3 \[UndirectedEdge] 7 -> 24.8,'
'6 \[UndirectedEdge] 7 -> 62, 7 \[UndirectedEdge] 8 -> 37.2,'
'2 \[UndirectedEdge] 9 -> 24.8};'

'g3d = Graph3D[vl, edges, VertexCoordinates -> vcoords,EdgeWeight -> ew, VertexLabels -> Placed["Name", Center],'
'EdgeLabels -> {e_ :> Placed["EdgeWeight", Center]},'
'VertexSize -> .3, VertexStyle -> Red];'

'vars3d = Array[Through[{x, y, z}@#] &, Length @ vd];'
'λ = 1/100.;'
'obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /. ew)^2 & /@EdgeList[g3d]] +  λ Total[Norm /@ (vars3d - vd)];'
'lbnd = 0;'
'ubnd = 500;'

'solution3d = Last@Minimize[{obj3d, And @@ Thread[lbnd <= Join @@ vars3d <= ubnd]},Join @@ vars3d];'

'edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /.solution3d & /@ EdgeList[g3d];'

'Grid[Prepend[{#, # /. ew, # /. edgeLengths3d} & /@EdgeList[g3d], {"edge", "EdgeWeight", "Edge Length"}],Dividers -> All];'

'z1 = Values[solution3d] // Partition[#, 3] &;'

'theFile = File["op.txt"];'

'Export[theFile, z1, "Table"];'
    ))

but I get the following error

String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Further output of MessageName[StringForm, string] will be suppressed during this calculation.
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Undefined message MessageName[Message, msgl] with arguments {$MessageList}
String expected at position 1 in StringForm[MessageName[General, msgl], $MessageList].
Further output of MessageName[StringForm, string] will be suppressed during this calculation.
The problem may be unbounded. Specifying a value for MaxIterations greater than 5000 may improve the solution.

Suggestions on how to resolve this error will be really helpful.

@DbxDev DbxDev added the wolfram language bug A bug in the Wolfram Language. label Sep 25, 2020
@DbxDev
Copy link
Contributor

DbxDev commented Sep 25, 2020

This is the same WolframLanguage bug as witnessed in #22. It'll be fixed in 12.2 (I can reproduce on a 12.1 build, but not with a recent prototype build).
Messages that should be Quiet-ed, are incorrectly issued in some cases.

@DbxDev DbxDev closed this as completed Sep 25, 2020
@DeepaMahm
Copy link
Author

DeepaMahm commented Sep 25, 2020

@DbxDev Thanks, could you please explain how to pass the input arguments from python to .m file and load it back as MMA expression in python {edges,vl,ew,vd}=ImportString[#,"PythonExpression"]&/@ {"[(1,2),(1,3),(1,4),(2,5),(2,6),(5,6),(3,4),(3,7),(6,7),(7,8),(2,9)]", "[1,2,3,4,5,6,7,8,9]","{(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}", "{1:[75.,25.,0],2:[115.,45.,0],3:[10.,5.,0],4:[45.,0,0],5:[90.,60.,0],6:[45.,55.,0],7:[0,25.,0],8:[10.,50.,0],9:[115.,25.,0]}"}; ?

@DeepaMahm
Copy link
Author

DeepaMahm commented Sep 28, 2020

@DbxDev

I tried

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

    session = WolframLanguageSession()

    edges = [(1, 2), (1, 3), (1, 4), (2, 5), (2, 6), (5, 6), (3, 4), (3, 7), (6, 7), (7, 8), (2, 9)]
    vl = [1, 2, 3, 4, 5, 6, 7, 8, 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}
    vd = {1: [75., 25., 0], 2: [115., 45., 0], 3: [10., 5., 0], 4: [45., 0, 0], 5: [90., 60., 0], 6: [45., 55., 0], 7: [0, 25., 0], 8: [10., 50., 0], 9: [115., 25., 0]}
    with WolframLanguageSession() as s:
        solution3d = wl.Get('test.m')
        s.evaluate(Global.solution3d(edges, vd, vl, ew))

test.m includes

solution3d[edges_, vd_, vl_, ew_] := (

    {edges,vl,ew,vd}=ImportString[#,"PythonExpression"]&/@{edges,vl,ew,vd};
    edges = UndirectedEdge @@@ edges; vcoords = List @@ vd;
    ew = Normal @ KeyMap[UndirectedEdge @@ # &,ew];

    g3d = Graph3D[vl, edges, VertexCoordinates -> vcoords, EdgeWeight->ew, VertexLabels->Placed["Name",Center],
    EdgeLabels->{e_:>Placed["EdgeWeight",Center]}, VertexSize->.5, BaseStyle->16];

    edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /.solution3d & /@ EdgeList[g3d];

    vars3d = Array[Through[{x, y, z}@#] &, Length@vd];
    \[Lambda] = 1/100.; lbnd = 0; ubnd = 500;

    obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /. (Rule @@@ ew))^2 & /@ EdgeList[g3d]] + \[Lambda] * Total[Norm /@ (vars3d - Values@vd)];
    solution3d = Last @ Minimize[{obj3d, And @@ Thread[lbnd <= Join @@ vars3d <= ubnd]}, Join @@ vars3d];

    edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /.solution3d & /@ EdgeList[g3d];
    ResourceFunction["PrettyGrid"][{#, # /. ew, # /. edgeLengths3d} & /@EdgeList[g3d],  "ColumnHeadings" -> {"edge", "EdgeWeight", "Edge Length"}];

    z1 = Values[solution3d] // Partition[#, 3] &;

    theFile = File["result.txt"];

    Export[theFile, z1, "Table"];
)

I'm not sure if

 solution3d = wl.Get('test.m')
 s.evaluate(Global.solution3d(edges, vd, vl, ew))

this right, nothing is written to the txt file unfortunately. Could you please have a look?

@DeepaMahm
Copy link
Author

@DbxDev This is a kind reminder

@DbxDev
Copy link
Contributor

DbxDev commented Sep 29, 2020

This goes beyond the scope of this ticket and should rather be discussed on stackoverflow.

You're confusing Wolfram Language representation in Python and actual code evaluation. The python code solution3d = wl.Get('test.m') represents a WL expression that is never evaluated and should be replaced with s.evaluate(wl.Get('test.m')). It'll declare the WL function Global`solution3d for the given session that you're using afterward.

Remember that WL code declared in Python (using wl.xxx syntax) must be evaluated in a session using (session.evaluate(...)) otherwise it stays inert!

@DeepaMahm
Copy link
Author

@DbxDev Thank you. Unfortunately, I couldn't run it successfully after making the change that has been suggested. I have opened a new thread on stackoverflow as you suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wolfram language bug A bug in the Wolfram Language.
Projects
None yet
Development

No branches or pull requests

2 participants