Processing math: 100%
Ask Your Question
2

Checking whether a polynomial in unimodal

asked 3 years ago

mathstudent gravatar image

updated 3 years ago

Let p(t)Z0[t]. Write p(t)=iaiti. Then we say p(t) is unimodal if a0a1...akak+1...an i.e, the sequence of coefficients increase at first and then decrease, they don't 'jump around' ; there is no phenomenon like increase then decrease then increase again. Given such a polynomial, how can we check unimodality in sage?

Preview: (hide)

3 Answers

Sort by » oldest newest most voted
1

answered 3 years ago

rburing gravatar image

updated 3 years ago

Here is a way:

def is_unimodal(p):
    coeffs = p.coefficients(sparse=False)
    max_coeff_idx = max(range(len(coeffs)), key=lambda i: coeffs[i])
    return all(coeffs[i] <= coeffs[i+1] for i in range(max_coeff_idx)) and \
           all(coeffs[i] >= coeffs[i+1] for i in range(max_coeff_idx, len(coeffs) - 1))

Example usage:

sage: R.<t> = ZZ[]
sage: p = R.random_element(degree=4).map_coefficients(abs); p
t^4 + 4*t^3 + t^2 + t + 1
sage: p.coefficients(sparse=False)
[1, 1, 1, 4, 1]
sage: is_unimodal(p)
True
Preview: (hide)
link

Comments

Actually coeffs don't take into account if some coefficient ak=0 in the middle. So this works fine if there is no internal zeros, but if there is some then it gives wrong answer.

mathstudent gravatar imagemathstudent ( 3 years ago )

@mathstudent That wasn't written in your definition. I've updated the answer. Probably there is a faster way, but I guess speed doesn't matter much here.

rburing gravatar imagerburing ( 3 years ago )

No... I meant your earlier program didn't work if there was some internal zeroes

mathstudent gravatar imagemathstudent ( 3 years ago )

Ah sorry, I misunderstood you. Fixed now.

rburing gravatar imagerburing ( 3 years ago )

Thank you very much!

mathstudent gravatar imagemathstudent ( 3 years ago )
1

answered 3 years ago

slelievre gravatar image

updated 2 years ago

Call C the list of coefficients, removing immediate repeats.

Unimodality means there is no decrease-then-increase in C.

The package more-itertools (which can be installed with pip) enables an elegant solution:

def is_unimodal(p):
    """
    Return whether this polynomial is unimodal.

    EXAMPLES::

        sage: R.<t> = ZZ[]
        sage: is_unimodal(1 + t + t^2 + 4*t^3 + t^4)  # coeffs: 1, 1, 1, 4, 1
        True
        sage: is_unimodal(1 + t^2 + 4*t^3 + t^4)  # coeffs: 1, 0, 1, 4, 1
        False
    """
    from more_itertools import triplewise, unique_justseen
    return all((a < b) or (b > c)
               for a, b, c in triplewise(unique_justseen(p)))
Preview: (hide)
link
0

answered 3 years ago

mathstudent gravatar image

updated 3 years ago

From @rburing's answer... slightly modified since taking coefficients in the polynomial ring somehow only gives the non-zero coefficients:

t = var('t')
R = ZZ[t]
def is_unimodal(p):
  coeffs = [R(p).constant_coefficient()]
  for i in range(1,p.degree(t)+1):
    coeffs = coeffs + [SR(p).coefficient(t^i)]
  max_coeff_idx = max(range(len(coeffs)), key=lambda i: coeffs[i])
  return all(coeffs[i] <= coeffs[i+1] for i in range(max_coeff_idx)) and \
       all(coeffs[i] >= coeffs[i+1] for i in range(max_coeff_idx, len(coeffs) - 1))
Preview: (hide)
link

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 3 years ago

Seen: 499 times

Last updated: Aug 10 '22