jump-dev / Convex.jl

A Julia package for disciplined convex programming
https://jump.dev/Convex.jl/stable/
Other
555 stars 119 forks source link

[Feature Request] power related convex functions #297

Open utotch opened 5 years ago

utotch commented 5 years ago

Hi.

CVX supports power-related functions:

These functions are often used for financial problems, like portfolio optimization.

I think these functions are important and useful, but current Convex.jl haven't supported them yet. https://convexjl.readthedocs.io/en/latest/operations.html

I request to support the functions.

ericphanson commented 5 years ago

Do you happen to know how they are implemented?

I ask for two reasons: (1) it would help anyone who would be up for implementing them in Convex, and (2) to know if there's any big obstacles to implementing them in Convex.

I was looking at matrix logarithm based functions implemented in https://github.com/hfawzi/cvxquad, and noticed arrays with > 2 dimensions are used frequently in the implementation (although the functions are just for matrices). Convex.jl only supports scalars, vectors, and matrices in its current form, which might make it hard to port CVXQUAD (which, since it doesn't have a license, would also likely require permission of the authors). So if these power-related functions also need arrays with 3+ dimensions, it might be harder to implement them in Convex. I've been toying with ideas for how to rewrite some of Convex to allow general arrays but I'm not sure when I would have time to do so. It would be interesting to see if there is the same or another obstacle to implementing these in the current form of Convex.jl, or if it's just a matter of doing it. If there is another obstacle, maybe it could be tackled at the same time as general arrays.

utotch commented 5 years ago

Thanks for the comment.

I don't have implementation-level knowledge in this time, but I asked how it is implemented in cvxpy to the author.

Simply speaking, the implementation in cvxpy is a little complicated and NOT using power cone BUT using second-order cone. (And many solvers don't accept power cone.)

I guess cvxpy canonicalize or factorize positive power to a combination of quadratic forms, but I don't have deep knowledge about it. I'm collecting related paper info now.

utotch commented 5 years ago

I guess these part of the implementation of cvxpy could be the clue.

https://github.com/cvxgrp/cvxpy/blob/master/cvxpy/atoms/elementwise/power.py Line 119-128

def __init__(self, x, p, max_denom=1024):
        p_old = p

        # how we convert p to a rational depends on the branch of the function
        if p > 1:
            p, w = pow_high(p, max_denom)
        elif 0 < p < 1:
            p, w = pow_mid(p, max_denom)
        elif p < 0:
            p, w = pow_neg(p, max_denom)

and https://github.com/cvxgrp/cvxpy/blob/master/cvxpy/utilities/power_tools.py Line 86-122

def pow_high(p, max_denom=1024):
    """ Return (t,1,x) power tuple
        x <= t^(1/p) 1^(1-1/p)
        user wants the epigraph variable t
    """
    assert p > 1
    p = Fraction(1/Fraction(p)).limit_denominator(max_denom)
    if 1/p == int(1/p):
        return int(1/p), (p, 1-p)
    return 1/p, (p, 1-p)

def pow_mid(p, max_denom=1024):
    """ Return (x,1,t) power tuple
        t <= x^p 1^(1-p)
        user wants the epigraph variable t
    """
    assert 0 < p < 1
    p = Fraction(p).limit_denominator(max_denom)
    return p, (p, 1-p)

def pow_neg(p, max_denom=1024):
    """ Return (x,t,1) power tuple
        1 <= x^(p/(p-1)) t^(-1/(p-1))
        user wants the epigraph variable t
    """
    assert p < 0
    p = Fraction(p)
    p = Fraction(p/(p-1)).limit_denominator(max_denom)
    return p/(p-1), (p, 1-p)

and also is_pow2(num) func can identry 2^4 as (2^2)^2, etc.

I'll show more info if I understand it deeper.

odow commented 2 months ago

Now that https://github.com/jump-dev/Convex.jl/pull/590 is merged, this issue can be resolved by adding support for atoms that create the various GenericConstraint{MOI.PowerCone} constraints.

See also https://github.com/jump-dev/Convex.jl/issues/90