1. Pre computed look up tables can be faster but there is always a trasde off between speed and memory usage. For 32 or 64 bit ints how big do thearray need to be?

For x = n1 * n2; there are 2 memory moves and the mult instruction.

Disregarding the table generation the lookup algorithm has 4 moves, 2 subtractions, and 1 addition. I haven’t figured out how to count instruction cycles with VS yet but I’d say it is not likely faster, but I could be wrong. Does two sub and 1 add execute faster than a mult?

And BTW a function call incurs a time penalty. It would be faster to make osq[n1 + n2] - osq[n1 – n2] a macro instead of a function.

#define BOUND 20000
void main() {
int a, b,c = 0,n1=21000,n2 = 21000,x;
for (a = 0; a < BOUND * 2; a++)osq[-a] = osq[a] = a * a / 4;
c = osq[n1 + n2] - osq[n1 - n2];
x = n1 * n2;
printf("n1 %d n2 %d x %d c %d \n", n1, n2, x,c);

}

c = osq[n1 + n2] - osq[n1 - n2];
005F5B32 mov eax,dword ptr [n1]
005F5B38 mov ecx,dword ptr [n1]
005F5B3B sub ecx,dword ptr [n2]
005F5B3E mov edx,dword ptr [eax*4+621240h]
005F5B45 sub edx,dword ptr [ecx*4+621240h]
005F5B4C mov dword ptr [c],edx
x = n1 * n2;
005F5B4F mov eax,dword ptr [n1]
005F5B52 imul eax,dword ptr [n2]
005F5B56 mov dword ptr [x],eax  Reply With Quote

2. ttps://www.agner.org/optimize/instruction_tables.pdf
https://en.wikipedia.org/wiki/Cycles_per_instruction

Looking at the lateness for imult, mov, add, and sub I'd say at best it is a wash. The additional moves and adds/subtracts offset the imult latency.  Reply With Quote

3. Is there any reaso why anyone would use FORTRAN instead of C?

Apparently it is active, Intel offers a comiler.  Reply With Quote

4. What keeps Fortran going?
• High-performanice number crunching.
• A big existing codebase. Much like what keeps COBOL alive.

However, Fortran doesn't work well with more recent programming languages, and I've found tools to convert Fortran code to C and C++:  Reply With Quote

5. Originally Posted by steve_bank Is there any reaso why anyone would use FORTRAN instead of C?

Apparently it is active, Intel offers a comiler.
A former workmate of mine was using Fortran at uni, around about 2018, as part of his civil engineering undergraduate studies. Apparently it was to create simulations that run on a supercomputer.

I'm not sure if he actually had to write code - I forgot to ask - although I would assume that engineers have graphical programs for that sort of thing.  Reply With Quote

6. If anybody is interested...

I installed the Intel C++ compiler. It is command line and also integrates into VS C++. It comes with math, video processing, cryptography, an neural net toolkits/libraries. The math library looks comprehensive, that is what I was interested in.

Once installed you select Intel in the VS project options window.  Reply With Quote

7. The Discrete Fourier Trasform.

https://en.wikipedia.org/wiki/Discre...rier_transform

I coud not get the C++ complex number functions to work so I just summed the series terms as scalars. Not practical but a demo if yiu want to explore signal analysis.

If you run it a few things. It is a power of 2 algorith. If you run it on a ata set not exact power of 2 in length yiu can pad it with zeros.

Be nindful of aliasing. If signal is greater than sample frequency/2 it will show up at another frequncy line. You can demo it for yourself. You can substitude any signal for y[].

Real and imaginatru terms are summed and magnitue is foundby root sum square. Phase atan(inag/real);

The mag[] output is a mirror spectrum, so in display only use 0-N/2. The amplitude of the mirrored signal is 0.5 so to get te correct signal amplitude mag is multiplied by 2.

For signal plot y vs x, for spectrum mag vs f. You can vary transform time, sample frequency, and trasform size. The max time must be enough to accommodate the lowest frequncy cycle. Sample frequency must be 2 x highest frequency. For demo code is set so the signal length always equals the transform length.

I use memory allocatio on the heap for the arrays because the compiler can give warnings about running out of stack memory. Also the compiler will not allow variables for fixed array size.

You can change the output to csv and plot in a spreadsheet.

Run time

N--size ---Time
10 1024 - .2
11 2048 - .5
12 4096 - .8
13 8192 - 3
14 16384 - 10

