Two different outputs of the same array - arrays

I have a question about some odd behaviour with my program.
I have two arrays data and ind_array. Both arrays are initialized in main function. ind_array is filled with some values and data is filled with values using function loadData().
But output of the program depends on where I print values of data array. Before inputting values to ind_array or after.
Look at the first tree numbers of output.
Thanks in advance.
Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define FILE_NAME "DataValues.csv"
#define NUM_ROWS 40
#define NUM_COLUMS 2
#define COMA " ,"
void loadData(double (*data)[2]){
//double data[NUM_ROWS][NUM_COLUMS];
FILE* data_file = fopen(FILE_NAME, "r");
char line[NUM_ROWS];
int i = 0;
while(fgets(line, sizeof(line), data_file)){
char* tok = strtok(line, COMA);
int j = 0;
while(tok != NULL){
char *ptr;
data[i][j] = atof(tok); //const char to double
tok = strtok(NULL, COMA);
j++;
}
i++;
}
}
int main(){
double data[NUM_ROWS][NUM_COLUMS];
double ind_array[0][5];
loadData(data);
for(int j = 0; j < NUM_ROWS; j++){
printf(" %f\n", data[j][0]);
}
printf("\n");
ind_array[0][0] = 2;
ind_array[0][1] = 5;
ind_array[0][2] = 0;
ind_array[0][3] = 3;
ind_array[0][4] = 0;
for(int j = 0; j < NUM_ROWS; j++){
printf(" %f\n", data[j][0]);
}
return 0;
}
Output
1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000
9.000000 10.000000 11.000000 12.000000 13.000000 14.000000 15.000000
16.000000 17.000000 18.000000 19.000000 20.000000 21.000000 22.000000
23.000000 24.00000025.000000 26.000000 27.000000 28.000000 29.000000
30.000000 31.000000 32.000000 33.000000 34.000000 35.000000 36.000000
37.000000 38.000000 39.000000 40.000000
2.000000 0.000000 0.000000 4.000000 5.000000 6.000000 7.000000
8.000000 9.000000 10.000000 11.000000 12.000000 13.000000 14.000000
15.000000 16.000000 17.000000 18.000000 19.000000 20.000000 21.000000
22.000000 23.000000 24.000000 25.000000 26.000000 27.000000 28.000000
29.000000 30.000000 31.000000 32.000000 33.000000 34.000000 35.000000
36.000000 37.000000 38.000000 39.000000 40.000000

Well you are declaring a 0 X 5 array on this line:
double ind_array[0][5];
The total amount of cells in that array is 0 x 5 = 0. You are printing uninitialized memory which is undefined behaviour, switch the 0 for 1.

Related

Getting column data from file stream in C

I have a file which is written with a column of data (For example, "250\n 249\n...". Actually, there are 250 rows data with at most 15 digits in a row). I wish to get data from the different files and average them. However, I have no idea how could I get such a large amount of data with single column. I tried the following:
char str[80];\newline
FILE * abc;
abc=fopen("bromo.dat", "r");
fgets(str, 80, msd);
atof(str);
What I got was only the data from the first row. How could get the rest of the data?
You can use strtok to split the number in each line by space character. Then use the atof funcition as you used in your code to convert string to float number.
You should use 2D array to store all numbers in the file, and use another array to store the number in each line:
float number[250][15]; // maximum 250 line with at most 15 digits in each line
int number_each_line[250] = {0}; // the number of digits in each line
The complete program for test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[80];
float number[250][15];
int number_each_line[250] = {0};
FILE * fp;
fp =fopen("bromo.dat", "r");
if (!fp) {
return -1;
}
int i = 0;
while(fgets(str, 80, fp) && i < 250) {
int j = 0;
char *token = strtok(str, " ");
while(token != NULL) {
number[i][j] = atof(token);
j++;
token = strtok(NULL, " ");
}
number_each_line[i] = j;
i++;
}
// print first 10 lines in file
for(int k = 0; k < 10; k++) {
for(int j = 0; j < number_each_line[k]; j++) {
printf("%f ", number[k][j]);
}
printf("\n");
}
fclose(fp);
}
The output of test:
bromo.dat:
1.2 1 4 5
2.1 2 6 7 8
3.5 3 2 3 5.3
2.1 4 6 7 8
2.1 5 6 7 8
2.1 6 6 7 8
2.1 8 6 7 8
2.1 9 6 7 8
2.1 10 6 7 8
./test
1.200000 1.000000 4.000000 5.000000
2.100000 2.000000 6.000000 7.000000 8.000000
3.500000 3.000000 2.000000 3.000000 5.300000
2.100000 4.000000 6.000000 7.000000 8.000000
2.100000 5.000000 6.000000 7.000000 8.000000
2.100000 6.000000 6.000000 7.000000 8.000000
2.100000 8.000000 6.000000 7.000000 8.000000
2.100000 9.000000 6.000000 7.000000 8.000000
2.100000 10.000000 6.000000 7.000000 8.000000

