Access Struct Array Data in Arduino - c++

I'm struggling to create and access data stored in a struct array on my Arduino Uno.
I'm not too familiar with C++/Arduino but in my head the below should work.
The lights and stuff all work with other code but does not work when trying to change the light with light[i].
Might be something to do with pointers but i'm still unsure of when/where to use them.
struct light
{
byte k;
byte r;
byte g;
byte b;
};
typedef struct light Light;
Light l1;
Light l2;
Light l3;
Light lights[3] = {l1, l2, l3};
void setup() {
l1 = {0, 0, 0, 0};
l2 = {0, 0, 0, 0};
l3 = {0, 0, 0, 0};
}
void loop()
{
l1 = {0, 0, 0, 0};
l2 = {0, 0, 0, 0};
l3 = {0, 0, 0, 0};
//turn on different light every 3 seconds
int i;
if (millis() % 9000 < 3000) {
i = 0;
} else if ((millis() % 9000 >= 3000) && (millis() % 9000 < 6000)) {
i = 1;
} else {
i = 2;
}
lights[i] = {255, 255,0, 0};
// if this is uncommented l1 turns red
//l1 = {255,255,0,0}
//passes light data to DMX controller (works fine)
~turnOnlight(l1)
~turnOnLight(l2)
~turnOnLight(l3)
}
thanks in advance.

You probably want your array to point to respective lights, then you would need Light* lights[3] = {&l1,&l2, &l3} and when accesing the array member you have to dereference the pointer like this *lights[i] = {255, 255,0, 0};

Related

Using a Vector to fill up array of Class object - DMX Fixture Profile

Im writing a program to control different lights with DMX protocol. Each light has different channels to control different aspects (like Intensity, Color Temperature, colors etc.)
For that i want to create an easy way to put together a profile for each light.
This is what I came up so far. I'm working with an Arduino Due.
When I print out values after initialization, it just prints out 0 . Could somebody help me explain, what im doing wrong here? Or is there a better way to do this?
#include <vector>
struct Channel {
String name;
String unit;
int minValue;
int maxValue;
int color;
int dmxChannels;
int sliderChannels;
}; Channel AladdinBiColor[2], AladdinRGB[6];
class Profile {
public:
std::vector<Channel> channels;
int dmxChannels;
int sliderChannels;
String name[];
String unit[];
int minValue[];
int maxValue[];
int color[];
Profile(Channel* input, int count){
for (int i=0; i<count; i++){
channels.push_back(*input);
input++;
}
}
};
Profile AladdinBiColor_fixture(AladdinBiColor, 2);
Profile AladdinRGB_fixture(AladdinRGB, 6);
in Setup I call this function:
void setup(){
void initializeProfiles();
Serial.println(AladdinBiColor_fixture.channels[0].maxValue);
}
this prints out 0
which looks like this. It initializes the array.
void initializeProfiles(){
AladdinBiColor[0] = {"INT","%", 0, 100, WHITE,2,2};
AladdinBiColor[1] = {"INT","%", 0, 100, WHITE,2,2};
AladdinRGB[0] = {"INT","%", 0, 100, WHITE,2,2};
AladdinRGB[1] = {"INT","%", 0, 100, WHITE,2,2};
AladdinRGB[2] = {"CF","%", 0, 100, WHITE,2,2};
AladdinRGB[3] = {"RED","%", 0, 100, RED,2,2};
AladdinRGB[4] = {"GREEN","%", 0, 100, GREEN,2,2};
AladdinRGB[5] = {"BLUE","%", 0, 100, BLUE,2,2};
}
So the Problem was that the initialization took place after the Profile objects have been created. I rearranged the order and created an array which points to the objects of Profile so one can access it easily.
#include <vector>
struct Channel {
String name;
String unit;
int minValue;
int maxValue;
int color;
};
Channel AladdinBiColor[2] = {
{"INT","%", 0, 100, WHITE},
{"CCT","K", 0, 100, WHITE}
};
Channel AladdinRGB[6] = {
{"INT","%", 0, 100, WHITE},
{"CCT","K", 0, 100, WHITE},
{"CF","%", 0, 100, WHITE},
{"RED","%", 0, 100, RED},
{"GREEN","%", 0, 100, GREEN},
{"BLUE","%", 0, 100, BLUE}
};
class Profile {
public:
std::vector<Channel> channels;
int dmxChannels;
int sliderChannels;
Profile(Channel* input, int count, int dmxChannelsA){
for (int i=0; i<count; i++){
channels.push_back(*input);
input++;
}
dmxChannels = dmxChannelsA;
sliderChannels = count;
}
};
Profile AladdinBiColor_fixture(AladdinBiColor, 2,2);
Profile AladdinRGB_fixture(AladdinRGB, 6, 5);
Profile *lightProfiles[1][3] = { //index 1 = brand, index 2 = light
{&AladdinRGB_fixture, &AladdinBiColor_fixture, &AladdinRGB_fixture}
};
This way - in my main file - i can access the Profile objects with index numbers:
void setup(){
// first parameter of lightProfiles is the brand, second the light of it
Serial.println(lightProfiles[0][1]->channel[0].maxValue);
}

