{
  "id": 238839,
  "title": "STF, different buckets appear non-periodical and cannot rebuild original signal",
  "url": "/competitions/birdclef-2021/discussion/238839",
  "author_name": "",
  "post_date": "2021-05-13T15:29:22.439064600Z",
  "votes": 2,
  "comment_count": 4,
  "views": 0,
  "content": "<p>Hi there,</p>\n<p>I have been toying around with with frequencies.<br>\nLooking at the complex representation of frequencies and Fourier Transformation.<br>\nThe formula for representing a periodic signal  is<br>\ny(t) = A * e **(j(wt+phi))<br>\nwith<br>\nA := amplitude<br>\nw := 2 * PI * bucket frequency<br>\nt := the number of the sample looked at in the current time frame<br>\nphi := the angle</p>\n<p>creating code for this I appear to have made a mistake in either the code or the understanding of the result. <br>\nThe result appears to be non periodical and increasing in intervals.</p>\n<p>Following is the code:</p>\n<pre><code>import pandas as pd\nimport librosa\nimport librosa.display\nimport librosa.feature\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrequency1 = 5000\namp1 = 2\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nn_fft = frequency1 * 2 #theorem saying only one needs at least frequency * 2 samples rates to display frequency nicely\nft = librosa.stft(y1, n_fft=n_fft, hop_length=n_fft, center=False)\nft.shape\n#ft.shape[0] --&gt; frequency buckets\n#ft.shape[1] --&gt; timebuckets encode for n_fft samples\n\nfreqs = np.arange(0,1+n_fft//2)\nelement = np.sum(ft[5][3])\nfreq = freqs[5]\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * freq\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n</code></pre>\n<p>Also: adding the elements up again does not yield the original.<br>\n(I mean to do this to verify that the logic for generating the waves for the different frequency buckets is actually working)</p>\n<pre><code>element = np.sum(ft[1:,:]) # Not leaving the DC domain out is not returning the original signal.\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * frequency1\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n</code></pre>\n<p>Signal processing is not my area of expertise and I appear to be missing some basic knowledge somewhere and would love to know what I am assuming/doing wrong here.</p>\n<p>I am aware that there are inverse functions for this but I would like to know more this for practical purposes. Thank you</p>\n<p>Dud.</p>",
  "messages": [
    {
      "id": "1306036",
      "postDate": "05/13/2021 15:29:22",
      "content": "<p>Hi there,</p>\n<p>I have been toying around with with frequencies.<br>\nLooking at the complex representation of frequencies and Fourier Transformation.<br>\nThe formula for representing a periodic signal  is<br>\ny(t) = A * e **(j(wt+phi))<br>\nwith<br>\nA := amplitude<br>\nw := 2 * PI * bucket frequency<br>\nt := the number of the sample looked at in the current time frame<br>\nphi := the angle</p>\n<p>creating code for this I appear to have made a mistake in either the code or the understanding of the result. <br>\nThe result appears to be non periodical and increasing in intervals.</p>\n<p>Following is the code:</p>\n<pre><code>import pandas as pd\nimport librosa\nimport librosa.display\nimport librosa.feature\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrequency1 = 5000\namp1 = 2\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nn_fft = frequency1 * 2 #theorem saying only one needs at least frequency * 2 samples rates to display frequency nicely\nft = librosa.stft(y1, n_fft=n_fft, hop_length=n_fft, center=False)\nft.shape\n#ft.shape[0] --&gt; frequency buckets\n#ft.shape[1] --&gt; timebuckets encode for n_fft samples\n\nfreqs = np.arange(0,1+n_fft//2)\nelement = np.sum(ft[5][3])\nfreq = freqs[5]\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * freq\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n</code></pre>\n<p>Also: adding the elements up again does not yield the original.<br>\n(I mean to do this to verify that the logic for generating the waves for the different frequency buckets is actually working)</p>\n<pre><code>element = np.sum(ft[1:,:]) # Not leaving the DC domain out is not returning the original signal.\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * frequency1\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n</code></pre>\n<p>Signal processing is not my area of expertise and I appear to be missing some basic knowledge somewhere and would love to know what I am assuming/doing wrong here.</p>\n<p>I am aware that there are inverse functions for this but I would like to know more this for practical purposes. Thank you</p>\n<p>Dud.</p>",
      "rawMarkdown": "Hi there,\n\nI have been toying around with with frequencies.\nLooking at the complex representation of frequencies and Fourier Transformation.\nThe formula for representing a periodic signal  is\ny(t) = A * e **(j(wt+phi))\nwith\nA := amplitude\nw := 2 * PI * bucket frequency\nt := the number of the sample looked at in the current time frame\nphi := the angle\n\ncreating code for this I appear to have made a mistake in either the code or the understanding of the result. \nThe result appears to be non periodical and increasing in intervals.\n\nFollowing is the code:\n\n```\nimport pandas as pd\nimport librosa\nimport librosa.display\nimport librosa.feature\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrequency1 = 5000\namp1 = 2\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nn_fft = frequency1 * 2 #theorem saying only one needs at least frequency * 2 samples rates to display frequency nicely\nft = librosa.stft(y1, n_fft=n_fft, hop_length=n_fft, center=False)\nft.shape\n#ft.shape[0] --> frequency buckets\n#ft.shape[1] --> timebuckets encode for n_fft samples\n\nfreqs = np.arange(0,1+n_fft//2)\nelement = np.sum(ft[5][3])\nfreq = freqs[5]\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * freq\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n```\nAlso: adding the elements up again does not yield the original.\n(I mean to do this to verify that the logic for generating the waves for the different frequency buckets is actually working)\n\n```\nelement = np.sum(ft[1:,:]) # Not leaving the DC domain out is not returning the original signal.\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * frequency1\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n```\n\nSignal processing is not my area of expertise and I appear to be missing some basic knowledge somewhere and would love to know what I am assuming/doing wrong here.\n\nI am aware that there are inverse functions for this but I would like to know more this for practical purposes. Thank you\n\nDud.",
      "votes": null
    },
    {
      "id": "1306049",
      "postDate": "05/13/2021 15:38:33",
      "content": "<p>librosa provides the inverse transform.  Maybe have a look at its code: <a href=\"https://librosa.org/doc/0.8.0/generated/librosa.istft.html#librosa.istft\" target=\"_blank\">https://librosa.org/doc/0.8.0/generated/librosa.istft.html#librosa.istft</a></p>",
      "rawMarkdown": "librosa provides the inverse transform.  Maybe have a look at its code: https://librosa.org/doc/0.8.0/generated/librosa.istft.html#librosa.istft",
      "votes": null
    },
    {
      "id": "1308458",
      "postDate": "05/15/2021 08:16:45",
      "content": "<p>Hi CPMP,</p>\n<p>thanks for the input. Unfortunately, the logic at the heart of istft is in a shared object file.<br>\nnumpy/fft/_pocketfft_internal.cpython-38-x86_64-linux-gnu.so<br>\nBut it gave me an idea for a  practical approach.👍<br>\nWhile I see myself unable to find the error in my code above, I can piggy back of the logic already existing by zeroing out all buckets not required. The outcome should be the same.</p>\n<p>So if someone does have an idea as to what I am doing wrong in the code above, feel free to help me out.<br>\nCheers</p>\n<p>Dud.</p>",
      "rawMarkdown": "Hi CPMP,\n\nthanks for the input. Unfortunately, the logic at the heart of istft is in a shared object file.\nnumpy/fft/_pocketfft_internal.cpython-38-x86_64-linux-gnu.so\nBut it gave me an idea for a  practical approach.👍\nWhile I see myself unable to find the error in my code above, I can piggy back of the logic already existing by zeroing out all buckets not required. The outcome should be the same.\n\nSo if someone does have an idea as to what I am doing wrong in the code above, feel free to help me out.\nCheers\n\nDud.",
      "votes": null
    },
    {
      "id": "1308556",
      "postDate": "05/15/2021 09:53:34",
      "content": "<p>Looking at your code I don't see why you need a Fourier tranform at all.</p>\n<p>From y(t) = A * e **(j(wt+phi)), if you take the real component of it is:</p>\n<p>y(t) = A * cos((wt+phi))</p>\n<p>And if you plot it then you get the sinusoidal you are looking for.</p>\n<p>If you take a Fourier transform then I bet the signal appears as a straight line at the frequency you used.</p>",
      "rawMarkdown": "Looking at your code I don't see why you need a Fourier tranform at all.\n\nFrom y(t) = A * e **(j(wt+phi)), if you take the real component of it is:\n\ny(t) = A * cos((wt+phi))\n\nAnd if you plot it then you get the sinusoidal you are looking for.\n\nIf you take a Fourier transform then I bet the signal appears as a straight line at the frequency you used.",
      "votes": null
    },
    {
      "id": "1308908",
      "postDate": "05/15/2021 14:34:21",
      "content": "<p>Yes, but, correct me if I am wrong, that would only work with a purely sinusoidal function.<br>\nI have chosen that function because it is quite easy to spot a problem upon reconstruction.<br>\nMy goal here is the ability to generate a sinusoidal function from the frequency buckets.<br>\nA little thought experiment:<br>\nHaving a more complex example like curve y</p>\n<pre><code>import numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\n\nfrequency1 = 5000\nfrequency2 = 10000\namp1 = 2\namp2 = 5\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nx=np.arange(0,(2*2048*np.pi/frequency2),xaxis_unit)\ny2=amp2*np.sin(frequency2*x)\nplt.plot(x[0:100],y2[0:100])\nplt.show()\n\ny=y1+y2\nplt.plot(x[0:100],y[0:100])\nplt.show()\n</code></pre>\n<p>I do have a frequency, the carrier frequency1, but the amplitudes do not always add up to the maximum of the sum due to the difference in frequency.<br>\nSo within one iteration of the signal I have a pattern which I cannot reproduce with a single sinusoidal function unless I consider having w run backwards for some time multiple times in one iteration, which does not let itself nicely to the continuity of t and values.</p>\n<p>And yes you are right, it will only be single line in the FT-diagram using a simple sinus function.</p>\n<p>//edit y will of course be 2 lines in the FT-diagrams.</p>\n<p>//edit second<br>\nI also believe I need the imaginary number as I would have trouble with the phase otherwise as some additions of frequencies to the final signal might require the sine or cosine to have their \"start position\" a bit earlier or later.</p>",
      "rawMarkdown": "Yes, but, correct me if I am wrong, that would only work with a purely sinusoidal function.\nI have chosen that function because it is quite easy to spot a problem upon reconstruction.\nMy goal here is the ability to generate a sinusoidal function from the frequency buckets.\nA little thought experiment:\nHaving a more complex example like curve y\n```\nimport numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\n\nfrequency1 = 5000\nfrequency2 = 10000\namp1 = 2\namp2 = 5\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nx=np.arange(0,(2*2048*np.pi/frequency2),xaxis_unit)\ny2=amp2*np.sin(frequency2*x)\nplt.plot(x[0:100],y2[0:100])\nplt.show()\n\ny=y1+y2\nplt.plot(x[0:100],y[0:100])\nplt.show()\n```\nI do have a frequency, the carrier frequency1, but the amplitudes do not always add up to the maximum of the sum due to the difference in frequency.\nSo within one iteration of the signal I have a pattern which I cannot reproduce with a single sinusoidal function unless I consider having w run backwards for some time multiple times in one iteration, which does not let itself nicely to the continuity of t and values.\n\nAnd yes you are right, it will only be single line in the FT-diagram using a simple sinus function.\n\n//edit y will of course be 2 lines in the FT-diagrams.\n\n//edit second\nI also believe I need the imaginary number as I would have trouble with the phase otherwise as some additions of frequencies to the final signal might require the sine or cosine to have their \"start position\" a bit earlier or later.",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1306049,
      "author_name": "cpmpml",
      "author_url": "",
      "post_date": "05/13/2021 15:38:33",
      "content": "<p>librosa provides the inverse transform.  Maybe have a look at its code: <a href=\"https://librosa.org/doc/0.8.0/generated/librosa.istft.html#librosa.istft\" target=\"_blank\">https://librosa.org/doc/0.8.0/generated/librosa.istft.html#librosa.istft</a></p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1308458,
      "author_name": "badhairday",
      "author_url": "",
      "post_date": "05/15/2021 08:16:45",
      "content": "<p>Hi CPMP,</p>\n<p>thanks for the input. Unfortunately, the logic at the heart of istft is in a shared object file.<br>\nnumpy/fft/_pocketfft_internal.cpython-38-x86_64-linux-gnu.so<br>\nBut it gave me an idea for a  practical approach.👍<br>\nWhile I see myself unable to find the error in my code above, I can piggy back of the logic already existing by zeroing out all buckets not required. The outcome should be the same.</p>\n<p>So if someone does have an idea as to what I am doing wrong in the code above, feel free to help me out.<br>\nCheers</p>\n<p>Dud.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1308556,
      "author_name": "cpmpml",
      "author_url": "",
      "post_date": "05/15/2021 09:53:34",
      "content": "<p>Looking at your code I don't see why you need a Fourier tranform at all.</p>\n<p>From y(t) = A * e **(j(wt+phi)), if you take the real component of it is:</p>\n<p>y(t) = A * cos((wt+phi))</p>\n<p>And if you plot it then you get the sinusoidal you are looking for.</p>\n<p>If you take a Fourier transform then I bet the signal appears as a straight line at the frequency you used.</p>",
      "votes": null,
      "replies": [
        {
          "id": 1308908,
          "author_name": "badhairday",
          "author_url": "",
          "post_date": "05/15/2021 14:34:21",
          "content": "<p>Yes, but, correct me if I am wrong, that would only work with a purely sinusoidal function.<br>\nI have chosen that function because it is quite easy to spot a problem upon reconstruction.<br>\nMy goal here is the ability to generate a sinusoidal function from the frequency buckets.<br>\nA little thought experiment:<br>\nHaving a more complex example like curve y</p>\n<pre><code>import numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\n\nfrequency1 = 5000\nfrequency2 = 10000\namp1 = 2\namp2 = 5\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nx=np.arange(0,(2*2048*np.pi/frequency2),xaxis_unit)\ny2=amp2*np.sin(frequency2*x)\nplt.plot(x[0:100],y2[0:100])\nplt.show()\n\ny=y1+y2\nplt.plot(x[0:100],y[0:100])\nplt.show()\n</code></pre>\n<p>I do have a frequency, the carrier frequency1, but the amplitudes do not always add up to the maximum of the sum due to the difference in frequency.<br>\nSo within one iteration of the signal I have a pattern which I cannot reproduce with a single sinusoidal function unless I consider having w run backwards for some time multiple times in one iteration, which does not let itself nicely to the continuity of t and values.</p>\n<p>And yes you are right, it will only be single line in the FT-diagram using a simple sinus function.</p>\n<p>//edit y will of course be 2 lines in the FT-diagrams.</p>\n<p>//edit second<br>\nI also believe I need the imaginary number as I would have trouble with the phase otherwise as some additions of frequencies to the final signal might require the sine or cosine to have their \"start position\" a bit earlier or later.</p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "1306036": "Hi there,\n\nI have been toying around with with frequencies.\nLooking at the complex representation of frequencies and Fourier Transformation.\nThe formula for representing a periodic signal  is\ny(t) = A * e **(j(wt+phi))\nwith\nA := amplitude\nw := 2 * PI * bucket frequency\nt := the number of the sample looked at in the current time frame\nphi := the angle\n\ncreating code for this I appear to have made a mistake in either the code or the understanding of the result. \nThe result appears to be non periodical and increasing in intervals.\n\nFollowing is the code:\n\n```\nimport pandas as pd\nimport librosa\nimport librosa.display\nimport librosa.feature\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrequency1 = 5000\namp1 = 2\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nn_fft = frequency1 * 2 #theorem saying only one needs at least frequency * 2 samples rates to display frequency nicely\nft = librosa.stft(y1, n_fft=n_fft, hop_length=n_fft, center=False)\nft.shape\n#ft.shape[0] --> frequency buckets\n#ft.shape[1] --> timebuckets encode for n_fft samples\n\nfreqs = np.arange(0,1+n_fft//2)\nelement = np.sum(ft[5][3])\nfreq = freqs[5]\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * freq\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n```\nAlso: adding the elements up again does not yield the original.\n(I mean to do this to verify that the logic for generating the waves for the different frequency buckets is actually working)\n\n```\nelement = np.sum(ft[1:,:]) # Not leaving the DC domain out is not returning the original signal.\nA = np.abs(element)\nt = np.arange(0,n_fft)\nw = 2 * np.pi * frequency1\nj = np.imag(element)\nh = A * (np.e ** (1j * (w * t + np.angle(element))))\nplt.plot(h)\n```\n\nSignal processing is not my area of expertise and I appear to be missing some basic knowledge somewhere and would love to know what I am assuming/doing wrong here.\n\nI am aware that there are inverse functions for this but I would like to know more this for practical purposes. Thank you\n\nDud.",
    "1306049": "librosa provides the inverse transform.  Maybe have a look at its code: https://librosa.org/doc/0.8.0/generated/librosa.istft.html#librosa.istft",
    "1308458": "Hi CPMP,\n\nthanks for the input. Unfortunately, the logic at the heart of istft is in a shared object file.\nnumpy/fft/_pocketfft_internal.cpython-38-x86_64-linux-gnu.so\nBut it gave me an idea for a  practical approach.👍\nWhile I see myself unable to find the error in my code above, I can piggy back of the logic already existing by zeroing out all buckets not required. The outcome should be the same.\n\nSo if someone does have an idea as to what I am doing wrong in the code above, feel free to help me out.\nCheers\n\nDud.",
    "1308556": "Looking at your code I don't see why you need a Fourier tranform at all.\n\nFrom y(t) = A * e **(j(wt+phi)), if you take the real component of it is:\n\ny(t) = A * cos((wt+phi))\n\nAnd if you plot it then you get the sinusoidal you are looking for.\n\nIf you take a Fourier transform then I bet the signal appears as a straight line at the frequency you used.",
    "1308908": "Yes, but, correct me if I am wrong, that would only work with a purely sinusoidal function.\nI have chosen that function because it is quite easy to spot a problem upon reconstruction.\nMy goal here is the ability to generate a sinusoidal function from the frequency buckets.\nA little thought experiment:\nHaving a more complex example like curve y\n```\nimport numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\n\nfrequency1 = 5000\nfrequency2 = 10000\namp1 = 2\namp2 = 5\n\nxaxis_unit = 0.1/frequency1\n\nx=np.arange(0,(2048*np.pi/frequency1),xaxis_unit)\ny1=amp1*np.sin(frequency1*x)\nplt.plot(x[0:100],y1[0:100])\n\nx=np.arange(0,(2*2048*np.pi/frequency2),xaxis_unit)\ny2=amp2*np.sin(frequency2*x)\nplt.plot(x[0:100],y2[0:100])\nplt.show()\n\ny=y1+y2\nplt.plot(x[0:100],y[0:100])\nplt.show()\n```\nI do have a frequency, the carrier frequency1, but the amplitudes do not always add up to the maximum of the sum due to the difference in frequency.\nSo within one iteration of the signal I have a pattern which I cannot reproduce with a single sinusoidal function unless I consider having w run backwards for some time multiple times in one iteration, which does not let itself nicely to the continuity of t and values.\n\nAnd yes you are right, it will only be single line in the FT-diagram using a simple sinus function.\n\n//edit y will of course be 2 lines in the FT-diagrams.\n\n//edit second\nI also believe I need the imaginary number as I would have trouble with the phase otherwise as some additions of frequencies to the final signal might require the sine or cosine to have their \"start position\" a bit earlier or later."
  },
  "source": "meta"
}