class _sin {
public:
double DC = 0,fsig2 = 1, fsig1 = 1, fsamp = 1000, A2 = 2,A1 = 1, tmax = 1;
double *y, *x, *f;
int N = 1024;
void make_sin(void) {
// creates signal,
//frequency scale for DFT,
//and time scale for signal
int i;
double t = 0, dt, freq = 0, df;
df = fsamp / N;
dt = tmax / fsamp;
for (i = 0; i < N; i++) {
y[i] = A1 * sin(_PI2 * fsig1 * t) + DC;
y[i] = y[i] + (A2 * sin(_PI2 * fsig2 * t) + DC);
x[i] = t;
t += dt;
f[i] = freq;
freq += df;
}
}//make_sin()
};//_sin

class DFT{
public:
double *y, *mag, *ph;
int N;

void run_dft(void){
// real DFT
double C1,C2,C3, re, im;
int j, k;
C1 = _PI2 / N;
C3 = 2 / double(N);
for (j = 0; j < N; j++) {
re = 0;
im = 0;
for (k = 0; k < N; k++) {
C2 = double(j) * double(k) * C1;
re += (y[k] * cos(C2));
im += (y[k] * sin(C2));
}//for k
mag[j] = C3 * sqrt(pow(re, 2) + pow(im, 2));
ph[j] = atan(im / re);
}//for j
}//run_dft()
};//DFT

void save(double *ph,double *x,double *y,double * f, double *mag,int N){
int i;
ofstream magfile; ofstream sigfile;
sigfile.open("sig.txt");
magfile.open("mag.txt");
magfile << N << "\n"; //first line in data file is trasform size
sigfile << N << "\n";
for (i = 0; i < N; i++) {
sigfile << x[i] << setw(20) << y[i] << "\n";
magfile << f[i] << setw(20) << mag[i] << setw(20) << ph[i] << "\n";
}//for
sigfile.close();
magfile.close();

}//save()

int main(){
int i,N = pow(2,14); //power of 2 transform size
int g;
_sin s1; DFT dft;
double* y = new double[N];// signal
double* mag = new double[N]; // transform magnitude
double* f = new double[N]; // trasform frequenct scale
double* ph = new double[N];// transform phase
double* x = new double[N]; // signal time scale
s1.x = x; s1.y = y; s1.f = f;
s1.N = N; s1.fsamp = 1000;
s1.fsig1 = 172; s1.fsig2 = 200;
s1.A1 = 1; s1.A2 = 0;
s1.make_sin();
dft.N = N;
dft.y = y; dft.ph = ph; dft.mag = mag;
auto begin = std::chrono::high_resolution_clock::now();
dft.run_dft();
save(ph,x, y, f, mag, N);
}//main()  Reply With Quote

8. I don't know if it is in the C++standard, to ,easure execution time in VS C++

#include <chrono>
using namespace std::chrono;

auto _begin = std::chrono::high_resolution_clock::now();

code…

auto _end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanosecond s>(_end - _begin);
printf("Time measured: %.3f seconds.\n", elapsed.count() * 1e-9);  Reply With Quote

9. A simple spread sheet. Two arrays one for math strings one for numbers.

execstr() is a Scilab builtin that executse math strings.

clear
EQUATION = -1
for i = 1:4
for j = 1:4
n(i,j) = 0
s(i,j) = "x"
end
end
n(1,1) = 2
n(1,2) = 3
s(2,3) = " n(2,1) = n(1,1) + n(1,2)"
s(2,4) = "n(2,2) = sin(%pi/4)"
s(4.4) = " n(2,3) = n(2,1)*n(2,2)"

for i = 1:4
...for j = 1:4
.....if( strcmp(s(i,j) , "x") == EQUATION )
.....execstr(s(i,j))
.....end
....end
end
n=
2 3 0 0
5 .707 3.536 0
0 0 0 0  Reply With Quote

10. Random numbers with C rand()

rand() reurns a number from 0 to RAND_MAX defined in stdlib.h.

srand() seeds the generator. Inializing to the current seconds count on each call to rand_num() gives a degree of randomnes to the sequences.

The sequences are a uniform distrinution. The shift variable moves the sequence up or down. Adding a -sshift at half the max value cretes a distrtrbutin with a zero mean. dec_pt can create limited decimal
values.

Tested it by ciuntibg the occurences for random numbers 0 – 9.

#include<time.h>
void rand_num(double *r,int N,int sc,double dec_pt,double shift) {
cout << "RAND" << "\n";
int rn;
srand(unsigned int(time(NULL)));
for (int i = 0; i < N; i++) {
...rn = rand() % sc;
...r[i] = double(rn) / dec_pt + shift;
...}
}

int main() {
int cnt,N = 1000;
double* rnum = new double[N];

// N sequence 0-9
rand_num(rnum, N, 10, 1, 0);

for (int i = 0; i < 10; i++) {
...cnt[i] = 0;
...for (int j = 0; j < N; j++)
….. if (rnum[j] == double(i))cnt[i] += 1;
…...cout << i << " " << cnt[i] << "\n";
...}
}
delete[] rnum;
return(0);
}//main()  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•