C++. Low level graphics. Polygon mesh data reading via classes. Need elaboration on the code of the constructor

I have been studying C++ and low-level graphics and currently have questions on this code from https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-polygon-mesh.
class PolygonMesh : public Object
{
public:
PolygonMesh(uint32_t nfaces, int *fi, int *vi, Vec3f *p) :
numFaces(nf), faceIndex(NULL), vertexIndex(NULL), P(NULL)
{
// compute vertArraySize and maxVertexIndex
uint32_t vertArraySize = 0;
uint32_t maxVertexIndex = 0, index = 0;
for (uint32_t i = 0; i < numFaces; ++i) {
vertArraySize += nv[i];
for (uint32_t j = 0; j < fi[i]; ++j)
if (vi[index + j] > maxVertexIndex)
maxVertexIndex = vi[index + j];
index += fi[i];
}
maxVertexIndex += 1;
pts = std::unique_ptr<Vec3f []>(new point[maxVertexIndex]);
for (uint32_t i = 0; i < maxVertexIndex; ++i) P[i] = p[i];
vertexIndex = std::unique_ptr<uint32_t []>(new int[maxVertexIndex]);
for (uint32_t i = 0; i < maxVertexIndex; ++i) vertexIndex [i] = vi[i];
faceIndex = std::unique_ptr<uint32_t>(new int[numFaces]);
for (uint32_t i = 0; i < numFaces; ++i) faceIndex[i] = fi[i];
};
~PolygonMesh() { /* release memory */ ... }
bool intersect(...) const { ... }
void getSurfaceData(...) const { ... }
uint32_t numFaces; //number of faces
std::unique_ptr<uint32_t []> faceIndex; //face index
std::unique_ptr<uint32_t []> vertexIndex; //vertex index
std::unique_ptr<Vec3f []> P;
};
int main(...)
{
...
uint32_t numFaces = 2;
uint32_t faceIndex[2] = {4, 4};
uint32_t vertexIndex[8] = {0, 1, 2, 3, 0, 3, 4, 5};
Vec3f P[6] = {
Vec3f (-5, -5, 5), Vec3f ( 5, -5, 5),
Vec3f ( 5, -5, -5), Vec3f (-5, -5, -5),
Vec3f (-5, 5, -5), Vec3f (-5, 5, 5),
};
PolygonMesh *mesh = new PolygonMesh(numFaces, faceIndex, vertexIndex, P);
...
}
The website (the author) says :
The point list, face and vertex index array are passed to the constructor of the MeshPolygon class as well as the number of faces. However we don't know how many points are in the point array. To find out, we look for the vertex with the maximum index value in the vertex index array (lines 13-14). The first element of an array in C++ start at 0, therefore the total number of vertices in the point list is the maximum index value plus 1 (line 17).
So, it is about getting data from polygon mesh! Several questions puzzle me :
Above it says, "...we don't know how many points are in the point array..." In my understanding, why just not read the size of the P array that is being passed from the main() ? That is supposed to be the size of the array, or...?
If my understanding correct, then in the PolygonMesh(..) constructor what happens is deep copying of pointers(and all the values those addresses' possess) ? Is it right? I am asking , because I have just learned( or read) recently about smart pointers, std::move and r-values references. Also, in the code, they don't std::move all the pointers from main to the class object because we want to save those original data (pointers), right?
Is it correct that in order to find Vertex Array Size in the above code for the class object, we could just read the maximum value of uint32_t vertexIndex[8], i.e maximum vertexIndexArray is the total number of vertices?
I assume in line 11 it must be vertIndexArraySize += fi[i]; instead of vertArraySize += nv[i]; because I have no idea where does nv come from what what it means...
Thank you all for your genuine help !

I'm trying to parallelize rat maze problem using openmp but it is taking too much time can anyone help me?

The above parallelize code is taking much more time as compare to the original one. I have used bfs approach to solve the problem. I am getting the correct output but it is taking too much time.
(x, y) represents matrix cell coordinates, and
dist represents their minimum distance from the source
struct Node
{
int x, y, dist;
};
\\Below arrays detail all four possible movements from a cell
int row[] = { -1, 0, 0, 1 };
int col[] = { 0, -1, 1, 0 };
Function to check if it is possible to go to position (row, col)
from the current position. The function returns false if (row, col)
is not a valid position or has a value 0 or already visited.
bool isValid(vector<vector<int>> const &mat, vector<vector<bool>> &visited, int row, int col)
{
return (row >= 0 && row < mat.size()) && (col >= 0 && col < mat[0].size())
&& mat[row][col] && !visited[row][col];
}
Find the shortest possible route in a matrix mat from source
cell (i, j) to destination cell (x, y)
int findShortestPathLength(vector<vector<int>> const &mat, pair<int, int> &src,
pair<int, int> &dest)
{
if (mat.size() == 0 || mat[src.first][src.second] == 0 ||
mat[dest.first][dest.second] == 0) {
return -1;
}
// `M × N` matrix
int M = mat.size();
int N = mat[0].size();
// construct a `M × N` matrix to keep track of visited cells
vector<vector<bool>> visited;
visited.resize(M, vector<bool>(N));
// create an empty queue
queue<Node> q;
// get source cell (i, j)
int i = src.first;
int j = src.second;
// mark the source cell as visited and enqueue the source node
visited[i][j] = true;
q.push({i, j, 0});
// stores length of the longest path from source to destination
int min_dist = INT_MAX;
// loop till queue is empty
while (!q.empty())
{
// dequeue front node and process it
Node node = q.front();
q.pop();
// (i, j) represents a current cell, and `dist` stores its
// minimum distance from the source
int i = node.x, j = node.y, dist = node.dist;
// if the destination is found, update `min_dist` and stop
if (i == dest.first && j == dest.second)
{
min_dist = dist;
break;
}
// check for all four possible movements from the current cell
// and enqueue each valid movement
#pragma omp parallel for
for (int k = 0; k < 4; k++)
{
// check if it is possible to go to position
// (i + row[k], j + col[k]) from current position
#pragma omp task shared(i,visited,j)
{
if (isValid(mat, visited, i + row[k], j + col[k]))
{
// mark next cell as visited and enqueue it
visited[i + row[k]][j + col[k]] = true;
q.push({ i + row[k], j + col[k], dist + 1 });
}
}
}
}
if (min_dist != INT_MAX) {
return min_dist;
}
return -1;
}
main part of the code only contains a matrix and source and destination coordinates
int main()
{
vector<vector<int>> mat =
{
{ 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 },
{ 0, 1, 1, 1, 1, 1, 0, 1, 0, 1 },
{ 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 },
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 0, 1, 1, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 },
{ 0, 0, 1, 0, 0, 1, 1, 0, 0, 1 },
};
pair<int, int> src = make_pair(0, 0);
pair<int, int> dest = make_pair(7, 5);
int min_dist = findShortestPathLength(mat, src, dest);
if (min_dist != -1)
{
cout << min_dist<<endl;
}
else {
cout << "Destination cannot be reached from a given source"<<endl;
}
return 0;
}
I have used shared variable but it is taking too much time.
Can anyone help me?
As people have remarked, you only get parallelism over the 4 directions; a better approach is to keep a set of sets of points: first the starting point, then all points you can reach from there in 1 step, then the ones you can reach in two steps.
With this approach you get more parallelism: you're building what's known as a "wave front" and all the points can be tackled simultaneously.
auto last_level = reachable.back();
vector<int> newly_reachable;
for ( auto n : last_level ) {
const auto& row = graph.row(n);
for ( auto j : row ) {
if ( not reachable.has(j)
and not any_of
( newly_reachable.begin(),newly_reachable.end(),
[j] (int i) { return i==j; } ) )
newly_reachable.push_back(j);
}
}
if (newly_reachable.size()>0)
reachable.push_back(newly_reachable);
(I have written this for a general DAG; writing your maze as a DAG is an exercise for the reader.)
However, this approach still has big problems: if two points on the current wave front decide to add the same new point, you have to resolve that.
For a very parallel approach you need to abandon the "push" model of adding new points altogether, and to go a "pull" model: in every "distance" iteration you loop over all points and ask, if I am not reachable, was one of my neighbors reachable? If so, mark me as reachable in one step more than that neighbor.
If you think about that last approach for a second (or two) you'll see that you are essentially doing a sequence of matrix-vector products, with the adjacency matrix and the currently reachable set. Except that you replace the scalar "+" operation by "min" and the scalar "*" by "+1". Read any tutorial about the interpretation of graph operations as linear algebra. Except that it's not really linear.

