#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;
}