Compare commits
16 Commits
9929a4470c
...
main
Author | SHA1 | Date | |
---|---|---|---|
50390f7118
|
|||
7b83d9eeb4
|
|||
8ffcc39c9c
|
|||
cddbadfd4a
|
|||
c41d130a45
|
|||
2b2ffe9649
|
|||
e5ddece861
|
|||
cb5561b35b
|
|||
21fb373f65
|
|||
a94122eeb2
|
|||
02bd70cedd
|
|||
16274d2a98
|
|||
d8c3a75d50
|
|||
55480a727e
|
|||
49cab7b2cc
|
|||
6ab823c1fc
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
*.x64
|
||||
gmon.out
|
||||
prof_output
|
||||
|
@ -21,4 +21,4 @@
|
||||
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;1;0;1;0;0
|
||||
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1
|
||||
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1
|
||||
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0
|
||||
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0
|
||||
|
|
12
csv/5n.csv
12
csv/5n.csv
@ -1,7 +1,5 @@
|
||||
0;0;0;0;0;0;0
|
||||
0;0;0;0;1;0;0
|
||||
0;0;0;0;0;0;0
|
||||
0;0;0;0;1;0;0
|
||||
0;1;0;1;0;0;0
|
||||
0;0;0;0;0;0;1
|
||||
0;0;0;0;0;1;0
|
||||
0;0;1;0;0
|
||||
0;0;1;0;0
|
||||
1;1;0;1;1
|
||||
0;0;1;0;1
|
||||
0;0;1;1;0
|
||||
|
|
@ -2,4 +2,4 @@
|
||||
0;0;0;0;0
|
||||
0;0;0;0;0
|
||||
0;0;0;0;0
|
||||
0;0;0;0;0
|
||||
0;0;0;0;0
|
|
7
csv/7n.csv
Normal file
7
csv/7n.csv
Normal file
@ -0,0 +1,7 @@
|
||||
0;0;0;0;0;0;0
|
||||
0;0;0;0;1;0;0
|
||||
0;0;0;0;0;0;0
|
||||
0;0;0;0;1;0;0
|
||||
0;1;0;1;0;0;0
|
||||
0;0;0;0;0;0;1
|
||||
0;0;0;0;0;1;0
|
|
@ -1,5 +0,0 @@
|
||||
0;0;1;1;0
|
||||
0;0;1;1;0
|
||||
1;1;0;1;0
|
||||
1;1;1;0;1
|
||||
0;0;0;1;0
|
|
@ -1,5 +0,0 @@
|
||||
0;0;1;0;0
|
||||
0;0;1;0;0
|
||||
1;1;0;1;1
|
||||
0;0;1;0;1
|
||||
0;0;1;1;0
|
|
486
graph.c
486
graph.c
@ -1,45 +1,65 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "graph.h"
|
||||
#include "matrix.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "matrix.h"
|
||||
|
||||
void random_adjacency(const uint64_t vertex_count, uint64_t matrix[vertex_count][vertex_count]) {
|
||||
void random_adjacency(const ulong vertex_count, ulong matrix[vertex_count][vertex_count]) {
|
||||
srand(time(NULL));
|
||||
|
||||
for (uint64_t row_index=0; row_index < vertex_count; row_index++) {
|
||||
for (uint64_t column_index=0; column_index < vertex_count; column_index++) {
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (column_index == row_index) {
|
||||
matrix[row_index][column_index] = 0;
|
||||
continue;
|
||||
} else {
|
||||
matrix[row_index][column_index] = rand() % 2;
|
||||
}
|
||||
matrix[row_index][column_index] = rand()%2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_distance_matrix(const uint64_t vertex_count, const uint64_t adjacency_matrix[vertex_count][vertex_count], uint64_t distance_matrix[vertex_count][vertex_count]) {
|
||||
uint64_t power_matrix[vertex_count][vertex_count];
|
||||
copy(vertex_count, vertex_count, adjacency_matrix, power_matrix);
|
||||
void random_adjacency_struct(const Matrix *matrix) {
|
||||
if (matrix->row_length != matrix->column_length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint64_t row_index=0; row_index < vertex_count; row_index++) {
|
||||
for (uint64_t column_index=0; column_index < vertex_count; column_index++) {
|
||||
srand(time(NULL));
|
||||
|
||||
for (ulong row_index = 0; row_index < matrix->row_length; row_index++) {
|
||||
for (ulong column_index = 0; column_index < matrix->column_length; column_index++) {
|
||||
if (column_index == row_index) {
|
||||
matrix->values[row_index][column_index] = 0;
|
||||
} else {
|
||||
matrix->values[row_index][column_index] = rand() % 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_distance_matrix(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], ulong distance_matrix[vertex_count][vertex_count]) {
|
||||
ulong power_matrix[vertex_count][vertex_count];
|
||||
ulong temp_power_matrix[vertex_count][vertex_count];
|
||||
memcpy(power_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (row_index == column_index) {
|
||||
distance_matrix[row_index][column_index] = 0;
|
||||
} else if (adjacency_matrix[row_index][column_index] == 1) {
|
||||
distance_matrix[row_index][column_index] = 1;
|
||||
} else {
|
||||
distance_matrix[row_index][column_index] = UINT64_MAX;
|
||||
distance_matrix[row_index][column_index] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(uint64_t k = 2; k < vertex_count; k++) {
|
||||
matrix_multiply_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, power_matrix, power_matrix);
|
||||
for(ulong k = 2; k <= vertex_count; k++) {
|
||||
memcpy(temp_power_matrix, power_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
gemm_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, temp_power_matrix, power_matrix);
|
||||
|
||||
for (uint64_t row_index=0; row_index < vertex_count; row_index++) {
|
||||
for (uint64_t column_index=0; column_index < vertex_count; column_index++) {
|
||||
if (power_matrix[row_index][column_index] != 0 && distance_matrix[row_index][column_index] == UINT64_MAX) {
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (power_matrix[row_index][column_index] != 0 && distance_matrix[row_index][column_index] == -1) {
|
||||
distance_matrix[row_index][column_index] = k;
|
||||
}
|
||||
}
|
||||
@ -47,5 +67,431 @@ void calculate_distance_matrix(const uint64_t vertex_count, const uint64_t adjac
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_eccentricities(const uint64_t vertex_count, const uint64_t output_matrix[vertex_count][vertex_count]) {
|
||||
int get_eccentricities(const ulong vertex_count, const ulong distance_matrix[vertex_count][vertex_count], ulong eccentricities[vertex_count]) {
|
||||
ulong eccentricity;
|
||||
|
||||
// set all eccentricities to infinity in case this is a disconnected graph
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
eccentricities[index] = -1;
|
||||
}
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
eccentricity = 0;
|
||||
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (distance_matrix[row_index][column_index] > eccentricity) {
|
||||
eccentricity = distance_matrix[row_index][column_index];
|
||||
}
|
||||
}
|
||||
// in case of a disconnected graph
|
||||
if (eccentricity == 0) {
|
||||
return 1;
|
||||
}
|
||||
eccentricities[row_index] = eccentricity;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_radius(const ulong vertex_count, const ulong eccentricities[vertex_count]) {
|
||||
ulong radius = -1;
|
||||
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (eccentricities[index] < radius) {
|
||||
radius = eccentricities[index];
|
||||
}
|
||||
}
|
||||
|
||||
return radius;
|
||||
}
|
||||
|
||||
ulong get_diameter(const ulong vertex_count, const ulong eccentricities[vertex_count]) {
|
||||
ulong diamter = 0;
|
||||
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (eccentricities[index] > diamter) {
|
||||
diamter = eccentricities[index];
|
||||
}
|
||||
}
|
||||
|
||||
return diamter;
|
||||
}
|
||||
|
||||
void get_centre(const ulong vertex_count, const ulong eccentricities[vertex_count], const ulong radius, ulong centre[vertex_count]) {
|
||||
memset(centre, 0, vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (eccentricities[index] == radius) {
|
||||
centre[index] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_path_matrix(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], ulong path_matrix[vertex_count][vertex_count]) {
|
||||
ulong power_matrix[vertex_count][vertex_count];
|
||||
ulong temp_power_matrix[vertex_count][vertex_count];
|
||||
memcpy(power_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (row_index == column_index || adjacency_matrix[row_index][column_index] == 1) {
|
||||
path_matrix[row_index][column_index] = 1;
|
||||
} else {
|
||||
path_matrix[row_index][column_index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(ulong k = 2; k <= vertex_count; k++) {
|
||||
memcpy(temp_power_matrix, power_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
gemm_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, temp_power_matrix, power_matrix);
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (power_matrix[row_index][column_index] != 0) {
|
||||
path_matrix[row_index][column_index] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_components_basic(const ulong vertex_count, const ulong path_matrix[vertex_count][vertex_count], ulong components[vertex_count][vertex_count]) {
|
||||
ulong component[vertex_count];
|
||||
int contains_component;
|
||||
|
||||
memset(components, 0, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
memset(component, 0, vertex_count * sizeof(ulong));
|
||||
contains_component = 0;
|
||||
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (path_matrix[row_index][column_index] == 1) {
|
||||
component[column_index] = column_index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (memcmp(components[index], component, vertex_count * sizeof(ulong)) == 0) {
|
||||
contains_component = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contains_component) {
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
components[row_index][index] = component[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dfs(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], const ulong vertex, ulong visited[vertex_count]) {
|
||||
visited[vertex] = 1;
|
||||
|
||||
for (ulong neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
|
||||
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
|
||||
continue;
|
||||
}
|
||||
if (visited[neighbor_vertex]) {
|
||||
continue;
|
||||
}
|
||||
dfs(vertex_count, adjacency_matrix, neighbor_vertex, visited);
|
||||
}
|
||||
}
|
||||
|
||||
void find_components_dfs(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], ulong components[vertex_count][vertex_count]) {
|
||||
ulong component[vertex_count];
|
||||
int contains_component = 0;
|
||||
|
||||
memset(components, 0, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong vertex = 0; vertex < vertex_count; vertex++) {
|
||||
memset(component, 0, vertex_count * sizeof(ulong));
|
||||
contains_component = 0;
|
||||
|
||||
dfs(vertex_count, adjacency_matrix, vertex, component);
|
||||
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (memcmp(components[index], component, vertex_count * sizeof(ulong)) == 0) {
|
||||
contains_component = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contains_component) {
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
components[vertex][index] = component[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ulong amount_of_components(const ulong vertex_count, const ulong components[vertex_count][vertex_count]) {
|
||||
ulong amount_of_components = 0;
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (components[row_index][column_index] != 0) {
|
||||
amount_of_components++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return amount_of_components;
|
||||
}
|
||||
|
||||
int contains_bridge(const ulong vertex_count, const ulong bridges[vertex_count][2], const ulong bridge[2]) {
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (memcmp(bridges[index], bridge, 2 * sizeof(ulong)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void find_bridges_basic(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count], ulong bridges[vertex_count][2]) {
|
||||
ulong path_matrix[vertex_count][vertex_count];
|
||||
ulong temp_adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong temp_components[vertex_count][vertex_count];
|
||||
ulong bridge[2];
|
||||
|
||||
memset(bridges, 0, vertex_count * 2 * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (row_index == column_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (column_index < row_index) {
|
||||
bridge[0] = column_index + 1;
|
||||
bridge[1] = row_index + 1;
|
||||
} else {
|
||||
bridge[0] = row_index + 1;
|
||||
bridge[1] = column_index + 1;
|
||||
}
|
||||
|
||||
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
temp_adjacency_matrix[row_index][column_index] = 0;
|
||||
temp_adjacency_matrix[column_index][row_index] = 0;
|
||||
|
||||
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
|
||||
find_components_basic(vertex_count, path_matrix, temp_components);
|
||||
|
||||
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) && !contains_bridge(vertex_count, bridges, bridge)) {
|
||||
bridges[row_index][0] = bridge[0];
|
||||
bridges[row_index][1] = bridge[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
print_matrix(vertex_count, 2, bridges);
|
||||
}
|
||||
|
||||
void find_bridges_dfs_v1(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count], ulong bridges[vertex_count][2]) {
|
||||
ulong temp_adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong temp_components[vertex_count][vertex_count];
|
||||
ulong bridge[2];
|
||||
|
||||
memset(bridges, 0, vertex_count * 2 * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (row_index == column_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (column_index < row_index) {
|
||||
bridge[0] = column_index + 1;
|
||||
bridge[1] = row_index + 1;
|
||||
} else {
|
||||
bridge[0] = row_index + 1;
|
||||
bridge[1] = column_index + 1;
|
||||
}
|
||||
|
||||
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
temp_adjacency_matrix[row_index][column_index] = 0;
|
||||
temp_adjacency_matrix[column_index][row_index] = 0;
|
||||
|
||||
find_components_dfs(vertex_count, temp_adjacency_matrix, temp_components);
|
||||
|
||||
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) && !contains_bridge(vertex_count, bridges, bridge)) {
|
||||
bridges[row_index][0] = bridge[0];
|
||||
bridges[row_index][1] = bridge[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dfs_bridges(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], const ulong vertex, const ulong parent_vertex, ulong visited[vertex_count],
|
||||
ulong current_time, ulong discovery_time[vertex_count], ulong lowest_time[vertex_count], ulong bridges[vertex_count][2]) {
|
||||
current_time++;
|
||||
visited[vertex] = 1;
|
||||
discovery_time[vertex] = current_time;
|
||||
lowest_time[vertex] = current_time;
|
||||
|
||||
for (ulong neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
|
||||
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
|
||||
continue;
|
||||
}
|
||||
if (parent_vertex != neighbor_vertex && visited[neighbor_vertex]) {
|
||||
if (lowest_time[vertex] > discovery_time[neighbor_vertex]) {
|
||||
lowest_time[vertex] = discovery_time[neighbor_vertex];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (visited[neighbor_vertex]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dfs_bridges(vertex_count, adjacency_matrix, neighbor_vertex, vertex, visited, current_time, discovery_time, lowest_time, bridges);
|
||||
|
||||
if (lowest_time[vertex] > lowest_time[neighbor_vertex]) {
|
||||
lowest_time[vertex] = lowest_time[neighbor_vertex];
|
||||
}
|
||||
if (discovery_time[vertex] < lowest_time[neighbor_vertex]) {
|
||||
bridges[neighbor_vertex][0] = vertex + 1;
|
||||
bridges[neighbor_vertex][1] = neighbor_vertex + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_bridges_dfs_v2(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count], ulong bridges[vertex_count][2]) {
|
||||
ulong visited[vertex_count];
|
||||
ulong current_time = 0;
|
||||
ulong discovery_time[vertex_count];
|
||||
ulong lowest_time[vertex_count];
|
||||
|
||||
memset(bridges, 0, vertex_count * 2 * sizeof(ulong));
|
||||
memset(visited, 0, vertex_count * sizeof(ulong));
|
||||
memset(discovery_time, 0, vertex_count * sizeof(ulong));
|
||||
memset(lowest_time, 0, vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong vertex = 0; vertex < vertex_count; vertex++) {
|
||||
if (!visited[vertex]) {
|
||||
dfs_bridges(vertex_count, adjacency_matrix, vertex, -1, visited, current_time, discovery_time, lowest_time, bridges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_articulations_basic(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count], ulong articulations[vertex_count]) {
|
||||
ulong path_matrix[vertex_count][vertex_count];
|
||||
ulong temp_adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong temp_components[vertex_count][vertex_count];
|
||||
|
||||
memset(articulations, 0, vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong i = 0; i < vertex_count; i++) {
|
||||
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
temp_adjacency_matrix[row_index][i] = 0;
|
||||
temp_adjacency_matrix[i][column_index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
|
||||
find_components_basic(vertex_count, path_matrix, temp_components);
|
||||
|
||||
// the + 1 is needed because I am not removing the vertex, I am just removing all of its edges
|
||||
// removing all of its edges, means it itself becomes a component, which needs to be accounted for
|
||||
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) + 1) {
|
||||
articulations[i] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void find_articulations_dfs_v1(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count], ulong articulations[vertex_count]) {
|
||||
ulong temp_adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong temp_components[vertex_count][vertex_count];
|
||||
|
||||
memset(articulations, 0, vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong i = 0; i < vertex_count; i++) {
|
||||
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
temp_adjacency_matrix[row_index][i] = 0;
|
||||
temp_adjacency_matrix[i][column_index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
find_components_dfs(vertex_count, temp_adjacency_matrix, temp_components);
|
||||
|
||||
// the + 1 is needed because I am not removing the vertex, I am just removing all of its edges
|
||||
// removing all of its edges, means it itself becomes a component, which needs to be accounted for
|
||||
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) + 1) {
|
||||
articulations[i] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dfs_articulations(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], const ulong vertex, const ulong parent_vertex,
|
||||
ulong visited[vertex_count], ulong current_time, ulong discovery_time[vertex_count], ulong lowest_time[vertex_count],
|
||||
ulong articulations[vertex_count]) {
|
||||
current_time++;
|
||||
visited[vertex] = 1;
|
||||
discovery_time[vertex] = current_time;
|
||||
lowest_time[vertex] = current_time;
|
||||
ulong child_count = 0;
|
||||
ulong is_articulation = 0;
|
||||
|
||||
for (ulong neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
|
||||
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
|
||||
continue;
|
||||
}
|
||||
if (visited[neighbor_vertex]) {
|
||||
if (lowest_time[vertex] > discovery_time[neighbor_vertex]) {
|
||||
lowest_time[vertex] = discovery_time[neighbor_vertex];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
child_count++;
|
||||
|
||||
dfs_articulations(vertex_count, adjacency_matrix, neighbor_vertex, vertex, visited, current_time, discovery_time, lowest_time, articulations);
|
||||
|
||||
if (lowest_time[vertex] > lowest_time[neighbor_vertex]) {
|
||||
lowest_time[vertex] = lowest_time[neighbor_vertex];
|
||||
}
|
||||
|
||||
if (parent_vertex != -1 && discovery_time[vertex] <= lowest_time[neighbor_vertex]) {
|
||||
is_articulation = 1;
|
||||
}
|
||||
}
|
||||
if (parent_vertex == -1 && child_count > 1) {
|
||||
is_articulation = 1;
|
||||
}
|
||||
if (is_articulation) {
|
||||
articulations[vertex] = vertex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void find_articulations_dfs_v2(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count], ulong articulations[vertex_count]) {
|
||||
ulong visited[vertex_count];
|
||||
ulong current_time = 0;
|
||||
ulong discovery_time[vertex_count];
|
||||
ulong lowest_time[vertex_count];
|
||||
|
||||
memset(articulations, 0, vertex_count * sizeof(ulong));
|
||||
memset(visited, 0, vertex_count * sizeof(ulong));
|
||||
memset(discovery_time, 0, vertex_count * sizeof(ulong));
|
||||
memset(lowest_time, 0, vertex_count * sizeof(ulong));
|
||||
|
||||
for (ulong vertex = 0; vertex < vertex_count; vertex++) {
|
||||
if (!visited[vertex]) {
|
||||
dfs_articulations(vertex_count, adjacency_matrix, vertex, -1, visited, current_time, discovery_time, lowest_time, articulations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
73
graph.h
73
graph.h
@ -1,16 +1,73 @@
|
||||
#ifndef GRAPH_H
|
||||
#define GRAPH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "matrix.h"
|
||||
|
||||
void random_adjacency(const uint64_t vertex_count,
|
||||
uint64_t matrix[vertex_count][vertex_count]);
|
||||
void random_adjacency(const ulong vertex_count,
|
||||
ulong matrix[vertex_count][vertex_count]);
|
||||
|
||||
void calculate_distance_matrix(const uint64_t vertex_count,
|
||||
const uint64_t adjacency_matrix[vertex_count][vertex_count],
|
||||
uint64_t distance_matrix[vertex_count][vertex_count]);
|
||||
void random_adjacency_struct(const Matrix *matrix);
|
||||
|
||||
void calculate_eccentricities(const uint64_t vertex_count,
|
||||
const uint64_t output_matrix[vertex_count][vertex_count]);
|
||||
void calculate_distance_matrix(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
ulong distance_matrix[vertex_count][vertex_count]);
|
||||
|
||||
// returns 1 if it is a disconnected graph and sets all values in eccentricities to UINT64_MAX
|
||||
int get_eccentricities(const ulong vertex_count,
|
||||
const ulong distance_matrix[vertex_count][vertex_count],
|
||||
ulong eccentricities[vertex_count]);
|
||||
|
||||
ulong get_radius(const ulong vertex_count,
|
||||
const ulong eccentricities[vertex_count]);
|
||||
|
||||
ulong get_diameter(const ulong vertex_count,
|
||||
const ulong eccentricities[vertex_count]);
|
||||
|
||||
void get_centre(const ulong vertex_count,
|
||||
const ulong eccentricities[vertex_count],
|
||||
const ulong radius,
|
||||
ulong centre[vertex_count]);
|
||||
|
||||
void calculate_path_matrix(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
ulong path_matrix[vertex_count][vertex_count]);
|
||||
|
||||
void find_components_basic(const ulong vertex_count,
|
||||
const ulong path_matrix[vertex_count][vertex_count],
|
||||
ulong components[vertex_count][vertex_count]);
|
||||
|
||||
void find_components_dfs(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
ulong components[vertex_count][vertex_count]);
|
||||
|
||||
void find_bridges_basic(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count],
|
||||
ulong bridges[vertex_count][2]);
|
||||
|
||||
void find_bridges_dfs_v1(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count],
|
||||
ulong bridges[vertex_count][2]);
|
||||
|
||||
void find_bridges_dfs_v2(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count],
|
||||
ulong bridges[vertex_count][2]);
|
||||
|
||||
void find_articulations_basic(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count],
|
||||
ulong articulations[vertex_count]);
|
||||
|
||||
void find_articulations_dfs_v1(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count],
|
||||
ulong articulations[vertex_count]);
|
||||
|
||||
void find_articulations_dfs_v2(const ulong vertex_count,
|
||||
const ulong adjacency_matrix[vertex_count][vertex_count],
|
||||
const ulong components[vertex_count][vertex_count],
|
||||
ulong articulations[vertex_count]);
|
||||
|
||||
#endif
|
||||
|
305
main.c
305
main.c
@ -1,69 +1,294 @@
|
||||
#include "graph.h"
|
||||
#include "matrix.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void benchmark() {
|
||||
const uint64_t row_length1 = 100, column_length1 = 100;
|
||||
uint64_t matrix1[row_length1][column_length1];
|
||||
|
||||
const uint64_t row_length2 = 100, column_length2 = 100;
|
||||
uint64_t matrix2[row_length2][column_length2];
|
||||
|
||||
uint64_t new_matrix[row_length1][column_length2];
|
||||
void benchmark_gemm() {
|
||||
const ulong vertex_count = 100;
|
||||
ulong adjacency_matrix1[vertex_count][vertex_count];
|
||||
ulong adjacency_matrix2[vertex_count][vertex_count];
|
||||
ulong dot_product[vertex_count][vertex_count];
|
||||
|
||||
double elapsed_time = 0.0;
|
||||
const uint64_t iterations = 10000;
|
||||
const ulong iterations = 10;
|
||||
clock_t start_time;
|
||||
|
||||
for (uint64_t i = 0; i < iterations; i++) {
|
||||
random_adjacency(row_length1, matrix1);
|
||||
random_adjacency(row_length2, matrix2);;
|
||||
for (ulong i = 0; i < iterations; i++) {
|
||||
random_adjacency(vertex_count, adjacency_matrix1);
|
||||
random_adjacency(vertex_count, adjacency_matrix2);
|
||||
|
||||
start_time = clock();
|
||||
|
||||
matrix_multiply_basic(row_length1, column_length1, matrix1,
|
||||
row_length2, column_length2, matrix2,
|
||||
new_matrix);
|
||||
gemm_basic(vertex_count, vertex_count, adjacency_matrix1,
|
||||
vertex_count, vertex_count, adjacency_matrix2,
|
||||
dot_product);
|
||||
|
||||
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
printf("%lu iterations of matrix_multiply_basic took roughly %f seconds\n", iterations, elapsed_time);
|
||||
printf("An iteration of matrix_multiply_basic took on average roughly %f seconds\n", elapsed_time/iterations);
|
||||
printf("%lu iterations of gemm_basic took roughly %f seconds\n", iterations, elapsed_time);
|
||||
printf("An iteration of gemm_basic took on average roughly %f seconds\n", elapsed_time/iterations);
|
||||
}
|
||||
|
||||
void test() {
|
||||
const uint64_t vertex_count = 5;
|
||||
uint64_t adjacency_matrix[vertex_count][vertex_count];
|
||||
void benchmark_find_components() {
|
||||
const ulong vertex_count = 100;
|
||||
ulong adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong components[vertex_count][vertex_count];
|
||||
ulong path_matrix[vertex_count][vertex_count];
|
||||
|
||||
read_csv("csv/graph.csv", vertex_count, vertex_count, adjacency_matrix);
|
||||
double elapsed_time = 0.0;
|
||||
const ulong iterations = 100;
|
||||
clock_t start_time;
|
||||
|
||||
printf("G:\n");
|
||||
print_matrix(vertex_count, vertex_count, adjacency_matrix);
|
||||
printf("\n");
|
||||
for (ulong i = 0; i < iterations; i++) {
|
||||
random_adjacency(vertex_count, adjacency_matrix);
|
||||
|
||||
// uint64_t new_matrix[row_length1][column_length1];
|
||||
//
|
||||
// matrix_multiply_basic(row_length1, column_length1, matrix1,
|
||||
// row_length1, column_length1, matrix1,
|
||||
// new_matrix);
|
||||
//
|
||||
// printf("G²:\n");
|
||||
// print_matrix(row_length1, column_length1, new_matrix);
|
||||
// printf("\n");
|
||||
start_time = clock();
|
||||
|
||||
uint64_t distance_matrix[vertex_count][vertex_count];
|
||||
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
|
||||
find_components_basic(vertex_count, path_matrix, components);
|
||||
|
||||
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
printf("%lu iterations of find_components_basic took roughly %f seconds\n", iterations, elapsed_time);
|
||||
printf("An iteration of find_components_basic took on average roughly %f seconds\n", elapsed_time/iterations);
|
||||
|
||||
elapsed_time = 0.0;
|
||||
|
||||
for (ulong i = 0; i < iterations; i++) {
|
||||
random_adjacency(vertex_count, adjacency_matrix);
|
||||
|
||||
start_time = clock();
|
||||
|
||||
find_components_dfs(vertex_count, adjacency_matrix, components);
|
||||
|
||||
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
printf("%lu iterations of find_components_dfs took roughly %f seconds\n", iterations, elapsed_time);
|
||||
printf("An iteration of find_components_dfs took on average roughly %f seconds\n", elapsed_time/iterations);
|
||||
}
|
||||
|
||||
void test_with_basic() {
|
||||
const ulong vertex_count = 24;
|
||||
ulong adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong distance_matrix[vertex_count][vertex_count];
|
||||
ulong path_matrix[vertex_count][vertex_count];
|
||||
ulong eccentricities[vertex_count];
|
||||
ulong radius, diameter, centre[vertex_count];
|
||||
ulong components[vertex_count][vertex_count];
|
||||
ulong bridges[vertex_count][2];
|
||||
ulong articulations[vertex_count];
|
||||
|
||||
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
|
||||
get_eccentricities(vertex_count, distance_matrix, eccentricities);
|
||||
radius = get_radius(vertex_count, eccentricities);
|
||||
diameter = get_diameter(vertex_count, eccentricities);
|
||||
get_centre(vertex_count, eccentricities, radius, centre);
|
||||
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
|
||||
find_components_basic(vertex_count, path_matrix, components);
|
||||
find_bridges_basic(vertex_count, adjacency_matrix, components, bridges);
|
||||
find_articulations_basic(vertex_count, adjacency_matrix, components, articulations);
|
||||
|
||||
printf("distance_matrix:\n");
|
||||
puts("adjacency_matrix:");
|
||||
print_matrix(vertex_count, vertex_count, adjacency_matrix);
|
||||
|
||||
puts("\ndistance_matrix:");
|
||||
print_matrix(vertex_count, vertex_count, distance_matrix);
|
||||
printf("\n");
|
||||
|
||||
puts("\neccentricities:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
printf("\tVertex %lu: %lu\n", index + 1, eccentricities[index]);
|
||||
}
|
||||
|
||||
printf("\nradius: %lu", radius);
|
||||
printf("\ndiameter: %lu", diameter);
|
||||
puts("\ncentre:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (centre[index] == 1) {
|
||||
printf("\tVertex %lu\n", index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
puts("\npath_matrix:");
|
||||
print_matrix(vertex_count, vertex_count, path_matrix);
|
||||
|
||||
puts("\ncomponents:");
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
int empty = 1;
|
||||
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (components[row_index][column_index] != 0) {
|
||||
empty = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\tComponent %lu: {", row_index + 1);
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (components[row_index][column_index] != 0) {
|
||||
printf("%lu, ", components[row_index][column_index]);
|
||||
}
|
||||
}
|
||||
puts("}");
|
||||
}
|
||||
|
||||
puts("\nbridges:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (bridges[index][0] != 0) {
|
||||
printf("\tBridge %lu: {%lu, %lu}\n", index + 1, bridges[index][0], bridges[index][1]);
|
||||
}
|
||||
}
|
||||
|
||||
puts("\narticulations:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (articulations[index] != 0) {
|
||||
printf("\tVertex %lu\n", articulations[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_with_dfs() {
|
||||
const ulong vertex_count = 24;
|
||||
ulong adjacency_matrix[vertex_count][vertex_count];
|
||||
ulong distance_matrix[vertex_count][vertex_count];
|
||||
ulong eccentricities[vertex_count];
|
||||
ulong radius, diameter;
|
||||
ulong centre[vertex_count];
|
||||
ulong components[vertex_count][vertex_count];
|
||||
ulong bridges[vertex_count][2];
|
||||
ulong articulations[vertex_count];
|
||||
|
||||
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
const ulong vertex_count = 1500;
|
||||
ulong (*adjacency_matrix)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(ulong));
|
||||
ulong (*distance_matrix)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(ulong));
|
||||
ulong *eccentricities = malloc(vertex_count * sizeof(ulong));
|
||||
ulong radius, diameter;
|
||||
ulong *centre = malloc(vertex_count * sizeof(ulong));
|
||||
ulong (*components)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(ulong));
|
||||
ulong (*bridges)[vertex_count] = malloc(vertex_count * 2 * sizeof(ulong));
|
||||
ulong *articulations = malloc(vertex_count * sizeof(ulong));
|
||||
|
||||
random_adjacency(vertex_count, adjacency_matrix);
|
||||
*/
|
||||
|
||||
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
|
||||
get_eccentricities(vertex_count, distance_matrix, eccentricities);
|
||||
radius = get_radius(vertex_count, eccentricities);
|
||||
diameter = get_diameter(vertex_count, eccentricities);
|
||||
get_centre(vertex_count, eccentricities, radius, centre);
|
||||
find_components_dfs(vertex_count, adjacency_matrix, components);
|
||||
find_bridges_dfs_v2(vertex_count, adjacency_matrix, components, bridges);
|
||||
find_articulations_dfs_v2(vertex_count, adjacency_matrix, components, articulations);
|
||||
|
||||
puts("\nadjacency_matrix:");
|
||||
print_matrix(vertex_count, vertex_count, adjacency_matrix);
|
||||
|
||||
puts("\ndistance_matrix:");
|
||||
print_matrix(vertex_count, vertex_count, distance_matrix);
|
||||
|
||||
puts("\neccentricities:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
printf("\tVertex %lu: %lu\n", index + 1, eccentricities[index]);
|
||||
}
|
||||
|
||||
printf("\nradius: %lu", radius);
|
||||
printf("\ndiameter: %lu", diameter);
|
||||
puts("\ncentre:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (centre[index] == 1) {
|
||||
printf("\tVertex %lu\n", index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
puts("\ncomponents:");
|
||||
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
|
||||
int empty = 1;
|
||||
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (components[row_index][column_index] != 0) {
|
||||
empty = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\tComponent %lu: {", row_index + 1);
|
||||
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
|
||||
if (components[row_index][column_index] != 0) {
|
||||
printf("%lu, ", column_index + 1);
|
||||
}
|
||||
}
|
||||
puts("}");
|
||||
}
|
||||
|
||||
ulong bridge_number = 1;
|
||||
puts("\nbridges:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (bridges[index][0] != 0) {
|
||||
printf("\tBridge %lu: {%lu, %lu}\n", bridge_number, bridges[index][0], bridges[index][1]);
|
||||
bridge_number++;
|
||||
}
|
||||
}
|
||||
|
||||
puts("\narticulations:");
|
||||
for (ulong index = 0; index < vertex_count; index++) {
|
||||
if (articulations[index] != 0) {
|
||||
printf("\tVertex %lu\n", articulations[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// free(adjacency_matrix);
|
||||
// free(distance_matrix);
|
||||
// free(eccentricities);
|
||||
// free(centre);
|
||||
// free(components);
|
||||
// free(bridges);
|
||||
// free(articulations);
|
||||
}
|
||||
|
||||
void test_with_structs() {
|
||||
ulong row_length = 5, column_length = 5;
|
||||
|
||||
Matrix *adjacency_matrix1 = create_matrix(row_length, column_length);
|
||||
Matrix *adjacency_matrix2 = create_matrix(row_length, column_length);
|
||||
Matrix *dot_product = create_matrix(row_length, column_length);
|
||||
|
||||
random_adjacency_struct(adjacency_matrix1);
|
||||
print_matrix_struct(adjacency_matrix1);
|
||||
putchar('\n');
|
||||
|
||||
random_adjacency_struct(adjacency_matrix2);
|
||||
print_matrix_struct(adjacency_matrix2);
|
||||
putchar('\n');
|
||||
|
||||
gemm_basic_structs(adjacency_matrix1, adjacency_matrix2,dot_product);
|
||||
print_matrix_struct(dot_product);
|
||||
|
||||
free_matrix(adjacency_matrix1);
|
||||
free_matrix(adjacency_matrix2);
|
||||
free_matrix(dot_product);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
test();
|
||||
// benchmark();
|
||||
// benchmark_gemm();
|
||||
// benchmark_find_components();
|
||||
// test_with_basic();
|
||||
// test_with_dfs();
|
||||
test_with_structs();
|
||||
}
|
||||
|
87
matrix.c
87
matrix.c
@ -1,54 +1,71 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "matrix.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
void print_matrix(const uint64_t row_length, const uint64_t column_length, const uint64_t matrix[row_length][column_length]) {
|
||||
for (uint64_t column_index=0; column_index < column_length; column_index++) {
|
||||
for (uint64_t row_index=0; row_index < row_length; row_index++) {
|
||||
void print_matrix(const ulong row_length, const ulong column_length, const ulong matrix[row_length][column_length]) {
|
||||
for (ulong column_index=0; column_index < column_length; column_index++) {
|
||||
for (ulong row_index=0; row_index < row_length; row_index++) {
|
||||
printf("%lu ", matrix[row_index][column_index]);
|
||||
}
|
||||
printf("\n");
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
int matrix_multiply_basic(const uint64_t row_length1, const uint64_t column_length1, const uint64_t matrix1[row_length1][column_length1],
|
||||
const uint64_t row_length2, const uint64_t column_length2, const uint64_t matrix2[row_length2][column_length2],
|
||||
uint64_t output_matrix[row_length1][column_length2]) {
|
||||
|
||||
if (row_length1 != column_length2) {
|
||||
return 1;
|
||||
void print_matrix_struct(const Matrix *matrix) {
|
||||
for (ulong column_index=0; column_index < matrix->column_length; column_index++) {
|
||||
for (ulong row_index=0; row_index < matrix->row_length; row_index++) {
|
||||
printf("%lu ", matrix->values[row_index][column_index]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t sum;
|
||||
void gemm_basic(const ulong row_length1, const ulong column_length1, const ulong matrix1[row_length1][column_length1],
|
||||
const ulong row_length2, const ulong column_length2, const ulong matrix2[row_length2][column_length2],
|
||||
ulong output_matrix[row_length1][column_length2]) {
|
||||
ulong sum;
|
||||
|
||||
for (uint64_t i = 0; i < row_length1; i++) {
|
||||
for (uint64_t j = 0; j < column_length2; j++) {
|
||||
for (ulong i = 0; i < row_length1; i++) {
|
||||
for (ulong j = 0; j < column_length2; j++) {
|
||||
sum = 0;
|
||||
|
||||
for (uint64_t k = 0; k <row_length1; k++) {
|
||||
for (ulong k = 0; k < row_length1; k++) {
|
||||
sum += matrix1[i][k] * matrix2[k][j];
|
||||
}
|
||||
|
||||
output_matrix[i][j] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_csv(const char *file_name, const uint64_t row_length, const uint64_t column_length, uint64_t output_matrix[row_length][column_length]) {
|
||||
void gemm_basic_structs(const Matrix *matrix1, const Matrix *matrix2, Matrix *output_matrix) {
|
||||
ulong sum;
|
||||
|
||||
for (ulong i = 0; i < matrix1->row_length; i++) {
|
||||
for (ulong j = 0; j < matrix2->column_length; j++) {
|
||||
sum = 0;
|
||||
|
||||
for (ulong k = 0; k < matrix1->row_length; k++) {
|
||||
sum += matrix1->values[i][k] * matrix2->values[k][j];
|
||||
}
|
||||
|
||||
output_matrix->values[i][j] = sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int read_csv(const char *file_name, const ulong row_length, const ulong column_length, ulong output_matrix[row_length][column_length]) {
|
||||
FILE *file_ptr;
|
||||
uint64_t bufsize = row_length*2; // have to account for delimiters
|
||||
ulong bufsize = row_length*2+1; // have to account for delimiters
|
||||
char buffer[bufsize];
|
||||
char *value, *file_line;
|
||||
uint64_t row_index = 0, column_index = 0;
|
||||
ulong row_index = 0, column_index = 0;
|
||||
|
||||
file_ptr = fopen(file_name, "r");
|
||||
if (file_ptr == NULL) {
|
||||
printf("Unable to open csv\n");
|
||||
puts("Unable to open csv");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -77,10 +94,26 @@ int read_csv(const char *file_name, const uint64_t row_length, const uint64_t co
|
||||
return 0;
|
||||
}
|
||||
|
||||
void copy(const uint64_t row_length, const uint64_t column_length, const uint64_t input_matrix[row_length][column_length], uint64_t output_matrix[row_length][column_length]) {
|
||||
for (uint64_t row_index = 0; row_index < row_length; row_index++) {
|
||||
for (uint64_t column_index = 0; column_index <column_length; column_index++) {
|
||||
output_matrix[row_index][column_length] = input_matrix[row_index][column_index];
|
||||
}
|
||||
Matrix* create_matrix(ulong row_length, ulong column_length) {
|
||||
ulong **values = (ulong**)malloc(row_length * sizeof(ulong*));
|
||||
|
||||
|
||||
for (ulong index = 0; index < row_length; index++) {
|
||||
values[index] = (ulong*)malloc(column_length * sizeof(ulong));
|
||||
}
|
||||
|
||||
Matrix *matrix = malloc(sizeof(Matrix));
|
||||
matrix->row_length = row_length;
|
||||
matrix->column_length = column_length;
|
||||
matrix->values = values;
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
void free_matrix(Matrix *matrix) {
|
||||
for (ulong index = 0; index < matrix->row_length; index++) {
|
||||
free(matrix->values[index]);
|
||||
}
|
||||
|
||||
free(matrix->values);
|
||||
}
|
||||
|
42
matrix.h
42
matrix.h
@ -1,34 +1,34 @@
|
||||
#ifndef MATRIX_H
|
||||
#define MATRIX_H
|
||||
|
||||
#include <stdint.h>
|
||||
typedef unsigned long ulong;
|
||||
typedef struct matrix {ulong row_length; ulong column_length; ulong **values;} Matrix;
|
||||
|
||||
void print_matrix(const uint64_t row_length,
|
||||
const uint64_t column_length,
|
||||
const uint64_t matrix[row_length][column_length]);
|
||||
void print_matrix(const ulong row_length, const ulong column_length,
|
||||
const ulong matrix[row_length][column_length]);
|
||||
|
||||
void print_matrix_struct(const Matrix *matrix);
|
||||
|
||||
/*
|
||||
First two matrices will be multiplied and
|
||||
restult will be written to output_matrix.
|
||||
Matrix requirements are as specified in the parameters.
|
||||
Function return 0 on success and 1 on failure.
|
||||
Matrix size requirements are as specified in the parameters.
|
||||
*/
|
||||
int matrix_multiply_basic(const uint64_t row_length1,
|
||||
const uint64_t column_length1,
|
||||
const uint64_t matrix1[row_length1][column_length1],
|
||||
const uint64_t row_length2,
|
||||
const uint64_t column_length2,
|
||||
const uint64_t matrix2[row_length2][column_length2],
|
||||
uint64_t output_matrix[row_length1][column_length2]);
|
||||
void gemm_basic(const ulong row_length1, const ulong column_length1,
|
||||
const ulong matrix1[row_length1][column_length1],
|
||||
const ulong row_length2, const ulong column_length2,
|
||||
const ulong matrix2[row_length2][column_length2],
|
||||
ulong output_matrix[row_length1][column_length2]);
|
||||
|
||||
int read_csv(char *file_name,
|
||||
uint64_t row_length,
|
||||
uint64_t column_length,
|
||||
uint64_t output_matrix[row_length][column_length]);
|
||||
void gemm_basic_structs(const Matrix *matrix1, const Matrix *matrix2,
|
||||
Matrix *output_matrix);
|
||||
|
||||
void copy(const uint64_t row_length,
|
||||
const uint64_t column_length,
|
||||
const uint64_t input_matrix[row_length][column_length],
|
||||
uint64_t output_matrix[row_length][column_length]);
|
||||
int read_csv(const char *file_name, const ulong row_length,
|
||||
const ulong column_length,
|
||||
ulong output_matrix[row_length][column_length]);
|
||||
|
||||
Matrix* create_matrix(ulong row_length, ulong column_length);
|
||||
|
||||
void free_matrix(Matrix *matrix);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user