Not declared in this scope - Arduino

I'm having a problem when I try this code I've made:
int ledStart = 30;
boolean commonHigh = true;
void setup() {
Serial.begin(115200);
SetTimer(0, 0, 10); // 10 seconds
StartTimer();
for (int i =0;i<9;++i) {
pinMode (i, OUTPUT);
}
pinMode(9, INPUT);
}
int counter = 0;
bool go_by_switch = true;
int last_input_value = LOW;
void loop() {
// put your main code here, to run repeatedly:
number++;
delay(1000);
if(number>9)
number=0; // If number is bigger than 9, then number is 0
}
// 0 6
// pins A B C D E F G
int ledpins[] = {12, 10, 7, 4, 2, 13, 8};
int pincnt = 7;
int number = 0;
int sevenseg[10][7] = {
// A, B, C, D, E, F, G
{1, 1, 1, 1, 1, 1, 0}, // A-F shall light. G shall not light.
{0, 1, 1, 0, 0, 0, 0}, // A shall not light. B and C shall light.
/*0*/
/*1*/
/*2*/
/*3*/
/*4*/
/*5*/
/*6*/
/*7*/
/*8*/
{1, 1, 1, 1, 1, 1, 1, 1}
if(go_by_switch) {
int switch_input_value = digitalRead(9);
if(last_input_value == LOW && switch_input_value == HIGH) {
counter = (counter + 1) % 10;
}
last_input_value = switch_input_value;
}
else {
delay(500);
counter = (counter + 1) % 10;
}
writeNumber(counter);
}
for (int p=0; p<pincnt; p++) {
pinMode (ledpins[P], OUTPUT);
//It will count from 0 to smaller than 7. {12, 10, 7, 4, 2, 13, 8}; It will count from 0 to smaller than 7.
// 0 1 2 3 4 5 6
digitalWrite(ledpins[P], LOW);
}
for (int x=0; x<pincnt; x++); { //x is smaller than 7. The point is to bring out one of the patterns that will show on the display
if (sevenseg[number][x]) // sevenseg = 7-segment display
digitalWrite (ledpins[x], HIGH); // If it is 1, then there will be light.
else
digitalWrite (ledpins[x], LOW); // If it is 0, then there will not be light.
// A
//F B
// G
//E C
// D
The error message I get is:
_28.10.2015.ino: In function 'void setup()':
_28.10.2015.ino:7:20: error: 'SetTimer' was not declared in this scope
_28.10.2015.ino:8:14: error: 'StartTimer' was not declared in this scope
_28.10.2015.ino: In function 'void loop()':
_28.10.2015.ino:22:1: error: 'number' was not declared in this scope
_28.10.2015.ino: At global scope:
_28.10.2015.ino:52:1: error: expected '}' before 'if'
_28.10.2015.ino:52:1: error: too many initializers for 'int [7]'
_28.10.2015.ino:52:1: error: expected ',' or ';' before 'if'
Feil ved kompilering.
(Feil ved kompilering=Errors at compile(Norwegian)
The problem is that you are not declaring these functions that you are getting errors, neither the "number" variable.
You need to declare them, like:
int number;
void StartTimer( )
{
// function code;
}
Or include a ".h" that contain these functions, like #Neil Locketz said.
There are quite a few issues with this code.
One of the first things that I notice is that you close out your loop() function with }, then you proceed to write more code that doesn't belong to any function at all.
Also, as #Raul points out, you define an array sevenseg[][], but you do not end the statement with a semicolon.
Your last for() loop is missing its closing brace, }.
Your last for() loop has a semicolon before the opening brace. It shouldn't be there.
You use the variable number in your loop() function, but you define what number is after you use it. You have to define a variable before you use it.
You call SetTimer() and StartTimer() in your setup() function, but those functions are not defined. That's because either 1, you have not included the library where those functions are defined or 2, you did not define those functions yourself. If your issue is 1, then I assume you intended to use #include <SimpleTimer.h>. Note that you also have to install that library. The instructions on how to download it and add it to your Arduino libraries are here. Finally, you have to create a timer object like this: SimpleTimer timer; and then you can call the function like this, timer.SetTimer(your-parameters-here);.
There are probably other things that I have missed, but that should give you a starting point. It looks like you have created a lot of code without testing to see if any of it worked. I would recommend taking this a step at a time... code one logical block and see if it works before you move on to coding your next idea. It may seem like it takes more time but, in the end, it is usually a much faster way to program.
Another suggestion that I would make is to define variables within the function in which you use them. Making all of your variables "global" like you have done is not a good way to write code. For example:
void loop()
{
static int number = 0;
number++;
delay(1000);
if (number > 9)
{
number = 0;
}
}
Note the use of the keyword static. This will ensure that the value stored in number will not go away when the function ends. In other words, the value will still be there the next time the loop() function is called.
Finally, if I had to guess at what you were trying to accomplish, I would think your code should look a little more like this. It appears as though you were trying out different things so I left a number of code snippets in there from your original code that don't actually do anything:
void setup() {
Serial.begin(115200);
for (int i = 0; i < 9; ++i)
{
pinMode (i, OUTPUT);
}
pinMode(9, INPUT);
}
void loop() {
static int counter = 0;
static int last_input_value = LOW;
static bool go_by_switch = true;
if(go_by_switch)
{
int switch_input_value = digitalRead(9);
if(last_input_value == LOW && switch_input_value == HIGH)
{
counter = (counter + 1) % 10;
}
last_input_value = switch_input_value;
}
else
{
delay(500);
counter = (counter + 1) % 10;
}
writeNumber(counter);
}
void writeNumber (int count)
{
#define PIN_COUNT 7
#define NUM_OF_SEGMENTS 7
#define NUM_OF_NUMBERS 10
// 0 6
// pins A B C D E F G
static const int ledpins[PIN_COUNT] = {12, 10, 7, 4, 2, 13, 8};
static const int sevenseg[NUM_OF_NUMBERS][NUM_OF_SEGMENTS] =
{
// A B C D E F G
{1, 1, 1, 1, 1, 1, 0}, //0
{0, 1, 1, 0, 0, 0, 0}, //1
{1, 1, 0, 1, 1, 0, 1}, //2
{1, 1, 1, 1, 0, 0, 1}, //3
{0, 1, 1, 0, 0, 1, 1}, //4
{1, 0, 1, 1, 0, 1, 1}, //5
{1, 0, 1, 1, 1, 1, 1}, //6
{1, 1, 1, 0, 0, 0, 0}, //7
{1, 1, 1, 1, 1, 1, 1}, //8
{1, 1, 1, 1, 0, 1, 1}, //9
};
static int number = 0;
int i;
number++;
delay(1000);
if(number >= NUM_OF_NUMBERS)
{
number = 0;
}
/* Clear all segments of the 7-segment display. */
for (i = 0; i < PIN_COUNT; i++)
{
pinMode (ledpins[i], OUTPUT);
digitalWrite(ledpins[i], LOW);
}
/* Set the 7-segment display with the current number. */
for (i = 0; i < PIN_COUNT; i++)
{
if (sevenseg[number][i]) // sevenseg = 7-segment display
digitalWrite (ledpins[i], HIGH); // If it is 1, then there will be light.
else
digitalWrite (ledpins[i], LOW); // If it is 0, then there will not be light.
}
}

