Rotate the Roots

11

1

Given a nonzero polynomial with integer coefficients and roots that are on the imaginary and on the real line such that if a is a root then so is -a, return another polynomial with the roots rotated by 90 degrees.

Details

The polynomial can be given in any reasonable format, e.g. as a list of coefficients. The symmetry condition that a is a root if and only if -a is a root too enforces the rotated polynomial to have real integer coefficients as well.

Examples

In the following the polynomials are given as a list of coefficient of the monomials in descending degree. (i.e. the constant comes last) The polynomial x^2-1 has roots {1,-1}. Rotating them by 90° means multiplying by i (the imaginary unit), so the output polynomial should have the roots {i,-i}, which is x^2 + 1.

Input / Output
[1 0 10 0 -127 0 -460 0 576]  [1 0 -10 0 -127 0 460 0 576]
[1 0 -4 0] [1 0 4 0]
[1] [1]

flawr

Posted 2017-05-14T15:12:21.040

Reputation: 40 560

May I take in the degree of the polynomial as well as the polynomial – Rohan Jhunjhunwala – 2017-05-14T15:19:59.953

Yes I think that is acceptable. – flawr – 2017-05-14T16:01:47.993

All your examples use monic polynomials. Can we assume the input polynomial will be monic? Does the output polynomial have to be monic? – Dennis – 2017-05-14T16:05:20.040

No it can also have other leading coefficients than 1, and the output is also just defined up to a integral multiple. – flawr – 2017-05-14T16:07:53.850

It seems the format doesn't have to be a list of coefficients. How far do the reasonable formats go? Can my format be a string expression in the indeterminate x, so that my submission can string-replace x with (i*x)? Can my format a function that evaluates the polynomial, so that my submission is to compose it with the function x -> i*x? – xnor – 2017-05-14T19:48:52.720

In the coefficient list form, can our output polynomial have leading zeroes? Can the coefficient be floats like 4.0? Complex numbers like 4.0+0j? – xnor – 2017-05-14T19:57:50.193

Yes, any of them are acceptable. – flawr – 2017-05-14T21:11:40.250

@xnor String representations are valid too as long as they produce integer (i.e. real) coefficients. – flawr – 2017-05-15T09:39:20.030

Answers

12

Mathematica, 10 Bytes

Pure function which takes a function of x and substitutes in ix.

#/.x->I*x&

Alternative with only 7 bytes but not quite sure if it counts. Pure function which takes in a pure function and returns a function of x.

#[I*x]&

Ian Miller

Posted 2017-05-14T15:12:21.040

Reputation: 727

5And you didn't even need any builtins! – Neil – 2017-05-14T16:34:17.540

I'm pretty sure a pure function polynomial is a "reasonable format" (like it was here) It uses # as the variable and has a & at the end.

– JungHwan Min – 2017-05-14T17:14:25.027

I would upvote this twice if I could – Greg Martin – 2017-05-14T17:23:24.917

My only concern about the second answer was the mismatch between input (a pure function) and output (a function of x). – Ian Miller – 2017-05-15T00:16:57.097

6

Jelly, 5 bytes

Jı*Ċ×

Try it online!

How it works

Multiplies the first element by 1, the third element by -1, etc.

Jı*Ċ×  argument: z
J      [1,2,...,len(z)]
 ı     i (the imaginary unit)
  *    to the power of (each element)
   Ċ   imaginary part
    ×  multiply by input (vectorize)

Proof of algorithm

Let the polynomial be f(x).

Since we are guaranteed that if x is a root then so is -x, so f must be even, meaning that its coefficient for the odd powers must be 0.

Now, rotating the roots by 90° is essentially f(ix).

Expanding then comparing coefficients proves the algorithm.

Leaky Nun

Posted 2017-05-14T15:12:21.040

Reputation: 45 011

So, we need not touch the 2,4th,6th, 8th etc? – Rohan Jhunjhunwala – 2017-05-14T15:19:24.363

2Those are zero anyway. – flawr – 2017-05-14T15:21:17.197

Your trick with ı*Ċ is very nice, you should explain it :) – Leo – 2017-05-14T19:01:45.050

