(************** Content-type: application/mathematica ************** CreatedBy='Mathematica 5.2' Mathematica-Compatible Notebook This notebook can be used with any Mathematica-compatible application, such as Mathematica, MathReader or Publicon. The data for the notebook starts with the line containing stars above. To get the notebook into a Mathematica-compatible application, do one of the following: * Save the data starting with the line of stars above into a file with a name ending in .nb, then open the file inside the application; * Copy the data starting with the line of stars above to the clipboard, then use the Paste menu command inside the application. Data for notebooks contains only printable 7-bit ASCII and can be sent directly in email or through ftp in text mode. Newlines can be CR, LF or CRLF (Unix, Macintosh or MS-DOS style). NOTE: If you modify the data for this notebook not in a Mathematica- compatible application, you must delete the line below containing the word CacheID, otherwise Mathematica-compatible applications may try to use invalid cache data. For more information on notebooks and Mathematica-compatible applications, contact Wolfram Research: web: http://www.wolfram.com email: info@wolfram.com phone: +1-217-398-0700 (U.S.) Notebook reader applications are available free of charge from Wolfram Research. *******************************************************************) (*CacheID: 232*) (*NotebookFileLineBreakTest NotebookFileLineBreakTest*) (*NotebookOptionsPosition[ 128833, 3526]*) (*NotebookOutlinePosition[ 133997, 3686]*) (* CellTagsIndexPosition[ 133208, 3658]*) (*WindowFrame->Normal*) Notebook[{ Cell[CellGroupData[{ Cell[TextData[{ "Implementing an XML-RPC client in ", StyleBox["Mathematica", FontSlant->"Italic"] }], "Title", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["Dario Malchiodi", "Author", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Dipartimento di Scienze dell'Informazione, Universit\[AGrave] degli Studi \ di Milano\nhttp://homes.dsi.unimi.it/~malchiod", StyleBox["\nmailto:", FontSlant->"Italic"], StyleBox[ButtonBox["malchiodi@dsi.unimi.it", ButtonData:>{ URL[ "mailto:malchiodi@dsi.unimi.it"], None}, ButtonStyle->"Hyperlink"], FontSlant->"Italic"] }], "TextAboutAuthor", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "XML-RPC is a protocol used to remotely execute a program independently of \ the particular hardware and operating system used on both ends of the \ communication channel, in that all the conveyed information consists in text \ containing XML encodings coupled with HTTP headers. A sagacious mix of ", StyleBox["J/Link", FontSlant->"Italic"], ", XML, and RegularExpression technologies available within ", StyleBox["Mathematica", FontSlant->"Italic"], " allows to easily implement a client exploiting this protocol." }], "Abstract", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Introduction" }], "SectionFirst", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ The possibility of executing code remotely, i.e. sending the \ arguments from a given computer to another one actually performing the \ execution and sending back the return value, allows for a correct use of \ high-performance computing facilities, such as clusters [1] and grids [4]. \ This kind of interaction, initially introduced by Sun Microsystems [12], is \ known as Remote Procedure Call (RPC for short) and represents an \ implementation of the client-server model for distributed programming, which \ has been implemented in various forms (see for instance the SOAP [11] \ protocol).\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "In order to insure that the protocol is independent of the used computing \ environment, the client encodes the procedure's name and arguments using an \ ", StyleBox["interface description language", FontSlant->"Italic"], ", and this encoding is sent to the server through a given ", StyleBox["network protocol", FontSlant->"Italic"], ". The same protocol and language are then used to send back the \ procedure's return value." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". The XML-RPC protocol" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"Sec. XML-RPC"], Cell["\<\ XML-RPC is an implementation of RPC [12] encoding the interface \ description language through XML (eXtensible Markup Language) [14] and using \ HTTP (HyperText Transfer Protocol) [3] as network protocol. The basic idea is \ to handle RPCs using POST requests whose content is a XML encoding of the \ method name and of the related arguments.\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ The typical call is encoded through the following request, to be \ sent to an existing server:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "POST /PRC2 HTTP/1.0\nUser-Agent: ", StyleBox["agent", "MB"], "\nHost: ", StyleBox["host", "MB"], "\nContent-Type: text/xml\nContent-Length: ", StyleBox["length", "MB"], "\n\n\n\n ", StyleBox["method name", "MB"], "\n \n \n <", StyleBox["type", "MB"], ">", StyleBox["value", "MB"], "\n \n ...\n \n" }], "Program", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ where bold text denotes the following values to be adapted to each \ particular call:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["agent", "MB"], " and ", StyleBox["host", "MB"], " are strings qualifying respectively: i) the environment from within the \ call is requested (typically the used software name, release, and operating \ system), and ii) the corresponding host location (in terms of a symbolic or \ numeric IP);" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["length", "MB"], " counts the number of bytes of the call ", StyleBox["payload", FontSlant->"Italic"], " (the following XML structure);" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["method name", "MB"], " is the name of the procedure to be executed;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["value", "MB"], " represents the value of the method's first argument. It is enclosed \ between nested ", StyleBox["param", "MR"], " and ", StyleBox["value", "MB", FontWeight->"Plain"], " tags, containing a further tag whose name (denoted ", StyleBox["type", "MB"], " in the above example) encodes the argument type. Supported types, both at \ the simple and structured level, are listed in Table ", CounterBox["NumberedTable", "tab.1"], "." }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ "Each argument is encoded in a ", StyleBox["param", "MR"], " tag, and their ordering must match the one specified in the called \ method's signature." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ FormBox[GridBox[{ { RowBox[{ StyleBox["int", "MR", FontSize->10], StyleBox[",", FontSize->10], StyleBox["i4", "MR", FontSize->10]}], StyleBox[\(signed\ integer\ \((four\ bytes)\)\), "Text"]}, { StyleBox["boolean", "MR", FontSize->10], StyleBox[\(boolean\ \((0 = false, \ 1 = true)\)\), "Text"]}, { StyleBox["string", "MR", FontSize->10], StyleBox["string", "Text"]}, { StyleBox["double", "MR", FontSize->10], StyleBox[\(floating\ point\ number\), "Text"]}, { StyleBox[\(dateTime . iso8601\), "MR", FontSize->10], StyleBox[\(date/time\ \((in\ ISO\ 8601\ format)\)\), "Text"]}, { StyleBox["base64", "MR", FontSize->10], StyleBox[\(base64\[Dash]encoded\ binary\), "Text"]}, { StyleBox["array", "MR", FontSize->10], StyleBox[\(array\ of\ data\), "Text"]}, { StyleBox["struct", "Program", FontSize->10], StyleBox[\(XML\ structure\), "Text"]} }, ColumnAlignments->{Left}, GridFrame->True, RowLines->True], TraditionalForm]], "NumberedTable", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["Supported data types in XML-RPC.", "Caption", PageWidth->PaperWidth, PageBreakBelow->Automatic, TextAlignment->Left, TextJustification->0, CellTags->"tab.1"], Cell[TextData[{ "Consider for instance a ", StyleBox["getSales", "MR"], " method, with intuitive meaning and signature ", StyleBox["int getSales(String region, int year)", "MR"], "; the POST request corresponding to a call to this method is the following \ (using dummy values for the ", StyleBox["User-Agent", "MR"], " and ", StyleBox["Host", "MR"], " entries):" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ POST /PRC2 HTTP/1.0 User-Agent: XML-RPC client (OS) Host: 10.0.0.1 Content-Type: text/xml Content-Length: 240 getSales Europe 2002 \ \>", "Program", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ Once a request is sent, the server answers sending an HTTP document \ whose payload contains either the return value for the method or an error \ message. In the first case, the server returns\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "HTTP/1.0 200 OK\nServer: ", StyleBox["server", "MB"], "\nDate: ", StyleBox["date", "MB"], "\nContent-Type: text/xml\nContent-length: ", StyleBox["length", "MB"], "\n\n\n\n \n \n \ <", StyleBox["type", "MB"], ">", StyleBox["value", "MB"], "\n \n \n" }], "Program", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "where the entries typeset in bold have either an obvious meaning or are \ encoded as in the previous ", StyleBox["", "MR"], " structure. Note that in this case the payload contains exactly one ", StyleBox["param", "MR"], " tag, for a method has only one return value; Multiple return values can \ be dealt with using the ", StyleBox["array", "MR"], " and ", StyleBox["struct", "MR"], " tags [14]." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "For instance, a successful call to the ", StyleBox["getSales", "MR"], " method introduced before could give rise to the following answer:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ HTTP/1.0 2000 OK Server: XML-RPC server (OS) Date: Tue, 10 Jan 2006 22:30:48 GMT Content-Type: text/xml Content-length: 142 2564 \ \>", "Program", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Unsuccesfull calls give rise to a different ", StyleBox["methodResponse", "MR"], " tag, enclosing a ", StyleBox["fault", "InlineInput", FontWeight->"Plain"], " tag instead of the ", StyleBox["params", "InlineInput", FontWeight->"Plain"], " one. The former in turn contains a ", StyleBox["struct", "MR"], " tag encoding an integer code and a textual description for the error." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". The ", StyleBox["Mathematica", FontSlant->"Italic"], " implementation" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"Sec. Mathematica implementation"], Cell[TextData[{ "Implementing an XML-RPC client in ", StyleBox["Mathematica", FontSlant->"Italic"], " requests to set up a network channel as communication medium, generating \ and sending through the latter the header and payload for a given RPC, \ reading the corresponding answer, validating it against possible errors and \ finally converting the result into ", StyleBox["Mathematica", FontSlant->"Italic"], " expressions. " }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "This implementation is available for download in form of a package [8], \ which can be used to extend ", StyleBox["Mathematica", FontSlant->"Italic"], "'s abilities of remotely accessing computational facilities, in that the \ available Web services package does not manage the XML-RPC protocol." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Setting up the communication channel" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"Sec. Comm. channel"], Cell["\<\ The first step consists in launching the Java runtime and storing \ in two variables the address and port of the server. Throughout this paper we \ will quote as an application example the NEOS server for optimization [2], a \ distributed, multi-method optimization system with multiple interfaces, \ including a set of APIs accessible through XML-RPC.\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[{ \(\(<< JLink`;\)\), "\[IndentingNewLine]", \(\(InstallJava[];\)\), "\[IndentingNewLine]", \($xmlRpcServer = "\"; $xmlRpcPort = 3332;\)}], "Input",\ PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "In order to provide a medium through which vehiculate XML-RPC requests and \ answers, socket-based communication needs to be set up. This can be done \ accessing the ", StyleBox["java.net", "MR"], " and ", StyleBox["java.io", "MR"], " packages through ", StyleBox["J/Link:", FontSlant->"Italic"], " " }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[{ \(\(cli = JavaNew["\", $xmlRpcServer, $xmlRpcPort];\)\), "\ \[IndentingNewLine]", \(\(out = JavaNew["\", cli@getOutputStream[]];\)\), "\[IndentingNewLine]", \(\(in = JavaNew["\", cli@getInputStream[]];\)\)}], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "in this way, the ", StyleBox["in", "InlineInput"], " and ", StyleBox["out", "InlineInput"], " variables will point to an input and an output stream which will be used \ for sending XML-RPC requests and receiving the corresponding answers, \ respectively." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Formatting requests" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Requests to an XML-RPC server follow the format explained in Sec. ", CounterBox["Section", "Sec. XML-RPC"], ", i.e. an HTTP header followed by an XML structure. Let us initially focus \ on the latter. Using the SymbolicXML format available within ", StyleBox["Mathematica", FontSlant->"Italic"], " it is possible to create its skeleton to be filled afterwards:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(\(xmlTempl = ImportString["\<\>", \ "\"];\)\)], "Input", CellLabel->"In[7]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "The simplest call is that to a method requesting no arguments. In this \ case the sole part of the skeleton to be filled is the empty ", StyleBox["methodName", "MR"], " tag, then SymbolicXML can be translated into a string through the ", StyleBox["ExportString", "InlineInput"], " function. For instance, the following cell stores in the ", StyleBox["payload1", "InlineInput"], " variable the XML encoding of a call to the method ", StyleBox["version", "MR"], "\[LongDash]used for testing purposes\[LongDash]which requests no arguments \ and returns a string describing the server version number:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[{ \(\(methodName = "\";\)\), "\[IndentingNewLine]", \(\(xmlObj = xmlTempl /. XMLElement["\", {}, {}] \[Rule] XMLElement["\", {}, {methodName}];\)\), "\ \[IndentingNewLine]", \(payload1 = ExportString[xmlObj, "\"]\)}], "Input", CellLabel->"In[20]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("\n\n version\ \n \n"\)], "Output", CellLabel->"Out[22]=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "When a method requests one or more arguments, also the ", StyleBox["params", "MR"], " tag need to be filled with a ", StyleBox["param", "MR"], " tag for each argument: in view of an implementation independent of a \ particular method call, this can be accomplished storing the arguments in a \ list (where each argument is in turn a list containing its type and value), \ over which a suitable function is mapped. For instance, the following cell \ stores in the ", StyleBox["payload2", "InlineInput"], " variable the XML encoding of a call to the method ", StyleBox["listSolversInCategory", "MR"], ", which returns a list of all the solvers pertaining to a given category, \ specified as argument (this example uses the category \"nco\", standing for \ \"non-constrained optimization\"):" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[{ \(\(methodName = "\";\)\), "\[IndentingNewLine]", \ \(\(params = {{"\", "\"}};\)\), "\[IndentingNewLine]", \(\(xmlObj = xmlTempl /. XMLElement["\", {}, {}] \[Rule] XMLElement["\", {}, {methodName}];\)\), "\ \[IndentingNewLine]", \(\(xmlObj = xmlObj /. XMLElement["\", {}, {}] \[Rule] XMLElement["\", {}, Map[XMLElement["\", {}, {XMLElement["\", {}, \ {XMLElement[#[\([1]\)], {}, {#[\([2]\)]}]}]}] &, params]];\)\), "\[IndentingNewLine]", \(payload2 = ExportString[xmlObj, "\"]\)}], "Input", CellLabel->"In[8]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("\n\n \ listSolversInCategory\n \n \n \ \n nco\n \n \n \n\ "\)], "Output", CellLabel->"Out[12]=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell["\<\ Once the payload has been built, the corresponding header is easily \ obtained after joining a set of strings\[LongDash]one per header entry\ \[LongDash]as follows:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "the ", StyleBox["POST", "MR"], " and ", StyleBox["Content-type", "MR"], " entries are rendered as constant strings;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ "the ", StyleBox["User-Agent", "MR"], " value specifies the ", StyleBox["Mathematica", FontSlant->"Italic"], " version and operating system, obtained respectively from the ", StyleBox["$VersionNumber", "InlineInput"], " and ", StyleBox["$System", "InlineInput"], " variables;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ "the ", StyleBox["Host", "MR"], " value consists in the joined values of the ", StyleBox["$MachineName", "InlineInput"], " and ", StyleBox["$MachineDomain", "InlineInput"], " variables;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ "the ", StyleBox["Content-Length", "MR"], " value is obtained as the length of the string containing the payload to \ be sent." }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ "For instance, a header for the request contained in ", StyleBox["payload1", "InlineInput"], " defined above is built as follows:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[{ \(\(head1 = "\";\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> "\";\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> ToString[$VersionNumber];\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> "\< (\>" <> $System <> "\<)\n\>";\)\), \ "\[IndentingNewLine]", \(\(head1 = head1 <> "\" <> $MachineName;\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> "\<.\>" <> $MachineDomain <> "\<\n\>";\)\), "\ \[IndentingNewLine]", \(\(head1 = head1 <> "\";\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> "\";\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> ToString[ StringLength[payload1]] <> "\<\n\>";\)\), "\[IndentingNewLine]", \(\(head1 = head1 <> "\<\n\>";\)\)}], "Input", CellLabel->"In[23]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["so that the whole content to be sent to the server is", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(\(Print[head1 <> payload1];\)\)], "Input", CellLabel->"In[30]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("POST /RPC2 HTTP/1.0\nUser-Agent: Mathematica/5.1 (Mac OS X)\nHost: \ smirnov.\nContent-Type: text/xml\nContent-Length: 93\n\n\ \n\n version\n \n"\ \)], "Print", CellLabel->"From In[30]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "The same procedure applies to other headers, for instance the one \ corresponding to the variable ", StyleBox["payload2", "InlineInput"], ". The only difference possibly stands in the ", StyleBox["Content-Length", "MR"], " entry." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Sending requests and receiving answers" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"Sec. sending-receiving"], Cell[TextData[{ "Sending a request is a matter of writing the previously obtained string on \ the socket output stream, namely calling the ", StyleBox["writeBytes", "InlineInput"], " method of the ", StyleBox["DataOutputStream", "InlineInput"], " class. This involves again the use of ", StyleBox["J/Link", FontSlant->"Italic"], ":" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(\(out@writeBytes[head1 <> payload1];\)\)], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "A dual action is requested to retrieve the return value of the called \ method, which will involve reading from the input stream contained in the ", StyleBox["in", "InlineInput"], " variable. Unlike the send process, in this case the amount of data to be \ read is unknown, thus the stream will be read one line at a time, until a ", StyleBox["Null", "InlineInput"], " value is returned, denoting the end of input:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[{ \(answer\ = \ "\<\>"; fetch = in@readLine[];\), "\[IndentingNewLine]", \(\(While[ StringQ[fetch], \[IndentingNewLine]answer = answer <> fetch <> "\<\n\>"; \[IndentingNewLine]fetch = in@readLine[];];\)\)}], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ As no more interaction with the server is required, the socket and \ the streams can be safely closed:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(out@close[]; in@close[]; cli@close[];\)], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Now, if the method has been correctly called, the ", StyleBox["answer", "InlineInput"], " variable contains the value returned by the called method. However, this \ value is encoded as explained in Sec. ", CounterBox["Section", "Sec. XML-RPC"], ":" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(\(Print[answer];\)\)], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("HTTP/1.0 200 OK\nServer: BaseHTTP/0.3 Python/2.4.1\nDate: Sat, 14 Jan \ 2006 16:29:14 GMT\nContent-type: text/xml\nContent-length: 140\n\n\n\n\n\nneos \ version 5\n\n\n\n"\)], \ "Print", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell["\<\ The first action to be performed on this return value consists in \ extracting the payload: this can be simply done after ignoring all the string \ contents until a couple of newlines is found:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(retVal = StringReplace[answer, RegularExpression["\<(.|\n)*?\n\n((.|\n)*)\>"] -> "\<$2\>"]\)], \ "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("\n\n\n\n\ neos version 5\n\n\n\ \n"\)], "Output", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "The same execution on the ", StyleBox["listSolversInCategory", "MR"], " (i.e. processing the value returned after having sent ", StyleBox["head2<>payload2", "InlineInput"], " on the communication channel) would bring to the following result:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("\n\n\n\n\ \nCONOPT:GAMS\n\ filter:AMPL\n\ Ipopt:AMPL\n\ KNITRO:AMPL\n\ KNITRO:GAMS\n\ LANCELOT:AMPL\n\ LANCELOT:SIF\n\ LOQO:AMPL\n\ MINOS:AMPL\n\ MINOS:GAMS\n\ MOSEK:AMPL\n\ MOSEK:GAMS\n\ PATHNLP:GAMS\n\ PENNON:AMPL\n\ SNOPT:AMPL\n\ SNOPT:FORTRAN\n\ SNOPT:GAMS\n\n\ \n\n\n"\)], "Output", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Erroneus remote calls (such as one to a nonexistent method) are detected \ exploiting the different contents of the ", StyleBox["methodResponse", "InlineInput"], " tag. Namely, if the returned payload matches with the regular expression" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(___ ~~ \("\<\>" ~~ \(___ ~~ \("\<\>" ~~ ___\)\)\)\)], \ "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ the RPC has been correctly executed. Otherwise, an error \ occurred.\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Decoding output" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"Sec. Decoding"], Cell[TextData[{ "The first action to be done with a string description obtained in Sec. ", CounterBox["Section", "Sec. sending-receiving"], " which wasn't filtered against errors is to extract the meaningful \ information contained in the ", StyleBox["param", "MR"], " tag. This is accomplished, as in previous sections, using a suitable \ string matching procedure extracting the type and value\[LongDash]ever \ described using strings\[LongDash]of the corresponding return value and \ inserting them in a list." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(\(StringReplace[ retVal, ___ ~~ \("\<\>" ~~ \(Whitespace ... ~~ \ \("\<\>" ~~ \(Whitespace ... ~~ \("\<<\>" ~~ \(v : Except["\<>\>"] .. ~~ \("\<>\>" ~~ \(j___ ~~ \ \("\<" ~~ \(Except["\<>\>"] .. ~~ \("\<>\>" ~~ \(Whitespace ... ~~ \ \("\<\>" ~~ \(Whitespace ... ~~ \("\<\>" ~~ \ ___\)\)\)\)\)\)\)\)\)\)\)\)\)\)\) \[Rule] {v, j}]\)[\([1]\)]\)], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \({"string", "neos version 5"}\)], "Output", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "On this list we will compute a function decoding the values into ", StyleBox["Mathematica", FontSlant->"Italic"], " expressions. This function has to handle the different types supported by \ the XML-RPC protocol. The implementation is straightforward for the simpler \ types: integer and floating-point values are esaily dealt with using the ", StyleBox["ToExpression", "InlineInput"], " function, boolean values are examined exaustively and strings are \ obviously left untouched. Analogously, the XML tree described by the ", StyleBox["struct", "MR"], " data type can be automatically converted into an ", StyleBox["XMLObject", "InlineInput"], " using the ", StyleBox["ImportString", "InlineInput"], " function." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ FormBox[GridBox[{ { StyleBox[\(clear\ text\), "Text"], StyleBox[\(A\ Mathematica\ XML - RPC\ package\), "Text"]}, { StyleBox["encoding", "Text"], StyleBox[\(\(QSBNYXRoZW1hdGljYSBYTUwtUlBDIHBhY2thZ2U\)\(=\)\), "Program"]} }, GridFrame->True, RowLines->True, ColumnLines->True], TraditionalForm]], "NumberedTable", PageWidth->PaperWidth, PageBreakBelow->Automatic, TextAlignment->Center, TextJustification->0], Cell["A string of text and the corresponding base64 encoding.", "Caption", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"tab.2"], Cell[TextData[{ "Base64 encoded values need a slightly more complex processing: this 64-bit \ encoding [6]\[LongDash]typically used in order to encode binary attachments \ to e-mails\[LongDash]maps a group of three consecutive bytes with four ASCII \ printable characters, as exemplified in Table ", CounterBox["NumberedTable", "tab.2"], ". Thus the corresponding decoding consists of:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ a function implementing the decode table, mapping a single \ printable character from the encoded text into a byte;\ \>", "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell["\<\ a function mapping a set of four consecutive characters in output \ of the function in previous point into the corresponding set of three bytes \ in the decoded text;\ \>", "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell["\<\ a function partitioning the encoded text into successive groups of \ four characters and applying to the latter the above function (possibly \ discarding trailing '=' characters, used during the encoding phase to pad \ original sequences not amounting to a multiple of three bytes).\ \>", "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell["\<\ A similar procedure can be used in order to encode clear text using \ the same protocol [7].\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Finally, the ISO8601 standard [5] for time and date can be easily \ processed: as the required format for a time/date is ", StyleBox["yyyy-mm-ddThh:mm:ss,", "MR"], " we can overload ", StyleBox["ToDate", "InlineInput"], " in order to accept as argument a string, whose contents will be split \ into a list (using the characters ", StyleBox["-", "MR"], ", ", StyleBox[":", "MR"], ", and ", StyleBox["T", "MR"], " as separators) and then converted into numeric values." }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Putting together those observations we obtain the ", StyleBox["xmlRpcDecode", "InlineInput"], " function, to be applied to the list obtained at the beggining of this \ section:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(xmlRpcDecode[{type_, value_}] := Block[{}, \[IndentingNewLine]Switch[ type, \[IndentingNewLine]"\" | "\" | "\", ToExpression[value], \[IndentingNewLine]"\", If[value == "\<0\>", False, True], \[IndentingNewLine]"\", ToDate[value], \[IndentingNewLine]"\", base64Decode[value], \[IndentingNewLine]"\", arrayDecode[value], \[IndentingNewLine]"\", ImportString["\<\>" ~~ \(value ~~ "\<\>"\), "\"], \[IndentingNewLine]_, value]]\)], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "This function handles arrays through the following ", StyleBox["arrayDecode", "InlineInput"], " function, removing the leading and trailing ", StyleBox["data", "MR"], " tags, associating to each ", StyleBox["value", "MR"], " tag the corresponding ", StyleBox["{type, value}", FontSlant->"Italic"], " couple, and building a list containing the so obtained couples. Finally, \ ", StyleBox["xmlRpcDecode", "InlineInput"], " is recursively mapped on this list:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(arrayDecode[value_] := StringCases[ StringReplace[ value, "\<\>" ~~ \(j___ ~~ "\<\>"\) \[Rule] j], ShortestMatch[ Whitespace ... ~~ \("\<\>" ~~ \(Whitespace ... ~~ \("\<<\ \>" ~~ \(v : \((Except["\<>\>"] .. )\) ~~ \("\<>\>" ~~ \(j___ ~~ \("\<" ~~ \ \(Except["\<>\>"] .. ~~ \("\<>\>" ~~ \(Whitespace ... ~~ "\<\>"\)\)\ \)\)\)\)\)\)\)\)] \[Rule] xmlRpcDecode[{v, j}]]\)], "Input", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Gluing the components" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic, CellTags->"Sec. Gluing"], Cell["\<\ Putting together the code shown so far, we obtain a set of \ functions enabling us to execute RPCs through one single function call:\ \>", \ "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["xmlRpcInit", "InlineInput"], ", to be called at the beginning of an XML-RPC session in order to fix \ address and port of the server;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["xmlRpcPayload", "InlineInput"], ", returning a string containing the payload for an XML-RPC request;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["xmlRpcHeader", "InlineInput"], ", returning the header corresponding to a given payload;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["xmlRpcDecode", "InlineInput"], ", translating the XML values returned from a remote call into valid ", StyleBox["Mathematica", FontSlant->"Italic"], " expressions;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["xmlRpcGetAnswer", "InlineInput"], ", extracting and converting into a ", StyleBox["Mathematica", FontSlant->"Italic"], " expression the meaninful information containted in the payload returned \ from an XML-RPC when no errors arise;" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ StyleBox["xmlRpc", "InlineInput"], ", built over the above functions and executing an XML-RPC whose return \ value is automatically converted into a ", StyleBox["Mathematica", FontSlant->"Italic"], " expression." }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[TextData[{ "Among all these functions, in order to access a given server only ", StyleBox["xmlRpcInit", "InlineInput"], " and ", StyleBox["xmlRpc", "InlineInput"], " will be directly called: the former once a new server needs to be \ addressed, and the latter for each call to this server." }], "Text", PageWidth->PaperWidth, CellDingbat->None, PageBreakBelow->Automatic], Cell["\<\ The above functions constitute the xmlRpc package [8], available \ for download at the web page \ http://homes.dsi.unimi.it/~malchiod/software/xmlRpc.\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ CounterBox["Section"], ". Examples" }], "Section", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell["The neosAPI package", "Subsection", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "The described XML-RPC implementation allows to access within ", StyleBox["Mathematica", FontSlant->"Italic"], " to the procedures available on a given server. For instance, the ", StyleBox["neosAPI", "Program"], " package [9] implements in this way a subset of procedures related to the \ above mentioned NEOS server for optimization. Consider for instance the \ constrained optimization problem:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \(TraditionalForm\`min\ \((x\^2 + y\^2)\)\ such\ that\ x + y = 3\)], "Program", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ The following cell builds a string containing the description of \ this problem in the AMPL modeling language [10]:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[{ \(<< neosAPI`\), "\[IndentingNewLine]", \(\(r = "\<<document>\n\>";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<<category>nco</category>\n\>";\)\), "\ \[IndentingNewLine]", \(\(r = r <> "\<<solver>SNOPT</solver>\n\>";\)\), "\ \[IndentingNewLine]", \(\(r = r <> "\<<inputMethod>AMPL</inputMethod>\n\>";\)\), "\ \[IndentingNewLine]", \(\(r = r <> "\<<model><![CDATA[\n\n\>";\)\), "\[IndentingNewLine]", \ \(\(r = r <> "\";\)\), "\[IndentingNewLine]", \(\(r = r <> "\";\)\), "\[IndentingNewLine]", \(\(r = r <> "\";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<]]></model>\n\n\>";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<<data><![CDATA[\n\>";\)\), "\[IndentingNewLine]", \(\(r = r <> "\";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<]]></data>\n\n\>";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<<commands><![CDATA[\n\>";\)\), \ "\[IndentingNewLine]", \(\(r = r <> "\";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<]]></commands>\n\n\>";\)\), "\[IndentingNewLine]", \(\(r = r <> "\<</document>\n\>";\)\)}], "Input", CellLabel->"In[164]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell["\<\ The use of HTML entities is a requirement of XML-RPC specifications \ [14], though a simple transformation can display the description in a more \ readable form:\ \>", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(StringReplace[ r, {"\<<\>" -> "\<<\>", "\<>\>" -> "\<>\>"}]\)], "Input", CellLabel->"In[189]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("\nnco\nSNOPT\n\ AMPL\n\n\n\n\n\n\n\n"\ \)], "Output", CellLabel->"Out[189]=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell["The problem is solved in three steps:", "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "the function ", StyleBox["neosSubmitJob", "InlineInput"], " sends the AMPL description to the NEOS server, which in turn places the \ corresponding job in a queue, returning the job's number and password:" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \({jobNum, jobPwd} = neosSubmitJob[r]\)], "Input", CellLabel->"In[190]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \({"730876", "HklLMQPD"}\)], "Output", CellLabel->"Out[190]=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "the function ", StyleBox["neosGetJobStatus", "InlineInput"], " allows for verifying whether or not the above job has been executed:" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(neosGetJobStatus[jobNum, jobPwd]\)], "Input", CellLabel->"In[191]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("Done"\)], "Output", CellLabel->"Out[191]=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "the function ", StyleBox["neosGetFinalResults", "InlineInput"], " retrieves the job output:" }], "Text", PageWidth->PaperWidth, CellDingbat->"\[FilledSmallCircle]", PageBreakBelow->Automatic], Cell[CellGroupData[{ Cell[BoxData[ \(neosGetFinalResults[jobNum, jobPwd]\)], "Input", CellLabel->"In[192]:=", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[ \("Job 730876 sent to schwinn.mcs.anl.gov\npassword: HklLMQPD\n---------- \ Begin Solver Output -----------\nExecuting \ /home/neosotc/neos-5-solvers/snopt-ampl/snopt-driver.py\nFile exists\nYou are \ using the solver snopt.\nExecuting AMPL.\nprocessing data.\nprocessing \ commands.\n\n2 variables, all nonlinear\n1 constraint, all linear; 2 nonzeros\ \n1 nonlinear objective; 2 nonzeros.\n\nSNOPT 6.2-2: Optimal solution found \ expressions.\n2 iterations, objective 4.5\n"\)], "Output", CellLabel->"Out[192]=", PageWidth->PaperWidth, PageBreakBelow->Automatic] }, Open ]], Cell[TextData[{ "The package also provides the function ", StyleBox["neosSolveJob", "InlineInput"], ", managing for submitting a job to the server, polling the queue until the \ job gets solved, and retrieving the result." }], "Text", PageBreakBelow->Automatic] }, Open ]], Cell[CellGroupData[{ Cell["Training a Support Vector Machine", "Subsection", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[TextData[{ "Support Vector Machines (SVM for short) [13] are models from the AI \ community used, besides other tasks, to assign patterns to two classes on the \ basis of a set of labeled examples ", Cell[BoxData[ \(TraditionalForm\`{\((x\_1, y\_1)\), ... , \((x\_m, y\_m)\)}\)]], ", where ", Cell[BoxData[ \(TraditionalForm\`x\_i\)]], " is a vector and ", Cell[BoxData[ \(TraditionalForm\`y\_i \[Element] {\(-1\), \(+1\)}\)]], " identifies the corrisponding class. In its simplest form, the output of a \ SVM is the equation ", Cell[BoxData[ \(TraditionalForm\`w\[CenterDot]x + b = 0\)]], " of a hyperplane gathering all patterns ", Cell[BoxData[ \(TraditionalForm\`x\_i\)]], " such that ", Cell[BoxData[ \(TraditionalForm\`y\_i = \(+1\)\)]], " in one half-space, and the remaining patterns in the other half-space. \ This is achieved setting ", Cell[BoxData[ \(TraditionalForm\`w = \[Sum]\+\(i = 1\)\%m\( \[Alpha]\_i\) \(y\_i\) x\_i\)]], " and ", Cell[BoxData[ \(TraditionalForm\`b = y\_i - w\[CenterDot]x\_i\)]], " for ", Cell[BoxData[ \(TraditionalForm\`i\)]], " such that ", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\_i > 0\)]], ", where ", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\_i\)]], "s are the solutions of the following quadratic constrained optimization \ problem:" }], "Text", PageWidth->PaperWidth, PageBreakBelow->Automatic], Cell[BoxData[{ \(max\ \(\[Sum]\+\(i = 1\)\%m \[Alpha]\_i\) - \(1\/2\) \(\[Sum]\+\(i, j = \ 1\)\%m\( \[Alpha]\_i\) \(\[Alpha]\_j\) \(y\_i\) \(y\_j\) x\_i\[CenterDot]x\_j\)\), "\[IndentingNewLine]", \(\[Sum]\+\(i = 1\)\%m\( \[Alpha]\_i\) y\_i = 0\), "\[IndentingNewLine]", \(\[Alpha]\_i \[GreaterEqual] 0\ \ \ \(\[ForAll] \ i\) = 1, \(\(...\) \(m\)\)\)}], "DisplayFormula", PageBreakBelow->Automatic], Cell[TextData[{ "The following function solves the above problem through the package \ described in the previous subsection, then scans the results in order to \ return a ", StyleBox["Mathematica", FontSlant->"Italic"], " expression gathering in a list the optimal values for ", Cell[BoxData[ \(TraditionalForm\`\[Alpha]\_i\)]], "s:" }], "Text", PageBreakBelow->Automatic], Cell[BoxData[ \(\(svm[x_, y_] := Block[{r, i, k, retValue, m, n, alpha}, \[IndentingNewLine]m = Length[x]; n = Length[ x[\([1]\)]]; \[IndentingNewLine]r = "\<<document>\n\>"; \ \[IndentingNewLine]r = r <> "\<<category>nco</category>\n\>"; \ \[IndentingNewLine]r = r <> "\<<solver>SNOPT</solver>\n\>"; \ \[IndentingNewLine]r = r <> "\<<inputMethod>AMPL</inputMethod>\n\>"; \ \[IndentingNewLine]r = r <> "\<<model><![CDATA[\n\n\>"; \[IndentingNewLine]r = r <> "\ 0 default \>"; \[IndentingNewLine]r = r <> ToString[m]; \[IndentingNewLine]r = r <> "\<; # number of sample points\n\>"; \[IndentingNewLine]r = r <> "\ 0 default \>"; \[IndentingNewLine]r = r <> ToString[n]; \[IndentingNewLine]r = r <> "\<; # sample space dimension\n\n\>"; \[IndentingNewLine]r = r <> "\"; \ \[IndentingNewLine]r = r <> "\"; \ \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r = r <> "\=0;\n\>"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r = r <> "\<-1/2*\n\>"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r \ = r <> "\"; \[IndentingNewLine]r = r <> "\<]]></model>\n\>"; \[IndentingNewLine]r = r <> "\<<data><![CDATA[\n\n\>"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]For[k = 1, k \[LessEqual] n, \(k++\), \(r = r <> ToString[k] <> "\<\t\>";\)]; \[IndentingNewLine]r = r <> "\<:=\n\>"; \[IndentingNewLine]For[i = 1, i \[LessEqual] m, \(i++\), r = r <> ToString[i] <> "\<\t\>"; \[IndentingNewLine]For[k = 1, k \[LessEqual] n, \(k++\), \(r = r <> ToString[\(x[\([i]\)]\)[\([k]\)]] <> "\<\t\>";\)]; \ \[IndentingNewLine]r = r <> If[i \[Equal] m, "\<;\n\n\>", "\<\n\>"];]; \[IndentingNewLine]r = r <> "\"; \[IndentingNewLine]For[i = 1, i \[LessEqual] m, \(i++\), r = r <> ToString[i] <> "\<\t\>" <> ToString[y[\([i]\)]]; \[IndentingNewLine]r = r <> If[i \[Equal] m, "\<;\n\n\>", "\<\n\>"];]; \[IndentingNewLine]r = r <> "\<]]></data>\n\n\>"; \[IndentingNewLine]r = r <> "\<<commands><![CDATA[\n\n\>"; \[IndentingNewLine]r \ = r <> "\