SSE Matrix Multiplication NxN. Why is this error

I am beginner using SSE instructions, and I try to implement MMM. So, I implemented MMM using matriz 2by2, now I want to implement MMM using matrix NXN
#include <emmintrin.h>
#include <stdio.h>
#include <stdlib.h>
void simd_2x2(int lda, double *A, double *B, double *C)
{
__m128d a, b1, c1;
for (int k = 0; k < lda; k++) {
//printf("%f\n",C[k * lda]);
c1 = _mm_loadu_pd(C + k * lda); //load unaligned block in C
//c2 = _mm_loadu_pd(C + 1 * lda);
for (int i = 0; i < lda; ++i) {
a = _mm_load_pd(A + i * lda);//load aligned i-th column of A
b1 = _mm_load1_pd(B + i + k * lda); //load i-th row of B
//b2 = _mm_load1_pd(B + i + 1 * lda);
c1 = _mm_add_pd(c1, _mm_mul_pd(a, b1)); //rank-1 update
//c2 = _mm_add_pd(c2, _mm_mul_pd(a, b2));
}
_mm_storeu_pd(C + k * lda, c1); //store unaligned block in C
//_mm_storeu_pd(C + 1 * lda, c2);
}
}
int main() {
int n = 2;
double *buf = NULL;
buf = (double *)malloc(3 * n * n * sizeof(double));
double *A = buf + 0;
double *B = A + n * n;
double *C = B + n * n;
simd_2x2(n, A, B, C);
return 0;
}
When n=2 everything work fine:
A = 4.000000 3.000000
2.000000 4.000000
B = 1.000000 3.000000
2.000000 4.000000
C = 0.000000 0.000000
0.000000 0.000000
C = C + A * B = 10.000000 24.000000
10.000000 22.000000
but if n=4 I get the next:
A = 4.000000 0.000000 1.000000 4.000000
2.000000 1.000000 4.000000 0.000000
3.000000 1.000000 2.000000 1.000000
4.000000 1.000000 3.000000 1.000000
B = 1.000000 5.000000 9.000000 13.000000
2.000000 6.000000 10.000000 14.000000
3.000000 7.000000 11.000000 15.000000
4.000000 8.000000 12.000000 16.000000
C = 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
C = C + A * B = 23.000000 59.000000 95.000000 131.000000
16.000000 44.000000 72.000000 100.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
The last two rows are not calculated, why is this? Can someone help me?
I have almost 5 days reading about SSE but I can not fully understand and neither solve this problem.

Merge sorting a struct