@Leo It's essentially a straightforward implementation though... – Leaky Nun – 2017-05-15T01:06:05.687

The logic here is not quite right, because you can instead have all coefficients for even powers be 0. – Ørjan Johansen – 2017-05-15T01:52:07.887

@ØrjanJohansen Are you saying that the coefficients for odd powers can be non-zero? – Leaky Nun – 2017-05-15T01:52:56.280

@ØrjanJohansen Could you give me an example? – Leaky Nun – 2017-05-15T01:55:51.600

x^5 - x^3 + x. – Ørjan Johansen – 2017-05-15T01:56:34.763

@ØrjanJohansen You're right. You should talk to flawr about that. – Leaky Nun – 2017-05-15T01:57:46.107

I already did, we cleared it up in the comments and then deleted them again. Note that the test cases are in descending order. – Ørjan Johansen – 2017-05-15T01:58:23.963

5

JavaScript (ES6), 25 bytes

a=>a.map((e,i)=>i%4?-e:e)

The original polynomial has solutions of the form x = ±a where a lies on the real or imaginary line. Except when a = 0 (in which case x is a factor of the polynomial), this means that x² - a² is a factor of the polynomial (which means alternate terms are always zero). Now when we rotate the roots, the factor changes to x² + a². Since all the factors change at the same time, the third term of the polynomial, which is the sum of all the -a² terms, changes sign, the fifth term, which is the sum of products of pairs of -a² terms, keeps the same sign, etc. alternating every other term.

Neil

Posted 2017-05-14T15:12:21.040

Reputation: 95 035

4

Octave, 27 bytes

@(x)round(poly(roots(x)*j))

Try it online!

This directly applies the definition: compute roots, multiply by j, convert back from roots to polynomial. A final rounding is necessary because of floating-point numerical errors.

Luis Mendo

Posted 2017-05-14T15:12:21.040

Reputation: 87 464

2

Python 3, 42 bytes

f=lambda x,s=1:x and[0,x[0]*s]+f(x[2:],-s)

Try it online!

Dennis

Posted 2017-05-14T15:12:21.040

Reputation: 196 637

1

S.I.L.O.S, 71 66 bytes

readIO
b=i
lbla
readIO
d=c
d&2
i=i*(1-d)
printInt i
b-1
c+1
if b a

Try it online!

I have no clue what wizardry @Leaky Nun did here to save 5 bytes.

Took me a second to figure out, but The second bit of C will alternate like we want. Therefore @Leaky Nun exploited this to save the bits we need.

Rohan Jhunjhunwala

Posted 2017-05-14T15:12:21.040

Reputation: 2 569

66 bytes – Leaky Nun – 2017-06-03T12:53:21.360

0

Casio-Basic, 8 bytes

n|x=x

Unnamed function, using Ian Miller's Mathematica approach. The imaginary from the Math2 keyboard needs to be used (counts as 2 bytes, char code 769), and the polynomial should be entered as an equation of x.

7 bytes for the code, 1 byte to specify n as a parameter.

Explanation: Takes the equation n, then simply replaces all instances of x with x.

numbermaniac

Posted 2017-05-14T15:12:21.040

Reputation: 639

0

Pari/GP, 16 bytes

p->x=I*x;eval(p)

Try it online!

alephalpha

Posted 2017-05-14T15:12:21.040

Reputation: 23 988

0

TI-Basic, 20 bytes

seq(real(i^X/i)Ans(X),X,1,dim(Ans

If stored in prgmA, run with:

{1, 0, 3, 0, 1}:prgmA

seq( just had to be the one* command that doesn't support complex numbers. :)

*: Exaggeration

pizzapants184

Posted 2017-05-14T15:12:21.040

Reputation: 3 174

0

Stax, 5 bytes

Æ[]▐↨

Run and debug online!

Port of the Jelly answer.

Uses ASCII representation to explain:

mih|1*
m         Map each element with rest of program, print mapped results on individual lines
 i        Current 0-based loop index
  h       Floor(i/2)
   |1     (-1)^(i/2)
     *    Multiply with current element

If there can be leading zeros, they need to be trimmed first and it can be done at the cost of another byte.

Weijun Zhou

Posted 2017-05-14T15:12:21.040

Reputation: 3 396