Problem in arrays of complex numbers..

Greetings to all,,,
I am working with complex numbers in arduino and I have used many 2D arrays. The problem is that when I use the array of size 6x300 or 1x181 then my program is stuck ( not working) ,, for arrays of size 6x6 or 1x6 etc it work properly...What should i do?? I need many 2d arrays of complex number in my program of larger size.
I am using arduino board.. Would it work by using due or any other board???

A complex number is presumably 8 bytes (a float for real part and a float for imaginary part.)
An Arduino Uno only has 2kbytes of RAM, so you can only have about 200 imaginary numbers (you need some RAM for other things too.) a 6x300 array is out of the question (14k+ !); 1x181 is probably right on the edge...

Non-Uno Arduinos have more RAM. a "MEGA" has 8k, so your 1x181 array should be OK, but 6x300 is still not possible. Various atmega1284 boards have 16k, Zero has 32k, Due has 96k, Teensy 3.1 or 3.2 has 64k, various chipKit boards (use MPIDE) have 16k to 128k, TI Launchpads (use Energia) have 32k to 256k (and floating point hardware!)

If your complex arrays are constants, there are ways to stick them in flash rather than RAM, which would open up additional possibilities.

thnks @ westfw.
Basically i am trying to convert a matlab code into arduino , so what is the possibility for me to done my job… I has attached a sample file that show how am i using the complex nos, I only need 3 arrays of large size 2 of them are of size 6x300 and 1 is of size 1x181 all other arrays are of smaller size,

sketch_oct25a.ino (524 Bytes)

Ok - you are using the complex class.

Could you pls run this:

void setup() {
  Serial.begin(9600);
  while(!Serial);
  Serial.print("size of Complex class is ");
  Serial.print(sizeof(Complex));
  Serial.println("bytes.");
}

If it's bigger than it needs to be, you might need to make up your own complex data structure and writing some code to add/multiply (easiest way is to use a couple of static Complex objects to do it).

I only need 3 arrays of large size 2 of them are of size 6x300 and 1 is of size 1x181

That's at least 30k. Which means:

  1. You're pretty restricted in which arduino-like boards you'd be able to use.
  2. Using flash for constant arrays won't help you fit on an Uno-sized board, because it only has 32k of flash.
  3. your example didn't really show how you are "using" the complex numbers; I still couldn't tell whether "y" is constants or variables, for instance. (sure looks variable, though.)

If it were me, I'd throw a Raspberry Pi style board at the problem instead of an Arduino...

@ westfw i have attached complete code now …
Why if i used due board does it work, as i have less knowledge of raspberry pi,

sketch_oct17a.ino (6.2 KB)

Why if i used due board does it work,

Because the Due has a lot more RAM than AVR Arduinos

i have less knowledge of raspberry pi

