Sample equally a set of discontinuous points

96 Views Asked by At

Suppose I have a vector $a=[0, 0.3, 1]$ with amplitudes $A=[0, 1, 0]$ and I want it sampled, equally-spaced, with $N=8$ samples from $a[0]=0$ to $a[2]=1$. If I only keep count of $0$ and $1$, the sampled vector would be $[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875]$, and $a[1]=0.3$ would fall between the samples. The same would be true for $N=7$, to have samples at both $0$ and $1$. My question: is there a known way to sample the $a$ vector as if it were a continuous function? The values in both $a$ and $A$ are random.

For example, $N=8$ would result in $[0, 0.125, 0.25, 0.26786, 0.21429, 0.160714, 0.10714, 0.053571, 0]$.

I don't know if there is a solution for this, so my apologies in advance if this is trivial; my searches couldn't find anything.


[edit] Let's say the vector $a$ holds frequencies and $A$ amplitudes and I need to sample $a$ for inverse FFT. Given that both $a$ and $A$ can have random values, e.g. they don't follow a known formula, how can I generate the evenly sampled spectrum based only on knowing the two vectors?


I'll try to be a bit more clear. Suppose $f=[0, 0.3, 1]$ (frequencies) and $A=[0, 1, 0]$ (amplitudes). I need to find the continuous-time equivalent of the function that would give amplitude $A[0]@f[0]$, $A[1]@f[1]$, etc. After some hammering, I came up to this (in wxMaxima, indices start from 1):

$$p(x):=if\space (x<=f[2])\space then\space \frac{A[2]-A[1]}{f[2]-f[1]}(x-f[1])+A[1]\space else\space \frac{A[3]-A[2]}{f[3]-f[2]}(x-f[2])+A[2]$$

After some more searches, it looks like this comes close to linear interpolation, and can be extended for $f=[0.1, 0.3, 0.4, 1]$, $A=[0.5, 0.8, -0.2, 0.5]$, or any other values. The last step is properly sampling $p(\frac{k}{N})$. The only problem I see is the recursion that seems to form in there. Is there a simpler way than my childish scribbling?

2

There are 2 best solutions below

0
On BEST ANSWER

It does look like I reinvented the wheel, but if it works... My purpose was to implement it in C++, but the mathematical way eluded me, that's why I posted it here, rather than SO, or elsewhere. I managed to make the wxMaxima function like this:

p(x,y) := block([j:1, k:0, out],
            for i:1 thru N do
            (
              out[i] : (y[j+1] - y[j])/(x[j+1] - x[j])*(k - x[j]) + y[j],
              k : k + 1/N,
              j : if k<=x[j+1] then j else j+1
            ),
            makelist(out[k],k,1,N) )$

And the test with $f=[0, 0.3, 0.4, 0.7, 1]$, $A=[0.4, -0.1, 0.8, -0.2, 0.5]$:

test

Also made a quick test code in C++, looks like this:

#include <iostream>
#include <array>

int main()
{
    const int n {5};
    const int N {8};
    double step {1.0/N};
    double k {0.0};
    std::array<double, n> f {0.0, 0.3, 0.4, 0.7, 1.0};
    std::array<double, n> A {0.4, -0.1, 0.8, -0.2, 0.5};
    std::array<double, N> x;
    for(int i=0, j=0; i<N; ++i)
    {
        x[i] = (A[j+1] - A[j])/(f[j+1] - f[j])*(k - f[j]) + A[j];
        k += step;
        j += (k <= f[j+1] ? 0 : 1);
        std::cout << x[i] << ", ";
    }
    std::cout << '\n';
    return 0;
}

I'll leave the question, maybe (most probably) someone else knows of a better way to do it.

1
On

Your question is not clear. You are using "sample" in a non-standard sense of the word. I would called the values you are finding "interpolation nodes" or something like that. The role of 0.3 in the selection is not clear. The role of A is not clear.