Ask Your Question

millermj's profile - activity

2023-05-19 22:10:55 +0100 received badge  Popular Question (source)
2022-03-07 14:22:51 +0100 received badge  Popular Question (source)
2021-12-06 15:32:57 +0100 received badge  Notable Question (source)
2021-05-16 08:50:43 +0100 received badge  Famous Question (source)
2021-03-24 19:31:18 +0100 asked a question linking sage cells with different templates (to "hide" code)

linking sage cells with different templates (to "hide" code) I'm setting up a sage cell that requires some front-end cod

2020-10-28 08:01:18 +0100 received badge  Popular Question (source)
2020-05-06 23:06:47 +0100 received badge  Popular Question (source)
2019-08-11 21:21:28 +0100 asked a question Submitting code to Sage

I have written a user-friendly front-end to MixedIntegerLinearProgram (aided by a suggestion of rburing). The code is listed below. I'd be happy to contribute this to the sage code base, but (not being a developer) I'm not sure how.

I have tried to follow the conventions that I've found, but I'd welcome corrections and suggestions of where to go from here.



Print the solution to a mixed integer linear program.

Variables are assumed real unless specified as integer,
and all variables are assumed to be nonnegative.


var('x1 x2')
maximize(20*x1 + 10*x2, {3*x1 + x2 <= 1300, x1 + 2*x2 <= 600, x2 <= 250})
# Z = 9000.0, x1 = 400.0, x2 = 100.0

var('s h a u')
maximize(0.05*s + 0.08*h + 0.10*a + 0.13*u, {a <= 0.30*(h+a), 
      s <= 300, u <= s, u <= 0.20*(h+a+u), s+h+a+u <= 2000})
# Z = 174.4, s = 300.0, u = 300.0, h = 980.0, a = 420.0

var('a b c d', domain='integer')
maximize(5*a + 7*b + 2*c + 10*d, 
      {2*a + 4*b + 7*c + 10*d <= 15, a <= 1, b <= 1, c <= 1, d <=1 })
# Z = 17.0, a = 0, b = 1, c = 0, d = 1   (Note that integer variables <=1 are binary.)

var('x y')
minimize(x + y, {x + 2*y >= 7, 2*x + y >= 6})
# Z = 4.33333333333, x = 1.66666666667, y = 2.66666666667

var('y', domain='integer')
minimize(x + y, {x + 2*y >= 7, 2*x + y >= 6})
# Z = 4.5, x = 1.5, y = 3

var('x y', domain='integer')
minimize(x + y, {x + 2*y >= 7, 2*x + y >= 6})
# Z = 5.0, x = 2, y = 3

var('x y', domain='integer')
maximize(x + y, {x + 2*y >= 7, 2*x + y >= 6})
# GLPK: Objective is unbounded

var('x y', domain='integer')
maximize(x + y, {x + 2*y >= 7, 2*x + y <= 3})
# GLPK: Problem has no feasible solution


- Michael Miller (2019-Aug-11): initial version


# ****************************************************************************
#       Copyright (C) 2019 Michael Miller
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# ****************************************************************************

from sage.numerical.mip import MIPSolverException

def maximize(objective, constraints):
    maxmin(objective, constraints, true)

def minimize(objective, constraints):
    maxmin(objective, constraints, false)

def maxmin(objective, constraints, flag):

    # Create a set of the original variables
    variables = set(objective.variables())
    for c in constraints:
    integer_variables = [v for v in variables if v.is_integer()]
    real_variables    = [v for v in variables if not v.is_integer()]

    # Create the MILP variables
    p = MixedIntegerLinearProgram(maximization=flag)
    MILP_integer_variables = p.new_variable(integer=True, nonnegative=True)
    MILP_real_variables = p.new_variable(real=True, nonnegative=True)

    # Substitute the MILP variables for the original variables
    # (Inconveniently, the built-in subs fails with a TypeError)
    def Subs(expr):
        const = RDF(expr.subs({v:0 for v in variables})) # the constant term
        sum_integer = sum(expr.coefficient(v) * MILP_integer_variables[v] for v in integer_variables)
        sum_real = sum(expr.coefficient(v) * MILP_real_variables[v] for v in real_variables)
        return sum_real + sum_integer + const

    objective = Subs(objective)
    constraints = [c.operator()(Subs(c.lhs()), Subs(c.rhs())) for c in constraints]

    # Set up the MILP problem
    for c in constraints:

    # Solve the MILP problem and print the results
        Z = p.solve()
        print "Z =", Z
        for v in integer_variables:
            print v, "=", int(p.get_values(MILP_integer_variables[v]))
        for v in real_variables:
            print v, "=", p.get_values(MILP_real_variables[v])
    except MIPSolverException as msg:
        if str(msg)=="GLPK: The LP (relaxation) problem has no dual feasible solution":
            print "GLPK: Objective is unbounded"
            print str(msg)
2019-08-11 21:12:28 +0100 commented answer Is there a way to temporarily turn off sage's type checking?

Thanks! This does what I need.

2019-07-21 15:00:19 +0100 received badge  Nice Question (source)
2019-07-21 02:24:18 +0100 asked a question Is there a way to temporarily turn off sage's type checking?

