26

Your implementation is going to be slow, and the excuse "I need it to take a fixed amount of time" does not justify this. Using plain tables smells like cargo culting as well. So I'm not tackling what you did wrong in your code, but what you did wrong in even thinking about your implementation. First, google how to implement cosine on a micro ...


19

Putting this through the built-in profiler reveals some hot spots. Perhaps surprisingly: ReverseBits. It's not the biggest thing in the list, but it is significant while it shouldn't be. You could use one of the many alternate ways to implement ReverseBits, or the sequence of bit-reversed indexes (which does not require reversing all the indexes), or the ...


14

Indent your loop bodies. Actually check ret - you're uselessly assigning and discarding it every time. Use better variable names: avoid single letters (Y, k, l) and generic names (index) It appears all the work of your code is inside four nested loops: Try to vectorise - rewrite the inner block to operate on muliple pixels/components/chromas simultaneously. ...


10

Here's what I tested. I took out the classmethod stuff to make it easier to read, and simplified names a bit. I'll defer judgement on whether that stuff is needed as part of a larger package or not. My h5py is installed with Python3, so I had to change the handling of types. Use of isinstance is, I think a preferred testing tool, but I it's not something ...


9

I'll add my small contribution even though I'm not really a Python developer (hopefully some day). I've taken your update method and tested it on my computer (desktop, i3-4360@ 3.70GHz × 4 ), without the SDR bit. And my intuition was right! Like in most languages allowing you to do it, don't ever do that: self.fft_data = np.append(self.fft_data, self....


8

These lines: size_t N_stage = static_cast<size_t>(std::pow(2, stage)); size_t W_offset = static_cast<size_t>(std::pow(2, stages - stage)); should not use floating-point math because they can be inaccurate. Instead use pure integer arithmetic: size_t N_stage = static_cast<size_t>(1) << stage; size_t W_offset = static_cast<size_t&...


7

As David Morris indicates, it might be simpler to use a filtering/smoothing function, such as a moving window average. This is pretty simple to implement using the rolling function from pandas.Series. (Only 501 points are shown.) Tweak the numerical argument (window size) to get different amounts of smoothing. import pandas as pd import matplotlib.pyplot as ...


7

I think your code is doing DFT (Discrete Fourier Transform) and not FFT. You are doing \$O(n^{2})\$ operations in the 2 for loops. The FFT is supposed to be \$n*\log(n)\$. First thing to do is remove repeated multiplications. The terms Double(n)*2*M_PI/Double(N) can be calculated (as initial step) for every \$n\$ in \$0:(N-1)\$. Make a map for each \$n\$ ...


7

Your code shouldn't work: You are calculating: $$\int_a^b f(t) \, g(t - \tau) \; d\tau$$ but convolution is defined as: $$f(t) \, * \, g(t) \equiv \int_{-\infty}^{\infty} f(\tau) \, g(t - \tau) \; d\tau$$ so the default limits of integration should be \$-\infty\$ to \$\infty\$. More importantly you should use the proper argument for f (the integration ...


7

Convolution Filter In CG this type of processing is call a convolution filter and there are many strategies used to handle edges As the previous answer points out for performance you are best to use typed arrays and avoid creating arrays for each cell you process. In your example for (let i = 1; i <= kernelSize; i++) { adjacentValues = adjacentValues....


7

Updated Code Review for 2020-12-30 Code Some of the original code review items have been addressed. Good work! Here are some remaining ideas: I assume your purpose here is to make the hilbert function faster, because you will call it multiple times. You've moved the FFT plan creation outside of hilbert, which is probably a huge speed increase. However, you ...


6

I do believe that the decorator way is the proper one. There are some tradeoff using it but you can easily overcome your main concern using functools.wraps: it will reuse the name, docstring and signature of the decorated function for the wrapper. The wrapper within the decorator should be aware of both M and sym; this is where things can get tricky ...


6

Few highlights: std::copy(std::begin(z), std::end(z), std::begin(zOut)); To copy input values to overwrite them is just a waste of time. You will overwrite them then you do not need to copy old values, use z instead of zOut inside loops. y.size() is possibly evaluated multiple times. It's a minor performance issue (and it may be inlined) but it depends on ...


6

Since you not only need adjacent values but also the number of adjacent cells, I do not think that there's a way to work around conditions that cover the corner cases. However, you can make a case differentiation between border cells and inner cells and use two seperate code paths for it. One with and the other without if conditions. If accuracy at the ...


6

counting flops Let's unpack the inner loop, where all the work is being done. I am repeating the whole thing here, wrapping to 80 columns and adding some indentation to make it easier to read. double value = sin(phase) * pGain->GetProcessedVoiceValue(voiceIndex, sampleIndex); *left++ += value; *right++ += value; // next phase phase += BOUNDED( ...


6

I would like to share some observations about your main concerns given at the end of the question. Let's start from the back: 5. extend_col/reduce_row From what I can see, the "trick" here is to bring the points into a homogenous coordinate system and back. Therefore, I would propose to change the name of both functions to to_homogeneous and ...


5

Performance I cannot offer any mayor improvements, just some small things: You should save results of a calculation or action instead of doing them over and over. For example: 2*FastMath.PI: this is not dependent on the loop variables, just save it in a variable (same goes for 2*sigmaSqr.get(j).get(k) which you are doing three times for every loop; and ...


5

UPPERCASE for constants As a convention, in Python constants are uppercase: OLY_PATH = "/home/will/Desktop/soundfiles/Olympus Recordings" TITAN_PATH = "/home/will/Desktop/soundfiles/TITAN Recordings" WAV_ROOTS = [oly_path, titan_path] DESTINATION_PATH = "/home/will/Desktop/soundfiles/output" TEEMP_WAV_PATH = "/home/will/Desktop/soundfiles/temp.wav" No ...


5

Currently you are calculating the mean each time in the loop, so that's slice + sum for each of the len(heightProfile) - smoothingInterval iterations. We can remove this by calculating the mean of first smoothingInterval items and then inside of the loop simply subtract current ith item from the sum of the previous mean and add (i + smoothingInterval)th item ...


5

Profile The first step of improving the performance is to profile it. I recommend running this using Xcode's profile option and see where the time is spent. I suspect (but don't know for sure) that it will be in the calls to sin() and cos(). Avoid Casts One thing that can slow down calculations is lots of casts between types. You're using k, n, and N as ...


5

Firstly, does the program give correct results? If so, how do you know? Without going into extensive unit testing, checking your results against a Matlab prototype/your Python implementation is probably good enough for now. I can't comment on the Gnuplot functions as I don't have it installed, also but some general C++ tips are... std::vectors are your ...


5

I see a number of things that may help you improve your program. Omit empty destructor The compiler will automatically generate a destructor that would, in this case be identical to the empty one your wrote. It's better to simply omit it and let the compiler do its thing. Cleanly separate interface and implementation In all, the files are fairly neatly ...


5

Don't define pi and twopi yourself. They should be available from math.h as M_PI and M_2_PI if you're in the GNU stack. Defining functions as inline is more or less useless. The compiler will do this (or not) as it sees fit, and generally knows better than you on when it's beneficial. GetMin() should be GetMin() const. Same for GetRange, ...


5

A few observations: s_t = np.zeros(n) and r_t = np.zeros(n) are more than you need. Since you don't actually use the array values but solely overwrite them, you can use np.empty here. You're doing quite a bit of redundant work in the for loop. When calculating s_t[i], numpy basically has to repeat all the computations it has already done for s_t[i-1]. If ...


5

Putting aside the matter of optimization for now: I have concerns about the numerical approach here. If this is written with a specific application in mind, and you can make certain assumptions about your data, you might be fine; but if this is to be applied generally there are certain cases that are going to give you a lot of trouble. I suspect that the ...


5

#define PI 3.14... could use a few more digits! sine should work for numbers greater than 2.0 * PI. sine should work for negative numbers. same for cosine. if(temp > 2*PI) { temp -= 2*PI; } is ineffective for numbers greater than 4.0 * PI. if(rem > 0){ // sine value for given argument isn't directly in the lut if(index == (TABLE_SIZE-1)){ ...


5

One remark is that you should get rid of all the needless branching and code repetition. It's bad for performance and code maintenance both. Given an angle you should be able to: Take it's absolute value. Divide by PI/2. Convert to unsigned integer, truncating decimals. Then you'll either have an index from 0 to 3 or you started with an angle larger than 2*...


4

Avoid recomputations You compute the energy accumulated in a sliding window. When a window slides by 1, one sample shifts out, and one sample shifts in. The accumulated energy changes by s[n]^2 - s[n-40]^2. Therefore the inner loop is superficial. This alone will give you a 40-fold improvement. Quadratic complexity mysignal is only getting more signals ...


4

PEP394 First #!bin/usr/python should be #!/bin/usr/python2. This is as you should state the version of python that it works on. python = Python2 and Python3 python2 = Python2 python3 = Python3 This is as Arch Linux changed python to python3, not python2. PEP8 Two spaces between module level functions and classes. One space between methods. Classes are ...


Only top voted, non community-wiki answers of a minimum length are eligible