Python'dan Mathematica nasıl kullanılır
3B geometri ( ref ) oluşturmak için aşağıdaki kod satırlarını kullanıyorum . Girişler edges, vd, vlve ewaşağıdaki biçimlerde Python gelen
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]};
Yukarıdakileri Mathematica'da kullanılan giriş formatlarına manuel olarak dönüştürüyorum. Bu manuel dönüştürmeyi nasıl önleyeceğimi ve Mathematica kodunu Python'dan doğrudan entegre edip çalıştırmayı öğrenmek istiyorum.
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]
Python'dan Mathematica'ya nasıl devam edileceğine ve arayüzle nasıl bağlantı kurulacağına dair öneriler gerçekten yardımcı olacaktır.
DÜZENLEME: Aşağıda yayınlanan cevap, Python'dan PythonExpression. Daha sonra, bu Mathematica ifadelerini bir python betiğinden değerlendirmek istiyorum. Aşağıdaki yorumlara dayanarak wolframclient yükledim ve aşağıdakileri yaptım
from wolframclient.evaluation import WolframLanguageSession
session = WolframLanguageSession()
from wolframclient.language import wlexpr
session.evaluate(wlexpr('')) # I would like to know how to inclide Mathematica expressions here
EDIT2: Yapabilir miyim
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];'))
Denedim,
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"];'
))
Ama şu hatayı alıyorum,
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.
Lütfen bunun nasıl düzeltilebileceğini önerebilir misiniz? Aşağıda gösterildiği gibi, MMA dizüstü bilgisayarda aynı ifadelerin çalıştırılmasında herhangi bir sorun yoktu.
Yanıtlar
İşte Mathematica'da istediğinizi yapmanın bir yolu.
İlk olarak, "PythonExpression" kullanmak, bir şeyleri içe / dışa aktarmak için kullanışlı olabilir:
{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]}"};
Ne yazık ki, Grafikler henüz İlişkilendirmelerle çalışmıyor, bu nedenle listelere ihtiyacınız var ve kenarlarda UndirectedEdgeveya gibi semboller kullanılmalıdır DirectedEdge:
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]
Hesaplamanız neredeyse çalışıyordu, ancak kenarları kurallara dönüştürmeniz gerekiyordu:
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]
O zaman iyi çalışıyor:
edgeLengths3d = # -> Norm[vars3d[[First@#]] - vars3d[[Last@#]]] /.
solution3d & /@ EdgeList[g3d];
ResourceFunction["PrettyGrid"][{#, # /. ew, # /. edgeLengths3d} & /@
EdgeList[g3d], "ColumnHeadings" -> {"edge", "EdgeWeight", "Edge Length"}]
Maalesef yanılmışım ve MMA'yı Python'dan kullanmak istediğini, tersi olmadığını hatırlamadım. ExternalEvaluate ["Python", str] bir MMA komutudur, Python değildir.
Python'dan MMA girdisinin nasıl verileceği burada açıklanmaktadır: "https://reference.wolfram.com/language/workflow/EvaluateAWolframLanguageExpressionFromPython.html".
Python'u başlattıktan sonra, Python'da çalıştırırsınız:
from wolframclient.evaluation import WolframLanguageSession
session = WolframLanguageSession()
from wolframclient.language import wlexpr
session.evaluate(wlexpr('myCommandString'))
myCommandString, Mathematica ifadelerinizin bulunduğu dizedir. Örneğin Python'da:
myCommandString="a=1;b=2;a+b"
Veya bunu birkaç satırda istiyorsanız:
myCommandString="a=1;"
myCommandString=myCommandString+"b=2;"
myCommandString=myCommandString+"a+b"
Bu yardımcı olur umarım.
Birden çok satıra yayılan bir kod bloğunuz varsa, onu bir .m dosyasına ve dosyayı python'dan koymak yararlı olabilir Get. İşte bir örnek:
Önce bir dosya oluşturun ve içinde değerlendirmek istediğiniz Wolfram Dil kodunu yazın. Dosyayı arayalım /tmp/test.m.
Şimdi Python'da:
from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl
# important note: the session is automatically closed.
with WolframLanguageSession() as s:
s.evaluate(wl.Get('/tmp/test.m'))
Kapatmayı unutmayın, WolframLanguageSessionaksi takdirde öksüz çekirdekler alırsınız (daha fazla bilgi burada ).
Gördüğünüz gibi değerlendirme adımı artık tek bir satıra sığmaktadır. En sevdiğiniz düzenleyicide kodunuzu güncellemekte özgürsünüz. İlk kodunuzla tam olarak bunu yaptım, sadece iki eksik noktalı virgül ekledim ve sonucu daha sonra gerçekleştirildiği gibi dışa aktardım.
İşte /tmp/test.mdosyam:
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];
\[Lambda] = 1/100.;
obj3d = Total[(Norm[vars3d[[First@#]] - vars3d[[Last@#]]] - # /.
ew)^2 & /@ EdgeList[g3d]] + \[Lambda] 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];
z1 = Values[solution3d] // Partition[#, 3] &;
Export["/tmp/result.txt", z1, "Table"];
```