Source code for sdpt3glue.solve_locally

'''
Methods that run code on a copy of Matlab or Octave installed on the user's
machine.
'''

import os
import os.path

import shutil
import subprocess
import tempfile


[docs]class MatlabCallError(Exception): ''' This error is raised when an error occurs during a subprocess call to Matlab. ''' pass
[docs]class OctaveCallError(Exception): ''' This error is raised when an error occurs during a subprocess call to Octave. ''' pass
[docs]class SubprocessCallError(Exception): ''' This error is raised when an error occurs during a subprocess call. ''' pass
[docs]def matlab_solve(matfile_target, discard_matfile=True): ''' The .mat is loaded into matlab and the problem is solved with SDPT3. Args: matfile_target: the path to the .mat file containing the Sedumi format problem data. discard_matfile: if True, deletes the .mat file after the solve finishes. Returns: A dictionary with solve result information. ''' # Generating the .mat file run_command = "matlab -r \"SDPT3solve('{0}')\" -nodisplay -nojvm".format( matfile_target) try: msg = run_command_get_output(run_command) except SubprocessCallError, e: raise MatlabCallError(e) # Cleanup if discard_matfile: print "now deleting {0}".format(matfile_target) os.remove(matfile_target) return msg
[docs]def octave_solve(matfile_target, discard_matfile=True, cmd="octave"): ''' The .mat is loaded into octave and the problem is solved with SDPT3. Args: matfile_target: the path to the .mat file containing the Sedumi format problem data. discard_matfile: if True, deletes the .mat file after the solve finishes. cmd: command name for octave, which will be used for alternative command. Returns: A dictionary with solve result information. ''' # Generating the .mat file with tempfile.NamedTemporaryFile( suffix=".m", dir=os.path.dirname(matfile_target)) as runner: with open(os.path.join(os.path.dirname(__file__), "SDPT3solve.m")) as lib: shutil.copyfileobj(lib, runner) runner.write("SDPT3solve('{0}');\n".format( os.path.relpath(matfile_target))) runner.flush() run_command = "{cmd} {script}".format( cmd=cmd, script=os.path.relpath(runner.name)) try: msg = run_command_get_output(run_command) except SubprocessCallError, e: raise OctaveCallError(e) # Cleanup if discard_matfile: print "now deleting {0}".format(matfile_target) os.remove(matfile_target) return msg
[docs]def run_command_get_output(run_command): ''' Runs the command run_command, saves the output to output_target, and returns the output log. ''' # Performing the Matlab solve try: proc = subprocess.Popen( run_command, shell=True, stdout=subprocess.PIPE, cwd=os.path.join(os.path.dirname(__file__))) return proc.communicate()[0] except: err_msg = ("Something went wrong with the command. The command " "run was:\n{0}\nPlease check that the command looks good " "and that the the folder containing SDPT3solve.m is in the " "Matlab or Octave path variable.").format(run_command) raise SubprocessCallError(err_msg)