inverse fft of fft not returning expected data

I'm trying to make sure FFTW does what I think it should do, but am having problems. I'm using OpenCV's cv::Mat. I made a test program that, given a Mat f, computes ifft(fft(f)) and compares the result to f. I would expect the difference between the two to be negligible, but there's a strange pattern in the data..
In this case, f is initialized to be an 8x8 array of floats with positive values less than 1.
Here's my test program code:
Mat f = .. //populate f
if (f.type() != CV_32FC1)
DLOG << "Bad f type";
const int y = f.rows;
const int x = f.cols;
double* input = fftw_alloc_real(y * 2*(x/2 + 1));
// forward fft
fftw_plan plan = fftw_plan_dft_r2c_2d(x, y, input, (fftw_complex*)input, FFTW_MEASURE);
// inverse fft
fftw_plan iplan = fftw_plan_dft_c2r_2d(x, y, (fftw_complex*)input, input, FFTW_MEASURE);
// populate fftw data from f
for (int yi = 0; yi < y; ++yi)
{
const float* yptr = f.ptr<float>(yi);
for (int xi = 0; xi < x; ++xi)
input[yi*x + xi] = (double)yptr[xi];
}
fftw_execute(plan);
fftw_execute(iplan);
// put data into another cv::Mat for comparison
Mat check(y, x, f.type());
for (int yi = 0; yi < y; ++yi)
{
float* yptr = check.ptr<float>(yi);
for (int xi = 0; xi < x ; ++xi)
yptr[xi] = (float)input[yi*x + xi];
}
DLOG << Util::summary(f, "f");
DLOG << f;
DLOG << Util::summary(check, "check");
DLOG << check;
Mat diff = f*x*y - check;
DLOG << Util::summary(diff, "diff");
DLOG << diff;
Where DLOG is my logger and Util::summary(cv::Mat m) just prints passed string and the dimensions, channels, min, and max of the mat.
Here's what the data looks like (output):
f: rows:8 cols:8 chans:1 min:0.00257996 max:0.4
[0.050668437, 0.04509116, 0.033668514, 0.10986148, 0.12855141, 0.048241843, 0.12613985,.09731093;
0.028602425, 0.0092236707, 0.037089188, 0.118964, 0.075040311, 0.40000001, 0.11959606, 0.071930833;
0.0025799556, 0.051522054, 0.22233701, 0.052993439, 0.032000393, 0.12673819, 0.015244827, 0.044803992;
0.13946071, 0.019708242, 0.0112687, 0.047459811, 0.019342113, 0.030085485, 0.018739942, 0.0098618753;
0.041809395, 0.029681522, 0.026837418, 0.16038358, 0.29034778, 0.17247421, 0.1789207, 0.042179305;
0.025630442, 0.017192598, 0.060540862, 0.1854037, 0.21287154, 0.04813192, 0.042614728, 0.034764063;
0.0030835248, 0.018511582, 0.0071733585, 0.017076733, 0.064545207, 0.0026390438, 0.088922881, 0.045725599;
0.12798512, 0.23215951, 0.027465452, 0.03174505, 0.04352935, 0.025079668, 0.044403922, 0.035459157]
check: rows:8 cols:8 chans:1 min:-3.26489 max:25.6
[3.24278, 2.8858342, 2.1547849, 7.0311346, 8.2272902, 3.0874779, 8.0729504, 6.2278996;
0.30818239, 0, 2.373708, 7.6136961, 4.8025799, 25.6, 7.6541481, 4.6035733;
0.16511716, 3.2974114, -3.2648909, 0, 2.0480251, 8.1112442, 0.97566891, 2.8674555;
8.9254856, 1.2613275, 0.72119683, 3.0374279, -0.32588482, 0, 1.1993563, 0.63116002;
2.6758013, 1.8996174, 1.7175947, 10.264549, 18.582258, 11.038349, 0.042666838, 0;
1.6403483, 1.1003263, 3.8746152, 11.865837, 13.623778, 3.0804429, 2.7273426, 2.2249;
0.44932228, 0, 0.45909494, 1.0929109, 4.1308932, 0.16889881, 5.6910644, 2.9264383;
8.1910477, 14.858209, -0.071794562, 0, 2.7858784, 1.6050987, 2.841851, 2.2693861]
diff: rows:8 cols:8 chans:1 min:-0.251977 max:17.4945
[0, 0, 0, 0, 0, 0, 0, 0;
1.5223728, 0.59031492, 0, 0, 0, 0, 0, 0;
0, 0, 17.494459, 3.3915801, 0, 0, 0, 0;
0, 0, 0, 0, 1.5637801, 1.9254711, 0, 0;
0, 0, 0, 0, 0, 0, 11.408258, 2.6994755;
0, 0, 0, 0, 0, 0, 0, 0;
-0.2519767, 1.1847413, 0, 0, 0, 0, 0, 0;
0, 0, 1.8295834, 2.0316832, 0, 0, 0, 0]
The difficult part for me is the nonzero entries in the diff matrix. I've accounted for the scaling FFTW does on the values and the padding needed to do an in-place fft on real data; what am I missing?
I find it surprising that the data could be off by a value of 17 (which is 66% of the max value), when there are so many zeros. Also, the data irregularities seem to form a diagonal pattern.
As you may have noticed when writting fftw_alloc_real(y * 2*(x/2 + 1)); fftw needs extra space in the x direction to store complex data. In your case, as x=8, it needs 2*(x/2+1)=10 reals.
http://www.fftw.org/doc/Real_002ddata-DFT-Array-Format.html#Real_002ddata-DFT-Array-Format
So...you should take care of this as you populate the input array or retreive values from it.
You way change
input[yi*x + xi] = (double)yptr[xi];
for
int xfft=2*(x/2 + 1);
...
input[yi*xfft + xi] = (double)yptr[xi];
And
yptr[xi] = (float)input[yi*x + xi];
for
yptr[xi] = (float)input[yi*xfft + xi];
It should solve your problem since the non-nul points in your diff correspond to the extra padding.
Bye,