Any known linear algorithm to approximate a function with line segments? - function

I have a function given by a list of points, ex:
f = [0.03, 0.05, 0.02, 1.3, 1.0, 5.6, ..., 13.4, 12.45]
I need an algorithm (with linear complexity) to "cut" this function/list into K intervals/sublists so that each interval/sublist contains points that "lie near a line segment" (take a look at the image)
The number K may be decided either by the algorithm itself or be a parameter of the algorithm. (preferable is to be decided by the algorithm itself)
Is there such a known algorithm I could use ?

i am writing with smartphone so this is short. Basically a function is nearly linear if the difference between two consecutive values is approximately equal see http://psn.virtualnerd.com/viewtutorial/PreAlg_13_01_0006
As an algorithm for traversing an unsorted array Sliding Window is nice ( https://www.geeksforgeeks.org/window-sliding-technique/ ) and can be implemented by a single pass (1-pass solution)
Update because comment :
So with a sliding window you can implement the vagueness or fuzziness of the values you mentioned in the comment this is why nearly linear and approximately, i.e.
if(abs(abs(x[i]-x[i+1]) - abs(x[i+1]-x[i+2])) < 0.5)
{linearity_flag=1;}
else
{linearity_flag=0;}
where x[i]-x[i+1] and x[i+1]-x[i+2] are two consecutive differences of two consecutive values and 0.5 is a deliberately chosen threshold that fixes what you define as a straight line or linear function in an x-y graph (or what 'jittering' of the line you allow). So you have to use the difference of differences of consecutive values. Instead of 3 points you can also include more points with this approach (sliding window)
If you want a strict mathematical ansatz you could use other curve analysis techniques : https://openstax.org/books/calculus-volume-1/pages/4-5-derivatives-and-the-shape-of-a-graph (actually the difference of differences of consecutive values is a discrete realization of a 2nd derivative)

Related

Function for Non-Linear interpolation of real data

I want to generate a function which would non-linearly interpolate data. Let's say the fraction x (varies between 0 and 1) represents the distance from the Point A towards Point B. So, if x=0, we are at Point A and if x=1, we are at Point B. Now the condition I have if that at x=0.1, we would need to have travelled 90% of the distance from Point A towards Point B. Notice, I would not be able to connect this with the actual values of the parameter data at Point A or B unlink is the case in exponential interpolation techniques [https://www.mrmath.com/misfit/algebra-stuff/linear-and-non-linear-interpolation/#:~:text=ExponentialThe%20second%20most%20popular,smooth%2C%20concave%20curve%20between%20points].
The following resources are too tough for me and I am looking for the simplest solutions:-
https://www.sciencedirect.com/science/article/pii/0022247X82901378
https://ieeexplore.ieee.org/document/1054589
As an example of linear interpolation, let's say that the value of the parameter at Point A is 'a' and at Point B is 'b'. The linear interpolation formula is then given as:-
a+(b-a)*y
where y=x for linear interpolations. I wish to develop a non-linear function for y=f(x). Is there an easy general way for this?

Can a neural network having non-linear activation function (say ReLU) be used for linear classification task?

I think the answer would be yes, but I'm unable to reason out a good explanation on this.
The mathematical argument lies in a power to represent linearity, we can use following three lemmas to show that:
Lemma 1
With affine transformations (linear layer) we can map the input hypercube [0,1]^d into arbitrary small box [a,b]^k. Proof is quite simple, we can just make all the biases to be equal to a, and make weights multiply by (b-a).
Lemma 2
For sufficiently small scale, many non-linearities are approximately linear. This is actually very much a definition of a derivative, or, taylor expansion. In particular let us take relu(x), for x>0 it is in fact, linear! What about sigmoid? Well if we look at a tiny tiny region [-eps, eps] you can see that it approaches a linear function as eps->0!
Lemma 3
Composition of affine functions is affine. In other words, if I were to make a neural network with multiple linear layers, it is equivalent of having just one. This comes from the matrix composition rules:
W2(W1x + b1) + b2 = W2W1x + W2b1 + b2 = (W2W1)x + (W2b1 + b2)
------ -----------
New weights New bias
Combining the above
Composing the three lemmas above we see that with a non-linear layer, there always exists an arbitrarily good approximation of the linear function! We simply use the first layer to map entire input space into the tiny part of the pre-activation spacve where your linearity is approximately linear, and then we "map it back" in the following layer.
General case
This is a very simple proof, now in general you can use Universal Approximation Theorem to show that a non-linear neural network (Sigmoid, Relu, many others) that is sufficiently large, can approximate any smooth target function, which includes linear ones. This proof (originally given by Cybenko) is however much more complex and relies on showing that specific classes of functions are dense in the space of continuous functions.
Technically, yes.
The reason you could use a non-linear activation function for this task is that you can manually alter the results. Let's say the range the activation function outputs is between 0.0-1.0, then you can round up or down to get a binary 0/1. Just to be clear, rounding up or down isn't linear activation, but for this specific question the purpose of the network was for classification, where some kind of rounding has to be applied.
The reason you shouldn't is the same reason that you shouldn't attach an industrial heater to a fan and call it a hair-drier, it's unnecessarily powerful and it could potentially waste resources and time.
I hope this answer helped, have a good day!

Find the Relationship Between Two Logarithmic Equations

No idea if I am asking this question in the right place, but here goes...
I have a set of equations that were calculated based on numbers ranging from 4 to 8. So an equation for when this number is 5, one for when it is 6, one for when it is 7, etc. These equations were determined from graphing a best fit line to data points in a Google Sheet graph. Here is an example of a graph...
Example...
When the number is between 6 and 6.9, this equation is used: windGust6to7 = -29.2 + (17.7 * log(windSpeed))
When the number is between 7 and 7.9, this equation is used: windGust7to8 = -70.0 + (30.8 * log(windSpeed))
I am using these equations to create an image in python, but the image is too choppy since each equation covers a range from x to x.9. In order to smooth this image out and make it more accurate, I really would need an equation for every 0.1 change in number. So an equation for 6, a different equation for 6.1, one for 6.2, etc.
Here is an example output image that is created using the current equations:
So my question is: Is there a way to find the relationship between the two example equations I gave above in order to use that to create a smoother looking image?
This is not about logarithms; for the purposes of this derivation, log(windspeed) is a constant term. Rather, you're trying to find a fit for your mapping:
6 (-29.2, 17.7)
7 (-70.0, 30.8)
...
... and all of the other numbers you have already. You need to determine two basic search paramteres:
(1) Where in each range is your function an exact fit? For instance, for the first one, is it exactly correct at 6.0, 6.5, 7.0, or elsewhere? Change the left-hand column to reflect that point.
(2) What sort of fit do you want? You are basically fitting a pair of parameterized equations, one for each coefficient:
x y x y
6 -29.2 6 17.7
7 -70.0 7 30.8
For each of these, you want to find the coefficients of a good matching function. This is a large field of statistical and algebraic study. Since you have four ranges, you will have four points for each function. It is straightforward to fit a cubic equation to each set of points in Cartesian space. However, the resulting function may not be as smooth as you like; in such a case, you may well find that a 4th- or 5th- degree function fits better, or perhaps something exponential, depending on the actual distribution of your points.
You need to work with your own problem objectives and do a little more research into function fitting. Once you determine the desired characteristics, look into scikit for fitting functions to do the heavy computational work for you.

sRGB's linear segment to avoid infinite slope - why?

In this article about sRGB (https://en.wikipedia.org/wiki/SRGB) is stated, that the gamma transformation has a linear portion near zero, to "avoid having an infinite slope at K = 0, which can cause numerical problems". I'd like to know what's the problem with that.
There are two answers, as is usual for gamma. The modern variant is:
The problem is that with an infinite slope you need "infinite" resolution (many bits of storage) in order to arrive at a linear representation that is invertible to gamma-encoded without loss. In other words, it allows for a small lookup table to produce an invertible linear encoding (8bit -> 10 bit -> 8 bit).
The numerical problem is most easily understood on the first step (8 bit -> 10 bit). With an infinite slope near zero, you need a much bigger encoding range to stay faithful and reversible, i.e. you'd need more than 16 bit (assuming integer coding, halfs do not have this problem).
The linear equivalent of #010101 or 1/255th with square (gamma = 2.0) coding is 1/(255*255)th. You would need 16 bits to represent that faithfully, and using 2.2 not 2.0 as an exponent would make it worse. These quite small numbers are just a corollary of the coding function, and in practice you don't need much resolution in a lightness range that is, roughly, black. So the linear segment helps coding by not wasting resolution to detail around black (or near zero).
The slightly older answer, taken from
http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html#gamma_correction
is that in some equipment this linear segment will be less sensitive to noise. This is probably mostly true of the analog signal path.

understanding getByteTimeDomainData and getByteFrequencyData in web audio

The documentation for both of these methods are both very generic wherever I look. I would like to know what exactly I'm looking at with the returned arrays I'm getting from each method.
For getByteTimeDomainData, what time period is covered with each pass? I believe most oscopes cover a 32 millisecond span for each pass. Is that what is covered here as well? For the actual element values themselves, the range seems to be 0 - 255. Is this equivalent to -1 - +1 volts?
For getByteFrequencyData the frequencies covered is based on the sampling rate, so each index is an actual frequency, but what about the actual element values themselves? Is there a dB range that is equivalent to the values returned in the returned array?
getByteTimeDomainData (and the newer getFloatTimeDomainData) return an array of the size you requested - its frequencyBinCount, which is calculated as half of the requested fftSize. That array is, of course, at the current sampleRate exposed on the AudioContext, so if it's the default 2048 fftSize, frequencyBinCount will be 1024, and if your device is running at 44.1kHz, that will equate to around 23ms of data.
The byte values do range between 0-255, and yes, that maps to -1 to +1, so 128 is zero. (It's not volts, but full-range unitless values.)
If you use getFloatFrequencyData, the values returned are in dB; if you use the Byte version, the values are mapped based on minDecibels/maxDecibels (see the minDecibels/maxDecibels description).
Mozilla 's documentation describes the difference between getFloatTimeDomainData and getFloatFrequencyData, which I summarize below. Mozilla docs reference the Web Audio
experiment ; the voice-change-o-matic. The voice-change-o-matic illustrates the conceptual difference to me (it only works in my Firefox browser; it does not work in my Chrome browser).
TimeDomain/getFloatTimeDomainData
TimeDomain functions are over some span of time.
We often visualize TimeDomain data using oscilloscopes.
In other words:
we visualize TimeDomain data with a line chart,
where the x-axis (aka the "original domain") is time
and the y axis is a measure of a signal (aka the "amplitude").
Change the voice-change-o-matic "visualizer setting" to Sinewave to
see getFloatTimeDomainData(...)
Frequency/getFloatFrequencyData
Frequency functions (GetByteFrequencyData) are at a point in time; i.e. right now; "the current frequency data"
We sometimes see these in mp3 players/ "winamp bargraph style" music players (aka "equalizer" visualizations).
In other words:
we visualize Frequency data with a bar graph
where the x-axis (aka "domain") are frequencies or frequency bands
and the y-axis is the strength of each frequency band
Change the voice-change-o-matic "visualizer setting" to Frequency bars to see getFloatFrequencyData(...)
Fourier Transform (aka Fast Fourier Transform/FFT)
Another way to think about "time domain vs frequency" is shown the diagram below, from Fast Fourier Transform wikipedia
getFloatTimeDomainData gives you the chart on on the top (x-axis is Time)
getFloatFrequencyData gives you the chart on the bottom (x-axis is Frequency)
a Fast Fourier Transform (FFT) converts the Time Domain data into Frequency data, in other words, FFT converts the first chart to the second chart.
cwilso has it backwards.
the time data array is the longer one (fftSize), and the frequency data array is the shorter one (half that, frequencyBinCount).
fftSize of 2048 at the usual sample rate of 44.1kHz means each sample has 1/44100 duration, you have 2048 samples at hand, and thus are covering a duration of 2048/44100 seconds, which 46 milliseconds, not 23 milliseconds. The frequencyBinCount is indeed 1024, but that refers to the frequency domain (as the name suggests), not the time domain, and it the computation 1024/44100, in this context, is about as meaningful as adding your birth date to the fftSize.
A little math illustrating what's happening: Fourier transform is a 'vector space isomorphism', that is, a mapping going bijectively (i.e., reversible) between 2 vector spaces of the same dimension; the 'time domain' and the 'frequency domain.' The vector space dimension we have here (in both cases) is fftSize.
So where does the 'half' come from? The frequency domain coefficients 'count double'. Either because they 'actually are' complex numbers, or because you have the 'sin' and the 'cos' flavor. Or, because you have a 'magnitude' and a 'phase', which you'll understand if you know how complex numbers work. (Those are 3 ways to say the same in a different jargon, so to speak.)
I don't know why the API only gives us half of the relevant numbers when it comes to frequency - I can only guess. And my guess is that those are the 'magnitude' numbers, and the 'phase' numbers are thrown out. The reason that this is my guess is that in applications, magnitude is far more important than phase. Still, I'm quite surprised that the API throws out information, and I'd be glad if some expert who actually knows (and isn't guessing) can confirm that it's indeed the magnitude. Or - even better (I love to learn) - correct me.