#include<stdio.h>
#include<stdlib.h>
typedef struct points{
float axis[2];
int id;
}Points;
typedef enum{
SortById,
SortByXAxis
}SortType;
Points* fill_Array(char* filename, int* length);
void Print_set(Points* set, int number_of_points);
void mergesort(Points* set, int low, int high, int number_of_points,SortType sort);
void merge(Points* set, int low, int middle, int high, int number_of_points,SortType sort);
int main(int argc, char* argv[])
{
int length;
Points *array;
array=fill_Array(argv[1],&length);
Print_set(array,length);
printf("\n\n");
mergesort(array,0,length,length,SortById);
Print_set(array,length);
return 0;
}
Points* fill_Array(char* filename,int* length)
{
int i;
Points* array;
FILE* file=fopen(filename,"r");
if(file == NULL)
{
return NULL;
}
fscanf(file,"%d",length);
array=malloc(sizeof(Points)* *length);
for(i = 0; i < *length; i++)
{
fscanf(file,"%d %f %f", &(array+i)->id,&(array+i)->axis[0],&(array+i)->axis[1]);
}
fclose(file);
return array;
}
void Print_set(Points *set, int number_of_points)
{
int i;
for(i = 0; i < number_of_points; i++)
{
printf("%d %f %f\n",(set+i)->id,(set+i)->axis[0],(set+i)->axis[1]);
}
}
void mergesort(Points* set,int low,int high,int number_of_points, SortType sort)
{
int mid1;
if((high-low)>=1)
{
mid1 = (low+high)/2;
mergesort(set, low, mid1, number_of_points, sort);
mergesort(set, mid1+1, high, number_of_points, sort);
merge(set, low, mid1, high, number_of_points, sort);
}
}
void merge(Points* set, int low, int middle, int high, int number_of_points, SortType sort)
{
int leftIndex=low;
int rightIndex=middle;
int combinedIndex = low;
Points tempArray[number_of_points];
int i;
while(leftIndex <= middle && rightIndex<= high)
{
if(set[leftIndex].id <= set[rightIndex].id)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
else
tempArray[combinedIndex++] = set[rightIndex++];
}
if(leftIndex == middle+1)
{
while(rightIndex <= high)
{
tempArray[combinedIndex++] = set[rightIndex++];
}
}
else
{
while(leftIndex <= middle)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
}
for( i = low; i < high; i++)
{
set[i] = tempArray[i];
}
}
I am trying to perform a merge sort on an input file using a custom merge sort function. The merge sort functions however are not working and print out down below, the first block being the actual input file printed out to make sure fscanf is reading in everything correctly and the second being the printing after the merge functions are run. The functions are duplicating some of the values and are not sorting them either and I cannot find the mistake in the code. Note that the enum will be used to sort either the ids or the first float values I am just trying to get the merge sort to work before I use it to sort either the ids or those values.
1 13.000000 7.000000
13 14.000000 6.000000
95 7.000000 13.000000
39 0.000000 20.000000
78 10.000000 10.000000
68 3.000000 17.000000
32 6.000000 14.000000
10 19.000000 1.000000
0 18.000000 2.000000
45 17.000000 3.000000
92 4.000000 16.000000
29 5.000000 15.000000
85 8.000000 12.000000
79 15.000000 5.000000
12 16.000000 4.000000
32 1.000000 19.000000
77 9.000000 11.000000
52 12.000000 8.000000
80 11.000000 9.000000
31 2.000000 18.000000
1 13.000000 7.000000
13 14.000000 6.000000
68 3.000000 17.000000
0 18.000000 2.000000
10 19.000000 1.000000
0 18.000000 2.000000
0 18.000000 2.000000
92 4.000000 16.000000
92 4.000000 16.000000
29 5.000000 15.000000
32 1.000000 19.000000
52 12.000000 8.000000
77 9.000000 11.000000
79 15.000000 5.000000
12 16.000000 4.000000
32 1.000000 19.000000
32 1.000000 19.000000
80 11.000000 9.000000
95 7.000000 13.000000
95 7.000000 13.000000
You appear to have gotten confused about the meaning of your boundary indices. Consider the initial call to function mergesort():
mergesort(array,0,length,length,SortById);
You pass the same value for arguments high and number_of_points, which is fine, but it implies that high represents an exclusive upper bound on the indices of the sort range. The mergesort() implementation, however, seems geared for argument high to represent an inclusive bound.
The confusion continues with your merge() function, which is probably the main culprit here. By taking the passed midpoint value as the start index of the right sub-array, it seems to be expecting the midpoint as an exclusive upper bound of the left sub-array, but the current mergesort() implementation passes an inclusive upper bound. On the other hand, some of the index comparisons performed by merge() are appropriate only if middle is an inclusive upper bound of the subarray.
In short, you have a muddle. The basic outline of the algorithm looks fine, but you need to decide (and document for yourself) what your function parameters represent, and reconcile your implementation details with that. Were I you, I would adopt half-open representation for all intervals, so that lower bounds are always inclusive, and upper bounds always exclusive. Among other things, that has the advantage that each midpoint value can be interpreted equally correctly as the (exclusive) upper bound of the left half of its subarray or as the (inclusive) lower bound of the right half.
void mergesort(Points* set,int low,int high,int number_of_points, SortType sort)
{
int mid1;
if((high-low)>1)
{
mid1 = (low+high)/2;
mergesort(set, low, mid1, number_of_points, sort);
mergesort(set, mid1, high, number_of_points, sort);
merge(set, low, mid1, high, number_of_points, sort);
}
}
void merge(Points* set, int low, int middle, int high, int number_of_points, SortType sort)
{
int leftIndex=low;
int rightIndex=middle;
int combinedIndex = low;
Points tempArray[number_of_points];
int i;
while(leftIndex <= middle && rightIndex < high)
{
if(set[leftIndex].id <= set[rightIndex].id)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
else
tempArray[combinedIndex++] = set[rightIndex++];
}
if(leftIndex == middle+1)
{
while(rightIndex < high)
{
tempArray[combinedIndex++] = set[rightIndex++];
}
}
else
{
while(leftIndex < middle)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
}
for( i = low; i < high; i++)
{
set[i] = tempArray[i];
}
}
0 18.000000 2.000000
1 13.000000 7.000000
10 19.000000 1.000000
0 18.000000 2.000000
12 16.000000 4.000000
13 14.000000 6.000000
29 5.000000 15.000000
31 2.000000 18.000000
32 6.000000 14.000000
32 1.000000 19.000000
39 0.000000 20.000000
39 0.000000 20.000000
52 12.000000 8.000000
31 2.000000 18.000000
68 3.000000 17.000000
77 9.000000 11.000000
78 10.000000 10.000000
12 16.000000 4.000000
79 15.000000 5.000000
85 8.000000 12.000000

