N-th dimensional arithmetic vector

Run Settings
LanguageC
Language Version
Run Command
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define BUFFER_LENGTH 80 typedef struct { int size; double* data; } Vector; Vector v_create(int size, double* source); Vector v_input(); Vector v_load(char* path); void v_destroy(Vector v); void v_save(Vector v, char* path); void v_print(Vector v); int v_equal(Vector a, Vector b); void v_add(Vector v1, Vector v2); void v_sub(Vector v1, Vector v2); double v_dot(Vector v1, Vector v2); Vector va_cross(Vector* vectors, int count); int v_collinear(Vector v1, Vector v2); int va_collinear(Vector* vectors, int count); int va_complanar(Vector* vectors, int count); Vector v_create(int size, double* source) { if (size < 0) size = 0; Vector v; v.size = size; v.data = malloc(size * sizeof(double)); for (int i = 0; i < v.size; i++) { v.data[i] = 0; } if (source) { for (int i = 0; i < v.size; i++) { v.data[i] = source[i]; } } return v; } Vector v_input() { char buffer[BUFFER_LENGTH]; int size; printf("Input Vector size (int): "); while (1) { fgets(buffer, BUFFER_LENGTH, stdin); if (sscanf(buffer, "%i", &size) == 1) break; printf( "Error while reading input.\n" "Try again with correct number (int): " ); } Vector v = v_create(size, NULL); printf("Input %i values separated by new line (double): \n", size); for (int i = 0; i < size; i++) { fgets(buffer, BUFFER_LENGTH, stdin); if (sscanf(buffer, "%lf", &v.data[i]) != 1) { printf( "Error while reading input.\n" "Starting over from #[%i] (double): ", i ); i--; } } return v; } void v_print(Vector v) { printf("{ "); for (int i = 0; i < v.size; i++) { printf("%lf ", v.data[i]); } printf("}"); } Vector v_load(char* path) { char buffer[BUFFER_LENGTH]; int size; Vector v; FILE* file = fopen(path, "r"); if (!file) { printf("Error while opening file [%s]. Returning empty vector...\n", path); return v_create(0, NULL); } fgets(buffer, BUFFER_LENGTH, file); if (sscanf(buffer, "%i", &size) != 1) { printf("Error while reading vector size [%s]. Setting size to 0...\n", path); size = 0; } v = v_create(size, NULL); for (int i = 0; i < size; i++) { fgets(buffer, BUFFER_LENGTH, file); if (sscanf(buffer, "%lf", &v.data[i]) != 1) { printf("Error while reading vector data [%s]. Returning empty vector...\n", path); v_destroy(v); } } return v; } void v_save(Vector v, char* path) { FILE* file = fopen(path, "w"); if (file == NULL) { printf("Error while saving vector to file [%s]\n", path); return; } fprintf(file, "%i\n", v.size); for (int i = 0; i < v.size; i++) { fprintf(file, "%lf\n", v.data[i]); } printf("Vector saved [%s]\n", path); } void v_destroy(Vector v) { v.size = 0; free(v.data); } int v_equal(Vector v1, Vector v2) { if (v1.size == v2.size) { for (int i = 0; i < v1.size; i++) { if (v1.data[i] != v2.data[i]) return FALSE; } return TRUE; } return FALSE; } void v_add(Vector v1, Vector v2) { if (v2.size > v1.size) { v1.data = realloc(v1.data, v2.size * sizeof(double)); for (int i = v1.size; i < v2.size; i++) { v1.data[i] = 0; } v1.size = v2.size; } for (int i = 0; i < v1.size; i++) { v1.data[i] += v2.data[i]; } } void v_sub(Vector v1, Vector v2) { if (v2.size > v1.size) { v1.data = realloc(v1.data, v2.size * sizeof(double)); for (int i = v1.size; i < v2.size; i++) { v1.data[i] = 0; } v1.size = v2.size; } for (int i = 0; i < v1.size; i++) { v1.data[i] -= v2.data[i]; } } void v_mul(Vector v, double k) { for (int i = 0; i < v.size; i++) { v.data[i] *= k; } } int v_collinear(Vector v1, Vector v2) { Vector vectors[2] = {v1, v2}; Vector cross = va_cross(vectors, 2); for (int i = 0; i < cross.size; i++) { if (cross.data[i] != 0) return FALSE; } return TRUE; } int va_collinear(Vector* vectors, int count) { for (int i = 1; i < count; i++) { if (!v_collinear(vectors[i], vectors[0])) return FALSE; } return TRUE; } int va_complanar(Vector* vectors, int count) { return FALSE; } double v_dot(Vector v1, Vector v2) { int min_size = v1.size; if (v2.size < v1.size) min_size = v2.size; double sum = 0; for (int i = 0; i < min_size; i++) { sum += v1.data[i] * v2.data[i]; } return sum; } Vector va_cross(Vector* vectors, int count) { int size = count + 1; for (int i = 0; i < count; i++) { if (vectors[i].size != size) return v_create(0, NULL); } Vector result = v_create(size, NULL); if (size == 2) { result.data[0] = vectors[0].data[1]; result.data[1] = -vectors[0].data[0]; return result; } for (int r = 0; r < size; r++) { double sub_det = 0; for (int offset = 0; offset < count; offset++) { double positive_mul = 1; double negative_mul = 1; for (int w = 0; w < count; w++) { int index = (r + w + offset + 1) % size; if (index == r) index = (index + 2) % size; positive_mul *= vectors[w].data[index]; negative_mul *= vectors[count - 1 - w].data[index]; } sub_det += positive_mul; sub_det -= negative_mul; } result.data[r] = sub_det; } return result; } /* main */ int main() { Vector a = v_create(3, (double[]) { 1, 2, 3 }); Vector b = v_create(3, (double[]) { 4, 5, 6 }); Vector vectors[] = {a, b}; Vector cross = va_cross(vectors, 2); printf("\nCross result:\n"); v_print(cross); return 0; }
Editor Settings
Theme
Key bindings
Full width
Lines