index 

Artificial Intelligence and Signal Processing

In 2022, the artificial intelligence research and deployment company OpenAI, introduced a conversational “large-language” model called ChatGPT, which they had trained on billions of pages of text, almost every book ever published, all of Wikipedia, and selected websites. (You can try it for no cost at https://chat.openai.com/.) The current version, as of mid-2024, is ChatGPT-4o. Since that introduction, there have been many other competing chatbots, such as Google’s Gemini, Microsoft’s CoPilot, Perplexity, and Anthropic’s Claude. There are even AI services that are especially oriented toward code development, such as GitHub Copilot, Amazon CodeWhisperer, Codex, and Tabine.

 

The strength of chatbots is in language interpretation and writing. For example, chatbots are quite good at tasks like suggesting possible titles for papers, talks, or proposals that you are working on. Just feed it all or a portion of what you have written. They can also paraphrase and outline, which can be useful for writing condensed summaries or abstracts. Their knowledge base is extraordinarily wide and they can often answer very specific questions about technical topics. For example, chatbots can offer opinions and suggestions as to whether your writing is suitable for a particular audience and will offer to re-write the whole thing, for example to make it more formal or less formal. They are often better than Google at answering very specific questions about hardware or software programs that would otherwise force you to plow through pages and pages of documentation.

AI as a programmer’s assistant.

But AIs can go well beyond human language tasks; they can also write code in several computer languages commonly used by scientists, such Matlab, Python, Wolfram Mathematica, C/C++, R, Pascal, Fortran, HTML, JavaScript, Excel macros, etc. But the critical question is: Can AIs write code easier, quicker, and more accurately that a human, specifically a human who is a busy scientist who is not a trained computer programmer?

 

Based on my limited testing, ChatGPT and Claude can generate working code in Matlab or Python for quite a range of signal processing applications, if you describe the task adequately. I found that they could write code that works for many signal  processing tasks, if the description is sufficiently complete. But for more complex tasks, its code might not work at all or might not do what you expect. Most often, the cause of failure is that I have written the prompt unclearly or incompletely. It’s somewhat misleading that, even in cases where a chatbot’s code does not work, it is presented in good style, divided into clearly identified sections, usually with explanatory comments for each line, appropriate indentation, examples of use, and even warning that the code may fail under certain circumstances (e.g., division by zero, etc.).

 

A simple example where chatbots work perfectly is Caruana's Algorithm (page 172), which is a fast way to estimate the parameters of a signal peaks that are locally Gaussian near their maxima. I asked the chatbots to create a function that “accepts two vectors x and y approximating a digitally sampled peak, takes the natural log of y, fits a parabola to the resulting data, then computes the position, FWHM, and height of the Gaussian from the coefficients of the parabolic fit”. In this case the chatbot does all the required algebra and creates code that is functionally identical to my hand-coded version.

Next, I asked both ChatGPT and Microsoft’s CoPilot to “Write a Matlab script that creates a plot with two horizontal subplots, the top one showing a signal with several peaks and some random noise, and the bottom one showing the results of applying a smooth of three different widths to that signal, each shown in a different line style and color, with a legend identifying each plot and its smooth width”. This results in a working script that generates the graphic shown here, just as requested, although CoPilot included only one of the smooth widths in its legend. (Note that the chatbots are forced to make choices for several things that I did not specify exactly, including the shape of the peaks, the sampling rate and signal length, and the three smooth widths. Moreover, it adds titles to both subplots, even though I did not specify that detail). It is particularly handy that, if you want to generate a Python equivalent for example, you can simply say “How can I do that in Python” and it creates a working python script that imports the required libraries and generates an almost identical graphic. Although in this case it chose a much lower sampling rate. (The same may be true of the other languages that it knows, but I have not tested that). You can also feed it a program written in one of its languages and ask it to convert it into another of its languages.

 

Sometimes the code generated by chatbots will result in an error, notated by a red warning message in the console of both Matlab and Python/Spyder. You can just copy that error message and paste it directly into the chatbot and it will attempt to fix the problem, often successfully.

 

Another query that created well-structured, easily-modified, functional code is “Create a signal consisting of three noisy Gaussian peaks, determine each peak height, position, and width by iterative curve fitting, repeat the process 10 times with the same Gaussian but with different independent samples of random noise, and then compute the mean and standard deviation of the peak heights, positions, and widths”.  Matlab code. Python code.

 

A more useful variation is a function that fits the sum of n Gaussian functions to the data in x and y, given the value of n and initial estimates of the positions and widths of each Gaussian, then repeats the fit 10 times with slightly different values of the initial estimates, takes the one with the lowest fitting error and returns its values for the position, width, and height of all the best-fit Gaussians”. ChatGPT and Claude produce code that works and, without me even asking, creates a script that demonstrates it with a nice graph.

 

Some other cases where it worked well: “Create a test function that accepts a signal (x,y), then applies the perpendicular drop method to measure the peak widths. Plot the test signal and draw the vertical lines at each minimum.” Both ChatGPT and Claude handled this neatly, as shoen in the graphaic.

Other examples include:

·         creating a Kalman filter,

·         demonstrating the bootstrap method,

·         detecting peaks and estimating their areas by perpendicular drop (shown on the right),

·         demonstrating wavelet denoising (for which Claude’s version worked better that ChatGPT’s),

·         and creating a function that symmetrizes exponentially broadened peaks by first-derivative addition, where Claude worked better than ChatGPT, Gemini, or Perplexity (graphic).

 

 

Clearly asking a chatbot to perform routine tasks such as these is quick and convenient, especially if you are creating the equivalent code in more than one language; it spits out the code faster than I can type. For larger more complex projects, you could break up the code into smaller chunks or functions that a chatbot can handle separately and that you can test separately, then combine them later as needed.

 

A chatbot  always presents its results nicely formatted, with correct spelling and grammar, which many people interpret as a “confident attitude”. This inspires trust in the results, but just as for people, confident does not always mean correct. There are several important caveats:

 

First, the code that a chatbot generates is not necessarily unique; if you ask it to repeat the task, you’ll sometimes get different code (unless the task is so simple that there is only one possible way to do it correctly). This is not necessarily a flaw; there is often more than one way to code a function for a particular purpose. If the code requires variables to be defined, the names of those variables will be chosen by a chatbot  and won’t always be the same from trial to trial. Moreover, unless you specify the name of the function itself, a chatbot  will choose that name as well, based on what the function does). 

 