Basic neural network returns the average of the target outputs

I'm currently coding a basic neural network that is supposed to calculate a XOR, using backpropagation. However, it instead outputs the average of its target outputs. (A XOR returning {0,1,1,0}, that is 0.5).
I followed both the following articles [1][2] and can't find my error. That guy supposedly had the same problem, but never found an answer.
Anyway, here's my code:
network.c
void initialise_network(Network *network)
{
assert(network != NULL);
network->inputs[network->num_inputs] = 1.0;
network->hidden[network->num_hidden] = 1.0;
for (int i = 0; i < network->num_inputs+1; i++)
{
for (int j = 0; j < network->num_hidden; j++)
{
network->ithw[i][j] = rnd_double(-1, 1);
network->delta_hidden[i][j] = rnd_double(0, 0);
printf("ithw[%d][%d]: %f\n", i, j, network->ithw[i][j]);
}
}
for (int i = 0; i < network->num_hidden+1; i++)
{
for (int j = 0; j < network->num_outputs; j++)
{
network->htow[i][j] = rnd_double(-1, 1);
network->delta_output[i][j] = rnd_double(0, 0);
// printf("htow[%d][%d]: %f\n", i, j, network->htow[i][j]);
}
}
}
void pass_forward(double* inputs, Network *network)
{
log_info("pass_forward() !");
printf("Inputs: \n");
for (int i = 0; i < network->num_inputs; i++)
{
network->inputs[i] = inputs[i];
printf("%f, ", network->inputs[i]);
}
for (int i = 0; i < network->num_hidden; i++)
{
double sum = 0.0;
for (int j = 0; j < network->num_inputs+1; j++)
{
printf("\n inputs[%d]: %f", j, network->inputs[j]);
sum += network->inputs[j] * network->ithw[j][i];
printf("\nithw[%d][%d]: %f", j, i, network->ithw[j][i]);
printf("\n sum[%d]: %f", j, sum);
}
printf("\n hidden[%d]: %f", i, sum);
network->hidden[i] = sigmoid(sum);
printf("\n sigmoid(hidden[%d]): %f", i, network->hidden[i]);
}
for (int i = 0; i < network->num_outputs; i++)
{
double sum = 0.0;
for (int j = 0; j < network->num_hidden+1; j++)
{
sum += network->hidden[j] * network->htow[j][i];
}
printf("\n output[%d]: %f\n", i, network->outputs[i]);
network->outputs[i] = sigmoid(sum);
}
}
trainer_xor.c
void train_network(double *target_output, Network *network)
{
double *delta_hidden = malloc(sizeof(double) * network->num_hidden + 1);
double *delta_output = malloc(sizeof(double) * network->num_outputs);
double momentum = 0.1;
printf("Inputs: %f, %f\n", network->inputs[0], network->inputs[1]);
printf("Output: %f\n", network->outputs[0]);
printf("Target Output: %f\n", target_output[0]);
for (int i = 0; i < network->num_outputs; i++)
{
delta_output[i] = network->outputs[i] * (1.0 - network->outputs[i]) *
(target_output[i] - network->outputs[i]);
printf("delta_output: %f\n", delta_output[i]);
}
for (int i = 0; i < network->num_hidden + 1; i++)
{
double error = 0.0;
for (int j = 0; j < network->num_outputs; j++)
{
error += network->htow[i][j] * delta_output[j];
}
delta_hidden[i] = network->hidden[i] * (1.0 - network->hidden[i]) * error;
printf("hidden[%d]: %f\n", i, network->hidden[i]);
printf("delta_hidden[%d]: %f\n", i, delta_hidden[i]);
}
for (int i = 0; i < network->num_outputs; i++)
{
for (int j = 0; j < network->num_hidden + 1; j++)
{
double delta = network->learning_rate * delta_output[i] * network->hidden[j];
network->htow[j][i] += delta;
network->htow[j][i] += momentum * network->delta_output[j][i];
network->delta_output[j][i] = delta;
// printf("htow[%d][%d]: %f\n", i, j, network->htow[i][j]);
printf("htow[%d][%d]: %f\n", j, i, network->htow[j][i]);
}
}
for (int i = 0; i < network->num_hidden; i++)
{
for (int j = 0; j < network->num_inputs + 1; j++)
{
double delta = network->learning_rate * delta_hidden[i] * network->inputs[j];
network->ithw[j][i] += delta;
network->ithw[j][i] += momentum * network->delta_hidden[j][i];
network->delta_hidden[j][i] = delta;
printf("ithw[%d][%d]: %f\n", j, i, network->ithw[j][i]);
}
}
getchar();
}
void do_training(int training_times, Trainer *trainer)
{
trainer->training_times = training_times;
for (int i = 0; i < training_times; i++)
{
for (int j = 0; j < trainer->train_set_size; j++)
{
pass_forward(trainer->train_set[j], trainer->network);
train_network(get_target_values(trainer->train_set[j], trainer->train_set_size),
trainer->network);
}
}
}
main.c
int main()
{
initialize_utils();
Network *network = network_create(2, 2, 1);
initialise_network(network);
Trainer *trainer = trainer_create(network);
do_training(300, trainer);
return 0;
}
I train my network for 300 times. The train_set is as follows:
[0][0] = 0
[0][1] = 0
[1][0] = 1
[1][1] = 0
[2][0] = 0
[2][1] = 1
[3][0] = 1
[3][1] = 1
For more informations, here are my outputs at a certain time:
Gen 0:
=== Gen 0! ===
[INFO] (src/network.c:100) pass_forward() !
Inputs:
0.000000, 0.000000,
inputs[0]: 0.000000
ithw[0][0]: 0.316492
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][0]: -0.028962
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][0]: -0.915344
sum[2]: -0.915344
hidden[0]: -0.915344
sigmoid(hidden[0]): 0.285908
inputs[0]: 0.000000
ithw[0][1]: 0.089068
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][1]: 0.176854
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][1]: 0.958716
sum[2]: 0.958716
hidden[1]: 0.958716
sigmoid(hidden[1]): 0.722865
output[0]: 0.000000
train_network()!
Inputs: 0.000000, 0.000000
Output: 0.625586
Target Output: 0.000000
delta_output: -0.146530
hidden[0]: 0.285908
delta_hidden[0]: 0.002849
hidden[1]: 0.722865
delta_hidden[1]: 0.007222
hidden[2]: 1.000000
delta_hidden[2]: -0.000000
htow[0][0]: -0.107817
htow[1][0]: -0.277817
htow[2][0]: 0.674453
ithw[0][0]: 0.316492
ithw[1][0]: -0.028962
ithw[2][0]: -0.914489
ithw[0][1]: 0.089068
ithw[1][1]: 0.176854
ithw[2][1]: 0.960883
Gen 1:
=== Gen 1! ===
[INFO] (src/network.c:100) pass_forward() !
Inputs:
0.000000, 0.000000,
inputs[0]: 0.000000
ithw[0][0]: 0.316628
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][0]: -0.028659
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][0]: -0.914866
sum[2]: -0.914866
hidden[0]: -0.914866
sigmoid(hidden[0]): 0.286005
inputs[0]: 0.000000
ithw[0][1]: 0.089247
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][1]: 0.177256
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][1]: 0.959846
sum[2]: 0.959846
hidden[1]: 0.959846
sigmoid(hidden[1]): 0.723091
output[0]: 0.625643
train_network()
Inputs: 0.000000, 0.000000
Output: 0.613576
Target Output: 0.000000
delta_output: -0.145479
hidden[0]: 0.286005
delta_hidden[0]: 0.003118
hidden[1]: 0.723091
delta_hidden[1]: 0.007844
hidden[2]: 1.000000
delta_hidden[2]: -0.000000
htow[0][0]: -0.118963
htow[1][0]: -0.304226
htow[2][0]: 0.639053
ithw[0][0]: 0.316718
ithw[1][0]: -0.028568
ithw[2][0]: -0.913841
ithw[0][1]: 0.089431
ithw[1][1]: 0.177440
ithw[2][1]: 0.962383
Gen 10:
=== Gen 10! ===
[INFO] (src/network.c:100) pass_forward() !
Inputs:
0.000000, 0.000000,
inputs[0]: 0.000000
ithw[0][0]: 0.317382
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][0]: -0.025525
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][0]: -0.911555
sum[2]: -0.911555
hidden[0]: -0.911555
sigmoid(hidden[0]): 0.286682
inputs[0]: 0.000000
ithw[0][1]: 0.089229
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][1]: 0.180321
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][1]: 0.967483
sum[2]: 0.967483
hidden[1]: 0.967483
sigmoid(hidden[1]): 0.724618
output[0]: 0.547804
Inputs: 0.000000, 0.000000
Output: 0.539370
Target Output: 0.000000
delta_output: -0.134006
hidden[0]: 0.286682
delta_hidden[0]: 0.004474
hidden[1]: 0.724618
delta_hidden[1]: 0.010913
hidden[2]: 1.000000
delta_hidden[2]: -0.000000
htow[0][0]: -0.176218
htow[1][0]: -0.440373
htow[2][0]: 0.456051
ithw[0][0]: 0.317521
ithw[1][0]: -0.025386
ithw[2][0]: -0.910074
ithw[0][1]: 0.089499
ithw[1][1]: 0.180592
ithw[2][1]: 0.971027
Gen 100:
=== Gen 100! ===
[INFO] (src/network.c:100) pass_forward() !
Inputs:
0.000000, 0.000000,
inputs[0]: 0.000000
ithw[0][0]: 0.295665
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][0]: -0.014208
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][0]: -0.929113
sum[2]: -0.929113
hidden[0]: -0.929113
sigmoid(hidden[0]): 0.283105
inputs[0]: 0.000000
ithw[0][1]: 0.023758
sum[0]: 0.000000
inputs[1]: 0.000000
ithw[1][1]: 0.161541
sum[1]: 0.000000
inputs[2]: 1.000000
ithw[2][1]: 0.932629
sum[2]: 0.932629
hidden[1]: 0.932629
sigmoid(hidden[1]): 0.717608
output[0]: 0.512934
Inputs: 0.000000, 0.000000
Output: 0.505055
Target Output: 0.000000
delta_output: -0.126251
hidden[0]: 0.283105
delta_hidden[0]: 0.004697
hidden[1]: 0.717608
delta_hidden[1]: 0.011935
hidden[2]: 1.000000
delta_hidden[2]: -0.000000
htow[0][0]: -0.195365
htow[1][0]: -0.496565
htow[2][0]: 0.365162
ithw[0][0]: 0.295813
ithw[1][0]: -0.014059
ithw[2][0]: -0.927556
ithw[0][1]: 0.024074
ithw[1][1]: 0.161856
ithw[2][1]: 0.936526
Kino, do you know that you need to train the network in multiple backpropagation passes until it converges, that is, until the weights change so that the difference between your target outputs and the actual outputs becomes smaller than some tolerance?
train_network() only seems to make one pass, are you doing the rest of the training elsewhere?
Something like:
const double TOLERANCE = 0.001;
while( fabs(network->outputs[ 0 ] - target_output[ 0 ]) > TOLERANCE &&
fabs(network->outputs[ 1 ] - target_output[ 1 ]) > TOLERANCE ) {
train_network(target_output, network);
}
(But it's probably neater to do the loop in train_network() itself.)

How do I initialize a two-dimensional array in C

I am trying to initialize two copies of the same two-dimensional arrays in C. However, only one stores the correct data:
//convert 1D array to 2D array
double** myA = malloc(n*sizeof(double*));
for (j=0;j<n;j++)
myA[j]=&a[j*n];
double** myS = (double **) malloc(n*sizeof(double*));
for (i=0; i<n; i++)
for (j=0; j<n; j++){
myS[i] = (double *) malloc(n*sizeof(double));
myS[i][j] = myA[i][j];
}
printf("A:\n");
print_matrix(myA,n);
printf("S:\n");
print_matrix(myS,n);
I want to initialize two copies of A. One as myA and the other as myS. However, here is my output:
A:
0.000000 1.000000 2.000000 3.000000 4.000000
1.000000 1.414214 2.236068 3.162278 4.123106
2.000000 2.236068 2.828427 3.605551 4.472136
3.000000 3.162278 3.605551 4.242641 5.000000
4.000000 4.123106 4.472136 5.000000 5.656854
S:
-0.000000 -0.000000 -0.000000 -0.000000 4.000000
-0.000000 -0.000000 -0.000000 -0.000000 4.123106
-0.000000 -0.000000 -0.000000 -0.000000 4.472136
-0.000000 -0.000000 -0.000000 -0.000000 5.000000
-0.000000 -0.000000 -0.000000 -0.000000 5.656854
Why are all the columns but the last -0.000000?
You're overwriting each row buffer N-1 times (and leaking memory like a sieve leaks water in the process).
Change this:
for (i=0; i<n; i++)
for (j=0; j<n; j++){
myS[i] = (double *) malloc(n*sizeof(double));
myS[i][j] = myA[i][j];
}
To this:
for (i=0; i<n; i++)
{
myS[i] = malloc(n*sizeof(double));
for (j=0; j<n; j++)
myS[i][j] = a[i*n+j];
}
Note two things in the above code:
Don't cast malloc.
The myA temp array is not needed. You can do the math with the index yourself. Throw that entire thing out.

Resources