реализация dct в c

Итак, я пытаюсь реализовать функцию DCT-ll в моем коде c, но я не совсем уверен, как это сделать? Я использую эту формулу: https://i.stack.imgur.com/UeUBd.png

и массив с этими значениями:

static float array[] = {0.35,
 0.35,
-0.37,
-0.335,
-0.285,
-0.23,
-0.215}

Кажется, я не могу найти никакой помощи в том, как это можно сделать, я сделал это только в MatLab, и это довольно легко

close all; clear all; clc ;
N=512; % signal length

M=120; %select the number of DCT coefficients

load mit200
%%
x=ecgsig(1:N,1);

%% DCT transform of signal
y=dct(x);

%% Select first M coefficients
y(M+1:end)=0;

%% reconstructed signal
xrec = idct(y);
plot(x);
hold on;
plot((xrec),'r.');
legend ( 'Original','Recovered');

Большая часть помощи, которую я могу найти, делает что-то вроде: Реализация DCT с дискретным косинусным преобразованием C, но это всегда с матрицей 8x8 - ›inMatrix[8][8]?

Вот мой код

#include "contiki.h"

#include "math.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

//Define sizeof - macros
#define SHIFT_AMOUNT 2 // 2^16 = 65536
#define SHIFT_MASK ((1 << SHIFT_AMOUNT) - 1) // 65535 (all LSB set, all MSB clear)
#define pi 3.14
//double static signal[3] = {0.35,0.35,0.35};
//static int price = 500 << SHIFT_AMOUNT;
static int dec;
static int frac;
static float s = 0;
static float array[] = {0.35,0.35,0.35,0.35,0.35,0.35,0.35,0.35,0.35,0.02,-0.21,-0.33,-0.37,-0.335,-0.285,-0.23,-0.215,-0.2,-0.19,-0.2,-0.2,-0.21,-0.23,-0.25,-0.255,-0.245,-0.24,-0.215,-0.235,-0.23,-0.23,-0.205,
-0.18,-0.165,-0.195,-0.21,-0.215,-0.195,-0.17,-0.155,-0.175,-0.195,-0.21,-0.2,-0.195,-0.185,-0.185,-0.18,-0.175,-0.175,-0.165,
-0.14,-0.12,-0.115,-0.13,-0.155,-0.19,-0.19,-0.185,-0.18,-0.16,-0.14,-0.13,-0.11,-0.12,-0.13,-0.13,-0.125,-0.095,-0.095,-0.09,-0.08,-0.075,-0.07,-0.075,-0.065,-0.055,-0.06,-0.055,-0.04,-0.03,-0.02,-0.015,-0.015,-0.01,0.015,0.035,0.025,0.015,0.015,0.025,0.025,0.04,0.04,0.03,
0.015,0.02,0.035,0.045,0.05,0.025,0.02,0.02,0.01,0.01,0,-0.005,-0.025,-0.02,-0.03,-0.03,-0.035,-0.045,-0.055,-0.06,-0.065,-0.075,-0.08,-0.075,-0.075,-0.075,-0.07,
-0.075,-0.08,-0.09,-0.1,-0.095,-0.095,-0.085,-0.095,-0.1,-0.1,-0.115,-0.115,-0.13,-0.14,-0.15,-0.16,-0.145,-0.155,-0.16,-0.17,-0.185,-0.175,-0.17,-0.165,-0.17,-0.17,
-0.165,-0.18,-0.18,-0.2,-0.2,-0.215,-0.205,-0.21,-0.205,-0.21,-0.22,-0.225,-0.225,-0.24,-0.225,-0.21,-0.205,-0.195,-0.19,-0.2,-0.19,-0.19,-0.185,-0.17,-0.17,-0.175,-0.165,-0.165,-0.185,
-0.185,-0.205,-0.205,-0.21,-0.195,-0.195,-0.19,-0.195,-0.195,-0.195,-0.185,-0.175,-0.175,-0.2,-0.225,-0.25,-0.24,-0.24,-0.24,-0.25,-0.26,-0.27,-0.28,-0.305,-0.335,-0.35,
-0.34,-0.285,-0.205,-0.135,-0.095,-0.045,0.01,0.075,0.14,0.175,0.135,0.045,-0.155,-0.425,-0.71,-0.915,-1.09,-1255,-1395,-1465,-1505,-1.49,-1.45,-1.39,-1.34,-1.27,-1155,-1025,
-0.95,-0.93,-0.93,-0.91,-0.885,-0.865,-0.84,-0.8,-0.755,-0.715,-0.66,-0.63,-0.58,-0.54,-0.51,-0.465,-0.435,-0.395,-0.365,-0.315,-0.265,-0.2,-0.155,-0.09,-0.04,-0.015,
-0.01,0.005,0.03,0.055,0.08,0.085,0.09,0.11,0.11,0.13,0.15,0.155,0.15,0.18,0.185,0.205,0.22,0.235,0.235,0.255,0.27,0.29,0.29,0.3,0.3,0.305,0.325,0.315,
0.31,0.315,0.315,0.345,0.36,0.37,0.375,0.375,0.365,0.375,0.385,0.41,0.405,0.4,0.4,0.405,0.4,0.41,0.395,0.4,0.385,0.39,0.395,0.385,0.38,0.355,0.355,0.355,0.35,0.325,0.3,0.28,0.25,0.25,0.25,
0.25,0.235,0.21,0.175,0.165,0.16,0.145,0.14,0.145,0.13,0.1,0.08,0.04,0.015,-0.01,-0.025,-0.025,-0.03,-0.04,-0.045,-0.07,-0.105,-0.08,-0.075,-0.085,-0.09,-0.11,-0.13,-0.12,-0.115,-0.125,-0.15,-0.17,-0.16,-0.16,
-0.15,-0.155,-0.16,-0.17,-0.185,-0.18,-0.18,-0.19,-0.18,-0.17,-0.16,-0.14,-0.14,-0.145,-0.17,-0.18,-0.175,-0.16,-0.155,-0.155,-0.165,-0.15,-0.155,-0.15,-0.145,-0.145,-0.165,-0.195,-0.205,-0.19,-0.18,-0.165,-0.17,
-0.16,-0.17,-0.165,-0.17,-0.17,-0.17,-0.17,-0.185,-0.19,-0.18,-0.18,-0.18,-0.175,-0.2,-0.21,-0.2,-0.2,-0.21,-0.215,-0.21,-0.2,-0.175,-0.16,-0.145,-0.145,-0.135,-0.14,-0.135,-0.13,-0.12,-0.115,-0.11,
-0.105,-0.1,-0.095,-0.11,-0.14,-0.175,-0.18,-0.18,-0.18,-0.165,-0.175,-0.175,-0.175,-0.165,-0.165,-0.165,-0.175,-0.165,-0.16,-0.155,-0.15,-0.155,-0.16,-0.16,-0.155,-0.145,-0.15,-0.15,-0.185,-0.2,
-0.2,-0.195,-0.19,-0.19,-0.195,-0.2,-0.195,-0.185,-0.175,-0.175,-0.155,-0.17,-0.17,-0.165,-0.15,-0.16,-0.165,-0.175,-0.17,-0.17,-0.185,-0.215,-0.225,-0.19,-0.125,-0.04,0.05,0.125,0.215,0.32,0.415,0.5,
0.605,0.725,0.845,0.94,1.06,1.11,1.1,1005,0.86,0.615,0.24,-0.11,-0.335,-0.46,-0.515,-0.54,-0.51,-0.44,-0.385,-0.36,-0.35,-0.335,-0.32,-0.295,-0.3,-0.3,-0.325,-0.335,-0.335};
static int i;

