| Bytes | Lang | Time | Link |
|---|---|---|---|
| 095 | Python | 250905T093437Z | ojdo |
| 035 | APLNARS | 250213T184220Z | Rosario |
| 049 | Mathematica | 170809T133132Z | miles |
| 042 | Octave | 170809T111601Z | flawr |
| 077 | C gcc | 170809T050337Z | ceilingc |
| 100 | Clojure | 170809T101214Z | NikoNyrh |
| 015 | Jelly | 170809T113713Z | miles |
| 079 | Mathematica | 170719T071821Z | numberma |
Python, 95 bytes
def f(x):N=len(x);R=range(N);return[sum((1j**2)**((n+.5)*k/N)*x[n] for n in R).real for k in R]
Straight implementation of the formula, with the trick that cos(pi * ...) == (-1+0j)**(...) and that (1j**2) == (-1+0j) (not saving characters, I just like the look of the chained exponentiation).
I tried to lambda it, but the saved return comes back with interest for saving N and R as assignment expressions (97 bytes):
lambda x:(N:=len(x),R:=range(N),[sum((1j**2)**((n+.5)*k/N)*x[n] for n in R).real for k in R])[-1]
APL(NARS), 35 chars
{↑+/⍵×2○N÷⍨1p1×,/↑∘.×/1r2 1-⊂⍳N←≢⍵}
It would use the DCT-II definition from Wikipedia showed in the question too. It appears strange numbers in the function because APL start to count from 1 in arrays. One more readable one is this below even if a little more long:
{{+/⍵{X[⍵]×2○N÷⍨1p1×(⍺-1)×⍵-1r2}¨⍳N}¨⍳N←≢X←⍵}
test:
f←{↑+/⍵×2○N÷⍨1p1×,/↑∘.×/1r2 1-⊂⍳N←≢⍵}
f 1 3 2 4
10 ¯2.388955165 ¯6.061692394E¯16 ¯2.07192983
f 1 ¯1 ¯1 1
0 ¯6.627740718E¯17 2.828427125 4.800234458E¯16
f 1 0 0 0 0 0 0 0 0 0
1 0.9876883406 0.9510565163 0.8910065242 0.8090169944 0.7071067812 0.5877852523 0.4539904997 0.3090169944 0.156434465
Mathematica, 51 49 bytes
Re@Total[I^Array[(2##+#2)/n&,{n=Length@#,n},0]#]&
Try it online! (Using Mathics)
Based on my solution to DFT.
Octave, 49 46 45 42 bytes
Here we consider the DCT as a matrix multiplication. The matrix is basically the entry-wise cosine of a rank 1 matrix which is very simple to construct.
Thanks @Cowsquack for -1 byte, thanks @ceilingcat for another -3 bytes!
@(x)cos(pi/(n=numel(x))*(0:n-1)'*(.5:n))*x
C (gcc), 88 83 78 77 bytes
k;d(a,b,c)float*a,*b;{for(k=c*c;k--;)b[k/c]+=a[k%c]*cpow(-1,k/c*(.5+k%c)/c);}
This assumes the output vector is cleared before use.
Thanks to @Peter Taylor for -5
Clojure, 100 bytes
#(for[c[(count %)]k(range c)](apply +(map(fn[n x](*(Math/cos(*(/ c)Math/PI(+ n 0.5)k))x))(range)%)))
Sometimes it is difficult to be creative.
Jelly, 15 bytes
LḶµ+.×þ÷L-*Ḟ³æ.
This uses the identity that cos(pi * x) = real(e^(i * pi * x)) = real((-1)^x)
Explanation
LḶµ+.×þ÷L-*Ḟ³æ. Input: array A
L Length
Ḷ Lowered range - [0, 1, ..., len(A)-1]
µ Begin a new monadic chain
+. Add 0.5
×þ Outer product using multiplication
÷ Divide by
L Length
-* Compute (-1)^x
Ḟ Real part
æ. Dot product with
³ The first argument (A)
Mathematica, 79 bytes
Tr/@(s=#;x=Length@s;Table[s[[n+1]]Cos[Pi/x(n+1/2)#],{n,0,x-1}]&/@Range[0,x-1])&
Since there are (currently) no test cases, as it turns out, there is a built-in for this: FourierDCT. However, the function "normalizes" the result by dividing it by a value before returning it. Thankfully, the documentation specifies that this division factor is just the square root of the input list's length (for DCT-II).
So, we can verify our results by multiplying the output of FourierDCT by the square root of the length of our input list. For anyone else who tries this problem, here are some test cases:
FourierDCT@{1,3,2,4}*Sqrt@4
{10, -2.38896, 0, -2.07193}
FourierDCT@{1,1,1,1,1}*Sqrt@5
{5, 0, 0, 0, 0}
Note that I've slightly edited the output of the last one; the last four values output as very small decimals, around 10-16, due to floating point precision errors around 0. My answer does give 0 for them, if you convert it to a decimal.
This solution gives exact answers when Mathematica can do so. If that's not okay and you want decimals, let me know.