Skip to main content

Breeze and GRB data types link by chi sq distribution

Answered

Comments

5 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff
    This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?.
  • Jaromił Najman
    • Gurobi Staff

    Hi Alejandro,

    Could you elaborate more on what exactly you are trying to achieve? You say you have a \(\texttt{data}\) vector of double values and an array of GRBVar objects (you have written GRBVal, but I assume you actually meant GRBVar, right?)

    Are you trying to model something like

    \[ \sum_i (d_i - x_i)^2  \]

    or rather

    \[ \left ( \sum_i (d_i - x_i) \right )^2 \]

    or something else (\(d_i\) are the data entries)?

    Best regards,
    Jaromił

    0
  • Alejandro Mus Mejias
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Jaromil,

    Thank you very much for your answer.

    What I am trying to get is precissely

    \[ \sum_i (d_i - x_i)^2 \]

    where x_i are (indeed, sorry for the confusion) GRBVar objects, with coefficients in \mathbb{R}, and d_i are complex values. Thus, actually is not only (d_i - x_i)^2 but norm(d_i - x_i)^2.

    The python code --using numpy and not Gurobi objects-- of the function is:

    def chi_sq(x, mod):
    UVM = np.zeros(np.shape(mod),dtype=np.complex128)
    for m in range(len(mod)):
    UVM[m] = np.sum( x*np.exp(2.*np.pi*1.j )
    return np.sum(np.abs(UVM-mod)**2)

    (NOTE: mod variable is our d) and my optimization problem is

    min_x x*log(x) + log(\sum_i (d_i - x_i)^2 - constant).

     

    Since we need to rewrite the log in a form of GenConstraints, I am solving

    min y

    s.t. y(x) := x*log(x) + log(\sum_i (d_i - x_i)^2 - constant).

     

    So my problems are:

    • How would be written  \sum_i (d_i - x_i)^2 , in terms of GRBVar objects. Indeed, how would be the function chi_sq implemented if the inputs are x (list of GRBVar) and d (list of complex values).
    • How could be written x*log(x) + log(\sum_i (d_i - x_i)^2  - constant) in terms of GenConstraint.

    For the log I know, but since the chi_sq that I have done in Python has as input a vector, how would it fit? Or can chi_sq be included directly on the cost function and added the log in a GenConstraint form?

    Thank you,

    Best,

    Alejandro Mus

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi Alejandro,

    How would be written \sum_i (d_i - x_i)^2 , in terms of GRBVar objects. Indeed, how would be the function chi_sq implemented if the inputs are x (list of GRBVar) and d (list of complex values).

    Gurobi does not offer the functionality of complex numbers. So as long as your data values have an imaginary part, i.e., \(d_i= a+ i\cdot b\), there is currently no way to implement it with the \(\texttt{gurobipy}\) module. However, if you can find a suitable way to use real number values for your data, you can write \(\sum_i (d_i - x_i)^2\) as

    import gurobipy as gp
    from gurobipy import GRB

    m = gp.Model("test")

    d = [1,2,3]
    c = [4,5,6]
    cst = 42
    x = m.addVars(3,name="x")
    aux1 = m.addVar(lb=-GRB.INFINITY,vtype=GRB.CONTINUOUS,name="auxVar1")

    qexpr = gp.QuadExpr(0)
    for i in range(3):
    qexpr.add(d[i]*d[i] - 2*d[i]*c[i]*x[i] + c[i]*c[i]*x[i]*x[i])
    qexpr.add(-cst)

    m.addConstr(qexpr - aux1 ==0, name="qConstr")
    m.write("myLP.lp")

    The above code constructs the constraint

    \[\sum_i (d_i^2 - 2d_ic_ix_i + c_i^2x_i^2) - \text{cst} = \text{auxVar1}\]

    How could be written x*log(x) + log(\sum_i (d_i - x_i)^2 - constant) in terms of GenConstraint.

    You can then use addGenConstrLog to construct your objective

    y = m.addVar(name="y")
    log1 = m.addVar(lb=-GRB.INFINITY,vtype=GRB.CONTINUOUS,name="log1_var")
    log2 = m.addVar(lb=-GRB.INFINITY,vtype=GRB.CONTINUOUS,name="log2_var")

    m.addGenConstrLog(y,log1,name="log(y)")
    m.addGenConstrLog(aux1,log2,name="log(sum)")

    m.setObjective(y*log1 + log2, GRB.MINIMIZE)

    m.write("myLP.lp")

    Note that I used the write function to analyze the LP file and check whether the final problem looks what I expect it to be.

    Best regards,
    Jaromił

    0
  • Alejandro Mus Mejias
    • Gurobi-versary
    • First Comment
    • First Question

    Thanks a lot for your answer!!

    I leave the code with your toy example translated to Scala and working with DenseVectors, in case someone have the same problem in other language (because, for example y*log1 + log2 I was not able to write it directly in Java due to typation limitations) and can be inspired with it.

    What I've done to overcome y*log1 + log2 is to solve

    Minimize
    y + log1_var
    Subject To
    qConstr >= cst
    General Constraints
     log(chi_sq): log1_var = LOG ( auxiliaryVariable1 )
    y(x) := x*log(x) = PWL(x)

    In Scala code:

    val aux1: GRBVar = model.addVar(1.0, GRB.INFINITY, 1.0, GRB.CONTINUOUS, "auxiliaryVariable1")

    val quadExpr: GRBQuadExpr = new GRBQuadExpr()
    V.mapValues(Complex.complexNorm(_)).mapValues(el=>quadExpr.addConstant(el*el))
    //SAME: (V*:*V).mapValues(Complex.complexNorm(_)).mapValues(quadExpr.addConstant)
    quadExpr.addTerms(V.mapValues(_.real).toArray,x.toArray)
    quadExpr.addTerms(Array.fill(n)(1.0),x.toArray,x.toArray)
    quadExpr.addConstant(cst)

    model.addQConstr(quadExpr,GRB.GREATER_EQUAL,aux1,"qConstr")


    val log1: GRBVar = model.addVar(1e-3/n, GRB.INFINITY, 1.0, GRB.CONTINUOUS, "log1_var")

    model.addGenConstrLog(aux1,log1,"log(chi_sq)","")


    def createVar(stPoint: Double): LazyList[Double] = LazyList.cons(stPoint, createVar(stPoint + 0.01))
    val xs: LazyList[Double] = createVar(0.01).take(100)
    val ys: Array[Double] = xs.view.map(el => el*log(el)).toArray

    val y: GRBVar = model.addVar(-GRB.INFINITY, GRB.INFINITY, 0.0, GRB.CONTINUOUS, "y")
    x.map(el=>model.addGenConstrPWL(el,y,xs.toArray,ys,"pwl"))

    val obj: GRBLinExpr = new GRBLinExpr()
    obj.addTerm(1.0, y)
    obj.addTerm(1.0,log1)

    model.setObjective(obj, GRB.MINIMIZE)

    model.write("myLP.lp")
    model.optimize()

    Indeed, it is a pity that can't deal with complex values, but I will figure out on how to rewrite the problem.

     

    Thanks a lot again for your time and your help,

     

    Bests,

    Alejandro Mus

    0

Post is closed for comments.