I'm having some difficulties writing sage code to solve linear programming problems using "natural variables", by substituting for them the variables required for MixedIntegerLinearProgram.

The code for "minimize_desired" is what I'd like to do, but it fails during the substitution with the error message "TypeError: no canonical coercion from Linear functions over Real Double Field to Symbolic Ring". What I'd like is for sage to just do the substitution and ignore the lack of coercion.

The code for "minimize_works" works, but I got past the type checking by changing everything to strings and then back into a sage object, which feels like a terrible kludge. However this does illustrate that, despite sage's worries about coercion, everything ends up fine for MixedIntegerLinearProgram.

Is there a way to turn off sage's type checking and just do the substitution?



Note: I simplified the examples below by eliminating all the code that dealt with constraints.

def minimize_desired(objective):
   p = MixedIntegerLinearProgram(maximization=false)
   pvar = p.new_variable(real=True, nonnegative=True)

   translation={v:pvar[v] for v in variables}
   objective=objective.subs(translation)      # FAILS HERE

   print p.solve()

def minimize_works(objective):
   p = MixedIntegerLinearProgram(maximization=false)
   pvar = p.new_variable(real=True, nonnegative=True)

   variables=set(str(v) for v in objective.arguments())
   translation={v:pvar[v] for v in variables}
   objective=sageobj(str(objective), translation)

   print p.solve()

var('x y')
2019-01-08 12:17:34 +0100 received badge  Notable Question (source)
2018-09-11 01:20:38 +0100 received badge  Popular Question (source)
2017-12-04 05:12:16 +0100 commented answer How can I get mpmath to work with sage variables?

I'm attempting to do a mix of symbolic and high-precision-numeric computations in a loop. It appears (from my example above) that merely importing mpmath precludes doing any symbolic computations involving sqrt anywhere in that session.

Specifically, it appears that the "ordinary" sqrt works with symbolic variables, but that the mpmath sqrt does not. Is there a workaround?

2017-12-03 00:10:43 +0100 asked a question How can I get mpmath to work with sage variables?

In Sage, the following code produces error messages ending with "TypeError: cannot evaluate symbolic expression numerically":

from mpmath import *
print sqrt(a)

If I remove the line "from mpmath import *", it prints "sqrt(a)" as expected.

How can I get mpmath to work with sage variables?

2017-06-17 21:52:53 +0100 answered a question error in creating relocatable "runtime binaries only"

While I don't know how to fix the compilation error that I asked about, I have discovered a workaround.

My goal is to get a small working relocatable copy of Sage. As compiled without the "Runtime binaries only", the SageMath folder is 5.3 GB, which is bigger than I'd like.

After relocating and the initial run of Sage (when the paths are patched), I ran the following commands from the SageMath directory.

$ LC_ALL=C find local/lib local/bin -type f -print0 | xargs -0 strip 2>&1 | grep -v "File format not recognized\|File truncated"
$ rm -rdf src
$ rm -rdf local/share/doc

The result was a working (as far as I can tell) copy of Sage, but SageMath is now only 1.5GB, which is much smaller. This will suffice for my needs, although I would much prefer doing this by fixing the compilation error.

2017-06-15 22:24:49 +0100 commented answer How can I display a plot from a script?

Thanks! I would also add an & to the end of the display command, so that the script would continue to run, so:

   os.system('display /tmp/dom.png &')
2017-05-27 20:40:16 +0100 received badge  Editor (source)
2017-05-27 20:37:44 +0100 asked a question How can I display a plot from a script?

If I type

plot(x^2, (x,-2,2))

in sage, I get the expected plot, displayed as a png file by my default image viewer. If instead I put the line

plot(x^2, (x,-2,2)).show()

in a file test.sage and run

sage test.sage

from the command line, I get

Graphics object consisting of 1 graphics primitive

typed on the command line, but no displayed plot.

How do I display a plot from a script?

2017-05-25 04:01:57 +0100 received badge  Scholar (source)
2017-05-25 03:55:23 +0100 received badge  Supporter (source)
2017-05-25 03:51:55 +0100 asked a question error in creating relocatable "runtime binaries only"

If I clone, change branch from develop to master in sage.yaml, and run

$ export PACKAGE="Runtime binaries only"
$ make bdist-sage-linux

I get error messages in stage-sage saying

ERROR:root:At b'.../local/share/doc/sage/html/en/reference/calculus/sage/calculus/ode.htmlX\x1e'
ERROR:root:path terminator b'\x1e' not allowed in .../local/share/doc/sage/doctrees/ca/intro/environment.pickle

What am I doing wrong? Or should I file a bug report?

Or where can I find documentation on what commands I can run to remove unnecessary files? (E.g. I'd expect that some directories could be deleted, and that some binaries could be stripped.)


2017-05-25 03:37:55 +0100 commented answer How can I purge unneeded files after compilation?

That works - thanks!

2017-05-19 07:41:53 +0100 received badge  Student (source)
2017-05-19 02:43:42 +0100 asked a question How can I purge unneeded files after compilation?

After compiling sage-7.6 from source, I get a folder of size 8.6 GB. I'd like to keep just the files necessary to run sage, but there is no "make clean". How can I purge unneeded files?

On a related note, the file contains instructions for sage --bdist, which appears to have been removed for quite some time. Who might I ask to have that text removed?