Second, and more importantly, there may be more than one way to interpret your request, unless you have very carefully worded it to be unambiguous. Take the example of data smoothing (page 42). On the face of it, this is a simple process. Suppose we ask for a function that performs a sliding average smooth of width n and applies it m times. How will that request be interpreted? If you simply say “…apply an n-point sliding average smooth to the y data and repeats it m times", you will get this code, which does what you asked but probably not what you want. The point of applying repeat smooths is to apply the smooth again to the previously smoothed data, not to the original data, as this code does. The general rule is that n passes of a m-width smooth results in a center-weighted smooth of width n*m-n+1. You will get what you want if you ask ChatGPT for a function that “applies an n-point sliding average smooth to y and then repeats the smooth on the previously smoothed data m times", a small but critical difference, resulting in this code, whereas the previous code returns a singly-smoothed result no matter the value of m.

 

Third, there may be unspecified details or side effects that may require addressing, such as the expectation that the number of data points in the signal after processing should be the same as before processing. In the case of smoothing, for example, there is also the question of what to do about the first n and last n data points, for which there are not enough data points to compute a complete smooth (see page 45). There is also the requirement that the smooth operation should be constructed so that it does not shift the x-axis positions of signal features, which is critical in many scientific applications. Human-coded smooth algorithms, such as fastsmooth, consider all these details.

 

Another example of unspecified details is the measurement of the full width at half-maximum (FWHM) of smooth peaks of any shape. The function I wrote for that task is “halfwidth.m”. I used its description as the ChatGPT query: “…a function that accepts a time series x, y, containing one or more peaks, and computes the full width at half maximum of the of the peak in y nearest xo. If xo is omitted, it computes the halfwidth from the maximum y value”. The AI came up with “computeFWHM.m”, which works well if the sampling rate is high enough. However, the AI’s version fails to interpolate between data points when the half-intensity points fall between data points and thus is inaccurate when the sampling rate is low, because I did not specify that it should do so. “CompareFWHM.mcompares both functions on some synthetic data with adjustable sampling rate.

 

Also, chatbots cannot evaluate the graphical results of their calculations. For example, if you ask it to apply some operation, and the graphical result is clearly incorrect, it does not have a clue. But you can complain about that to the chatbot and it will attempt a correction, sometimes successfully.

 

Another technical kink relates to the common Matlab practice of saving functions that you have written as a separate file in the path and then later calling that saved function from a script that you are writing, relying on Matlab to find it in the path. If you ask ChatGPT to convert that new script to another language, you must embed your external functions directly into the code (Matlab R2016b or later).

 

A more challenging task is iterative fitting of noisy overlapping peaks (page 202). I asked ChatGPT to “fit the sum of n Gaussian functions to the data in x and y, given initial estimates of the positions and widths of each Gaussian, returning the position, width, and height of all the best-fit Gaussians”. ChatGPT came up with the attractively coded “iterativefitGaussians.m”. The closest hand-coded equivalent in my tool chest was fitshape2.m (page 202); both codes work, are about the same length, and require similar input and output arguments. There is seldom a uniquely correct answer to iterative fitting problems, but the difference in performance between these two codes is instructive. The self-contained script “DemoiterativefitGaussians2.m” compares these two functions for a simulated signal with three noisy peaks whose true parameters are set in lines 13-15. For an “easy” test case, with little peak overlap, both codes work well. But if the peaks overlap significantly, ChatGPT’s code fails to yield a good fit but my fitshape2.m code does work. The difference is probably due to the different minimization functions employed (lsqcurvefit.m vs fminsearch.m).