The smallest Raspberry Pi has 256MB of RAM. About 1000x more than a large (and more expensive) Arduino like the Due... (athough, your application wouldn't get to use ALL of it...) Interacting with "real world" stuff would be somewhat (to "much") more difficult, though.

A Due might work. Where did you get "complex.h"? Compiling your example gives me "Complex is an unknown type" errors.

@westfw i got the the complex library from github,,,,, I have attached the library which i use,,,

Complex(Library files),

complex.cpp (5.87 KB)

complex.h (2.32 KB)

Recognized the code - Arduino/libraries/Complex at master · RobTillaart/Arduino · GitHub -

aghani05:
Greetings to all,,,
I am working with complex numbers in arduino and I have used many 2D arrays. The problem is that when I use the array of size 6x300 or 1x181 then my program is stuck ( not working) ,, for arrays of size 6x6 or 1x6 etc it work properly...What should i do?? I need many 2d arrays of complex number in my program of larger size.
I am using arduino board.. Would it work by using due or any other board???

You could write two wrappers that read/writes the numbers to / from an SD-card file.
Go for these signatures

bool readSD(filename, idx, &value);

bool writeSD(filename, idx, value);

Both return true if successful, idx needs to be calculated like idx = width * y + x;

The advantage of this approach is that you can support 1D, 2D and higher dimensional tables.

Next step would be a class that implements read/write. The class can buffer values e.g. a row to improve performance, keep the file open iso reopen every call, check the size of the dimensions, define the dimensions in the constructor etc

update: one could make a generic wrapper class that maps objects on the SD. Some additional params in the constructor and/or template class would do it.

I managed to compile your program for a Due, and by default it uses nearly 95k of RAM, so it probably won't run (as is) even on a Due. Sizeof(Complex) is 24 bytes; a double precision for each of Real and Imaginary parts, and ... I can't tell where the third float is :frowning: Changing all the occurrences of "double" to "float" halves the storage requirements, which should work on one of the ARMs with 64k+ of RAM (but not with only 32k.) (if that will be enough precision.)

@ westfw if it is not working on due board then what will be the solution for me ?? :confused: :frowning:

I dunno. I'm not a mind reader. It's not like your code has any comments explaining what it's actually doing, I don't immediately recognize the algorithm, and I don't know why you want to do this in an Arduino, and I can't suggest alternative approaches. If your problem really requires ~4000 complex numbers, then an Arduino is not a particularly good match for solving that problem. Arduino and MatLab are aimed at very different sorts of problems; you shouldn't really expect one to be able to everything that the other one can.

westfw:
I dunno. I’m not a mind reader. It’s not like your code has any comments explaining what it’s actually doing, I don’t immediately recognize the algorithm,

Oh, it’s some sort of fourier analysis. You can tell from the bit where he’s going e ^ (i * some_value * an_index): it’s a mathy way to get sine waves with frequencies that are multiples of some_value.

This is the kind of code that happens when you convert code from one language to the other without pausing to think about what the code is trying to do. You spend time trying to reimplement the idioms of the first language in the second.

I’m looking at the use of the variable ‘n’ in your setup. The sketch make a 600-element matrix, fills it with random numbers like so:

   for(j=0;j<=6;j++){
     for(k=0;k<=300;k++){
       randnumber=random(-3,3)-3/2.0f;   ///random number matrix
       n[j][k]=.1414*randnumber;
     }
   }

and the only thing it’s used for is this:

   for(int i=1; i<=6; i++)
   for(int j=1; j<=300; j++)
   y[i][j]=g[i][j]+n[i][j];      //y=g+n in  matlab

The reason its done this way is that in matlab, it’s very natural to say ‘make me a matrix of random numbers and subtract it from this other matrix’ (to introduce noise, I guess). But in C, the sketch has plonked 1200 bytes on the stack when this would have done exactly the same job:

   for(int i=1; i<=6; i++)
   for(int j=1; j<=300; j++)
   y[i][j]=g[i][j]+random(-3,3)-3/2.0f*.1414;

Matlab - and math, come to that - does its work by treating big, lumpy matrices as atomic things and doing operations on them. You’ll have to analyze your algoritm a little more carefully if you want it to work well in an arduino. If (say) A is the result of some calculation over of B and C, rather than doing that calculation and storing it in A, you might need to write a function that calculates Ai,j when its needed and you treat that function as if it were your matrix.

In computing, speed and space are always the tradeoff.

… reading further …

I mean - look at this:

  q[1][1]=c1;
   q[2][1]=c2;
   q[3][1]=c3;
   q[4][1]=c4;
   q[5][1]=c5;
   q[6][1]=c6;
   
   q11[1][1]=c1;
   q11[1][2]=c2;
   q11[1][3]=c3;
   q11[1][4]=c4;
   q11[1][5]=c5;
   q11[1][6]=c6;
   
     p1[1][1]=q11[1][1]*Rxx[1][1]+q11[1][2]*Rxx[2][1]+q11[1][3]*Rxx[3][1]+q11[1][4]*Rxx[4][1]+q11[1][5]*Rxx[5][1]+q11[1][6]*Rxx[6][1];
     p1[1][2]=q11[1][1]*Rxx[1][2]+q11[1][2]*Rxx[2][2]+q11[1][3]*Rxx[3][2]+q11[1][4]*Rxx[4][2]+q11[1][5]*Rxx[5][2]+q11[1][6]*Rxx[6][2];
     p1[1][3]=q11[1][1]*Rxx[1][3]+q11[1][2]*Rxx[2][3]+q11[1][3]*Rxx[3][3]+q11[1][4]*Rxx[4][3]+q11[1][5]*Rxx[5][3]+q11[1][6]*Rxx[6][3];
     p1[1][4]=q11[1][1]*Rxx[1][4]+q11[1][2]*Rxx[2][4]+q11[1][3]*Rxx[3][4]+q11[1][4]*Rxx[4][4]+q11[1][5]*Rxx[5][4]+q11[1][6]*Rxx[6][4];
     p1[1][5]=q11[1][1]*Rxx[1][5]+q11[1][2]*Rxx[2][5]+q11[1][3]*Rxx[3][5]+q11[1][4]*Rxx[4][5]+q11[1][5]*Rxx[5][5]+q11[1][6]*Rxx[6][5];
     p1[1][6]=q11[1][1]*Rxx[1][6]+q11[1][2]*Rxx[2][6]+q11[1][3]*Rxx[3][6]+q11[1][4]*Rxx[4][6]+q11[1][5]*Rxx[5][6]+q11[1][6]*Rxx[6][6];

Why are these values being jammed into q1 and q11? If you are not using a loop and expanding it out anyway - why not just use c1…c5? And why two matrixes, when they are just single-dimensional vectors? Because in Matlab, one is a covariant vector and one is contravariant. But this distinction only matters to matlab. More importantly, why are there six c variables rather than one array of c? Why use

        Complex c(0,1);

When any complex library will most certainly have 0+i as a named constant? That whole loop

   for(float t=-pi/2;t<=pi/2;t=t+ss_theta){

Is long because it’s stuffing values into arrays instead of calculating things as it needs them.

The real answer is: flatly translating this from matlab to C won’t work well. On the arduino, because resources are so tight the not-working-wellness of this method becomes a problem.

Judging from this line in the OP's code,

 float pi=3.14;

accuracy and precision are not very important.

thanks @PaulMrrayCbr for analyzing my code and for giving me suggestions in order to solve my problem,,,,, you really did a great job for me.... :slight_smile:

When any complex library will most certainly have 0+i as a named constant?

What should it be named?

I can add it easily to my library as a constant. - http://forum.arduino.cc/index.php?topic=96080.0 -

Now i rewrite my code and reduce the no of complex numbers as possible .But it’s still not working…
I have attached the updated code…

project_due.ino (6.33 KB)

when i am compiling this code now the msg displays after compiling is

“Sketch uses 33,644 bytes (6%) of program storage space. Maximum is 524,288 bytes.”

So if the sketch uses only 6% of total space then why it not run properly. And why does the IDE not display any msg regarding to memory shortage during compiling and uploading. The compiling is done well as well uploading is done well. Only when i open the serial monitor to show results, the results are not proper ,it looks like the program is stuck some where…