static const int SIZE = 512;


void calcTest(){
  float array2[SIZE];
  for (i = 0; i < SIZE; i++) {
    s = array[i];
    array2[i] = (s * cosf(pi/SIZE * (i + .5) * 1);

    //Print array
    if (s < 0){
      dec = s;
      frac = -(s - dec) * 1000;
      if (dec == 0)
      {
        printf("\n Temp1: -%d.%02u\n", dec, frac);
      }else{
        printf("\n Temp1: %d.%02u\n", dec, frac);
      }           
    }else{
      dec = s;
      frac = (s - dec) * 1000;     
      printf("\n Temp2: %d.%02u\n", dec, (unsigned int)frac);
    }

    //Print array2 which contains the DCT values
    if (s < 0){
      dec = array2[i];
      frac = -(array2[i] - dec) * 1000;
      if (dec == 0)
      {
        printf("\n *Temp1: -%d.%02u\n", dec, frac);
      }else{
        printf("\n *Temp1: %d.%02u\n", dec, frac);
      }           
    }else{
      dec = array2[i];
      frac = (array2[i] - dec) * 1000;     
      printf("\n *Temp2: %d.%02u\n", dec, (unsigned int)frac);
    }
  }
}



//Defining two processors, one for making the 'knock' and one to listen
PROCESS(data_comp, "data_comp");
AUTOSTART_PROCESSES(&data_comp);

/*---------------------------------------------------------------------------*/


PROCESS_THREAD(data_comp, ev, data)
{
  static struct etimer timer;

  PROCESS_BEGIN();  
  
  /* Setup a periodic timer that expires after 10 seconds. */
  etimer_set(&timer, CLOCK_SECOND * 10);
  
  while(1) {
    calcTest();
     /* Wait for the periodic timer to expire and then restart the timer. */
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
    etimer_reset(&timer);
  }

  PROCESS_END();
}

person WRD BAC    schedule 09.04.2021    source источник


Ответы (1)


Чтобы реализовать DCT-II с использованием формулы, просто вычислите формулу:

#include <stdio.h>
#include <math.h>


#define NumberOf(a) (sizeof (a) / sizeof *(a))


static void DCTII(size_t N, float *y, const float *x)
{
    static const float Pi = 0x3.243f6a8885a308d313198a2e03707344ap0f;

    for (size_t k = 0; k < N; ++k)
    {
        float sum = 0;
        for (size_t n = 0; n < N; ++n)
            sum += x[n] * cosf(Pi/N * (n + .5) * k);
        y[k] = sum;
    }
}


int main(void)
{
    float array[] = {0.35, 0.35, -0.37, -0.335, -0.285, -0.23, -0.215};
    float result[NumberOf(array)];

    DCTII(NumberOf(array), result, array);

    for (size_t i = 0; i < NumberOf(result); ++i)
        printf("y[%zu] = %g.\n", i, result[i]);
}

Для большей длины это не самая эффективная реализация.

person Eric Postpischil    schedule 09.04.2021
comment
Поскольку автор использовал тег contiki в этом вопросе - для встроенных устройств рекомендуется предварительно вычислить значения функции cos для конкретных значений аргументов и сохранить их в таблице поиска во флэш-памяти устройства. Затем во время выполнения вместо cos вычислений можно использовать простой поиск по таблице. - person kfx; 09.04.2021
comment
Да, как сказал @kfx, это для встроенных устройств - person WRD BAC; 09.04.2021
comment
@WRDBAC: В чем конкретно вам нужна помощь? Это функция cos? Знаете ли вы, как можно вычислить значения функции cos, которые необходимы в формуле, поместить их в массив и использовать массив вместо функции cos? - person Eric Postpischil; 09.04.2021
comment
@EricPostpischil сейчас я получаю сообщение об ошибке: Undefined error to 'cos', но я включил #include <math.h>? - person WRD BAC; 09.04.2021
comment
@WRDBAC: Можете ли вы написать программу, которая вычисляет значения функции cos, которая вам нужна? Вы знаете, как заставить эту программу точно печатать значения? Вы знаете, как поместить эти значения в исходный код C, определяющий массив? Вы знаете, как использовать этот массив для получения значений, которые вам нужны в функции DCT-II? - person Eric Postpischil; 09.04.2021
comment
Я опубликую свой код, но это файл, используемый в contiki, так что не обращайте внимания на процесс - person WRD BAC; 09.04.2021
comment
@EricPostpischil, мой код опубликован, и причина, по которой у меня два цикла, заключается в том, что я хотел бы посмотреть на DCT-II до и после - person WRD BAC; 09.04.2021