added core code, README, and testing scripts
[strong_simulation_stabilizer_rank.git] / matrix.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "matrix.h"
6
7
8 int** addMatrix(int **A, int **B, int rows, int cols)
9 {
10   int i, j;
11
12   int** C;
13
14   C = calloc(cols, sizeof(int*));
15   for(i=0; i<cols; i++)
16     C[i] = calloc(rows, sizeof(int));
17
18   for(i=0; i<rows; i++)
19     for(j=0; j<cols; j++)
20       C[i][j] = A[i][j] + B[i][j];
21
22   return C;
23 }
24
25 void addMatrixMod(int **A, int **B, int **C, int rows, int cols, int mod)
26 {
27   int i, j;
28
29   for(i=0; i<rows; i++)
30     for(j=0; j<cols; j++)
31       C[i][j] = (A[i][j] + B[i][j])%mod;
32
33   return;
34 }
35
36 void addVectorMod(int *A, int *B, int *C, int length, int mod)
37 {
38   int i;
39
40   for(i=0; i<length; i++)
41     C[i] = (A[i] + B[i])%mod;
42
43   return;
44 }
45
46 void scalarmultMatrix(int scalar, int **a, int **b, int rows, int cols)
47 {
48   int i, j;
49
50   //b = calloc(cols, sizeof(int*));
51   //for(i=0; i<cols; i++)
52   //  b[i] = calloc(rows, sizeof(int));
53
54   for(i=0; i<rows; i++)
55     for(j=0; j<cols; j++)
56       b[i][j] = scalar*a[i][j];
57
58 }
59
60 int trace(int **a, int rows, int cols)
61 {
62   int i;
63   int tr = 0.0;
64
65   for(i=0; i<rows; i++)
66     tr += a[i][i];
67
68   return tr;
69 }
70
71 // b = a^T
72 void transp(int **a, int **b, int rows, int cols)
73 {
74   int i, j;
75
76   for(i=0; i<cols; i++) {
77     for(j=0; j<rows; j++)
78       b[i][j] = a[j][i];
79   }    
80
81 }
82
83 void printVector(int* a, int length)
84 {
85   int i;
86   printf("Vector[%d]\n", length);
87   for(i=0; i<length; i++)
88     printf("%d ", a[i]);
89   if(length>0)
90     printf("\n");
91   
92 }
93
94 void printMatrix(int** a, int rows, int cols)
95 {
96   int i, j;
97   printf("Matrix[%d][%d]\n", rows, cols);
98   for(i=0; i<rows; i++) {
99     for(j=0; j<cols; j++) {
100       printf("%d ", a[i][j]);
101     }
102     printf("\n");
103   }
104 }
105
106 int** multMatrix(int **A, int **B, int ro1, int co1, int ro2, int co2)
107 {
108   int i, j, k;
109   int **C;
110   C = calloc(ro1, sizeof(int*));
111   for(i=0; i<ro1; i++)
112     C[i] = calloc(co2, sizeof(int));
113   
114   for(i=0; i<ro1; i++) {
115     for(j=0; j<co2; j++) {
116       C[i][j] = 0;
117       for(k=0; k<co1; k++)
118         C[i][j] += A[i][k] * B[k][j];
119     }
120   }
121
122   return C;
123 }
124
125 // A times B = C
126 void multMatrixMod(int **A, int **B, int **C, int ro1, int co1, int ro2, int co2, int mod)
127 {
128   int i, j, k, tmp;
129
130   for(i=0; i<ro1; i++) {
131     for(j=0; j<co2; j++) {
132       tmp = 0;
133       for(k=0; k<co1; k++)
134         tmp += (A[i][k] * B[k][j]);
135       C[i][j] = tmp%mod;
136     }
137   }
138
139 }
140
141 int** outerMatrix(int **A, int **B, int ro1, int co1, int ro2, int co2)
142 {
143   int i, j, k, l;
144   int **C;
145   C = calloc(ro1*ro2, sizeof(int*));
146   for(i=0; i<ro1*ro2; i++)
147     C[i] = calloc(co1*co2, sizeof(int));
148
149   for(i=0; i<ro1; i++)
150     for(j=0; j<ro2; j++)
151       for(k=0; k<co1; k++)
152         for(l=0; l<co2; l++) {
153           C[j+ro2*i][l+co2*k] = A[i][k]* B[j][l];
154         }
155
156   return C;
157 }
158
159 void outerMatrixMod(int **A, int **B, int **C, int ro1, int co1, int ro2, int co2, int mod)
160 {
161   int i, j, k, l;
162   //int **C;
163   //C = calloc(ro1*ro2, sizeof(int*));
164   //for(i=0; i<ro1*ro2; i++)
165   //  C[i] = calloc(co1*co2, sizeof(int));
166
167   for(i=0; i<ro1; i++)
168     for(j=0; j<ro2; j++)
169       for(k=0; k<co1; k++)
170         for(l=0; l<co2; l++) {
171           C[j+ro2*i][l+co2*k] = (A[i][k]* B[j][l])%mod;
172         }
173
174 }
175
176 void outerVectorMod(int *A, int *B, int *C, int ro1, int ro2, int mod)
177 {
178   int i, j;
179
180   for(i=0; i<ro1; i++)
181     for(j=0; j<ro2; j++)
182       C[j+ro2*i]= (A[i]* B[j])%mod;
183
184 }
185
186 void addSubMatrix(int **A, int **B, int ro1, int co1, int rooff1, int cooff1, int rooff2, int cooff2)
187 {
188   // rooff1 is row offset to start range ro1 in first matrix etc.
189   int i, j;
190
191   for(i=0; i<ro1; i++)
192     for(j=0; j<co1; j++)
193       B[rooff2+i][cooff2+j] = A[rooff1+i][cooff1+j];
194
195 }
196
197 void appendBlockMatrix(int **A, int **B, int **C, int ro1, int co1, int ro2, int co2)
198 {
199   // rooff1 is row offset to start range ro1 in first matrix etc.
200   int i, j;
201
202   for(i=0; i<ro1; i++)
203     for(j=0; j<co1; j++)
204       C[i][j] = A[i][j];
205
206   for(i=0; i<ro2; i++)
207     for(j=0; j<co2; j++)
208       C[ro1+i][co1+j] = B[i][j];
209   
210 }
211
212
213 void appendVector(int *A, int *B, int *C, int ro1, int ro2)
214 {
215   int i;
216
217   for(i=0; i<ro1; i++)
218     C[i] = A[i];
219   for(i=0; i<ro2; i++)
220     C[ro1+i] = B[i];
221
222 }
223
224
225 int dotProductMod(int *a, int *b, int length, int mod)
226 {
227   int i;
228   int dotproduct = 0;
229
230   for(i=0; i<length; i++)
231     dotproduct += a[i]*b[i];
232
233   return(dotproduct%mod);
234 }
235
236
237 void deallocate_mem(int ***arr, int rows)
238 {
239   int i;
240   for(i=0; i<rows; i++)
241     free((*arr)[i]);
242   free(*arr);
243 }