One signal processing task that gave the chatbots some trouble was Fourier self-deconvolution (page 113). After several attempts at writing prompts, ChatGPT did the job with the prompt: “Matlab function that performs Fourier self-deconvolution as a means for sharpening the width of signal peaks in x,y, by computing the Fourier transform of the original signal, dividing that by the Fourier transform of a zero-centered Gaussian function of width deconvwidth, performing an inverse Fourier transform of the result, and applies a smoothing function of width smoothwidth to the deconvoluted result”. Function code, test script).

 

Segmented processing functions, treated on page 331, are very useful in cases where the signal varies in character along its length so that a single processing function setting is not optimum. Basically, the idea is that you break up the signal into segments, process each segment with different settings, then reassemble the processed segments. A simple example is segmented smoothing (page 55).  The following prompt seems like a reasonable explanation of what is required:

 

“Write a function that accepts a signal vector y and a vector s of length n, makes n copies of y, smooths each one with a smooth width equal to the nth element of the vector s, then reassembles the smoothed signal from the nth segment of the nth copy.”

 

But when the resulting function is applied to the signal in blue on the left, the smoothed signal, in red, exhibits serious discontinuities. The problem here is caused by the “end effects” of smoothing, described on  page 45.

 

 

 

The problem is solved by an explicit description of a process that will avoid the problem: “Matlab function that accepts a signal vector y, a number of  segments n, an initial smooth width Wstart and a final smooth width of Wend, creates vector S of length n, whose first element is Wstart, last element is Wend, and other elements are evenly distributed between Wstart and Wend. The function makes n copies of y, smooths each one with a smooth width equal to the nth element of the vector S, then reassembles the smoothed signal from the nth segment of the nth copy”.


 

For more complex functions, it rapidly gets to the point where it’s impossible to completely describe the function in enough detail. This is especially true of open-source code that has been developed incrementally over time, with lots of added options and features suggested by hundreds of users, such as my 5500-line interactive peak fitter, ipf.m (page 414), or my 4000-line peakfit.m function (page 394) which takes up to 12 input arguments, provides 8 output values, and fits 50 different peak shapes. Even describing such functions completely for a chatbot would be tedious at best. It’s unrealistic to expect any chatbot to completely replace such efforts.

 

ChatGPT cannot write Matlab Live Scripts or Apps because they are not text files. However, you can easily convert a chatbot-generated script into a Live Script, as described on page 365, or you can have chatbots write keyboard-controlled interactive functions (like those described on page 394). I tested this with a simple pan-zoom-smooth function, using the prompt: “Write a Matlab function that accepts and plots a signal as an x,y pair and has pan and zoom functions that are interactively controlled by the keyboard cursor keys, using the left and right cursor keys to pan back and forth and the up and down keys to zoom in and out. Add a smoothing function that uses the A and Z keys to increase and decrease the smooth width.” Oddly, ChatGPT and Claude failed with the zoom part of this function, for reasons that are not clear, but Perplexity succeeded. This code could serve as the bones of a customized interactive function with your own additional keypress functions added, modeled on the smooth function (with the smooth width controlled by the “a” and “z” keys).

 

Much more thought and experience go into hand-coded programs than AI generated ones. An experienced human coder knows the typical range of applications and anticipates typical problems and limitations, especially as those apply to the specific field of applications, such as signals generated by different types of scientific instrumentation. Of course, AIs do know a great deal about specific computer languages and their capabilities and inbuilt functions, which can be very useful, especially if you are re-coding an algorithm in a new or less familiar computer language. But AIs are no replacement for human experience. It goes without saying that you must test any code that a chatbot gives you, just as you must test your own code.

 

Another useful service that chatbots can perform is to recognize the function and purpose of parts of a program that you are trying to understand. For example, if you feed ChatGPT this script, sft.m, without any comment, it will recognize it as a (slow) Fourier transform calculation. It will also recognize mathematical expressions and equations, such as the compound interest equation V = S*(1 + R)^T.

 

It seems likely that in the future, AI services such as chatbots will be much more capable and more widely available. Development is ongoing, and millions of users are already using the chatbot servers with free or subscription-based accounts.

 

How to use ChatGPT to code any programming language

 

Using ChatGPT as Your Programming Assistant

 




This page is part of "A Pragmatic Introduction to Signal Processing", created and maintained by Prof. Tom O'Haver , Department of Chemistry and Biochemistry, The University of Maryland at College Park. Comments, suggestions and questions should be directed to Prof. O'Haver at toh@umd.edu. Updated May, 2024.