Как добавить два вектора со скаляром и сохранить результат в одном из двух векторов и вернуть этот вектор из функции в C? - PullRequest
1 голос
/ 20 января 2020

Я застрял здесь с небольшой проблемой: Я готовлюсь к экзамену, и моей задачей было написать программу, которая может выполнять следующие действия: Есть два заданных вектора x и y , которые являются элементом R ^ (n) , и каждый из них представляет собой двойной массив длины n , где n является элементом N . Кроме того, в качестве элемента R задана двойная переменная a . Мне нужно написать четыре функции vec_plus , vec_mult , dotprod и norm2 , которые имеют следующую цель: (Мои проблемы до сих пор касаются только vec_plus и vec_mult ) 1. vec_plus должен вычислить x + a * y (элемент R ^ n ) и сохранить его в x ! 2. vec_mult должен вычислить a * x (элемент R ^ n ) и сохранить его в x ! 3. dotprod должен вычислить скалярное произведение <<strong> x , y > и вернуть его. 4. norm2 должен вычислить евклидову норму || x || = sqrt ( <<strong> x , x > ) и верните его. Теперь вот мой код:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

double vec_plus(double* x, double* y, double a, unsigned int n) {
    unsigned int i;
    for (i = 0; i < n; i++) { 
        x[i] = x[i] + (a * y[i]);
    }
    return *x;
}

double vec_mult(double* x, double a, unsigned int n) {
    unsigned int i;
    for (i = 0; i < n; i++) { x[i] = a * x[i]; }
    return *x;
}

double dotprod(double* x, double* y, unsigned int n) {
    unsigned int i;
    double z = 0;
    for (i = 0; i < n; i++) { z = z + x[i] * y[i]; }
    return z;
}

double norm2(double* x, unsigned int n) {
    unsigned int i;
    double z = 0;
    for (i = 0; i < n; i++) { z = z + hypot(x[i], x[i]); }
    return z;
}

int main(void) {
    unsigned int n;
    unsigned int i;
    printf("Please enter n = "); scanf_s("%u", &n);
    double* x, * y, a;
    x = (double*)malloc(n * sizeof(double));
    y = (double*)malloc(n * sizeof(double));
    if (x == NULL || y == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); }
    for (i = 0; i < n; i++) {
        printf("Please enter x_%d = ", i); scanf_s("%lf", &x[i]);
    }
    for (i = 0; i < n; i++) {
        printf("Please enter y_%d = ", i); scanf_s("%lf", &y[i]);
    }
    printf("Please enter your scalar a = "); scanf_s("%lf", &a);

    for (i = 0; i < n; i++) {
        printf("\nvec_plus_%d = %lf", i, vec_plus(x, y, a, n));
    }
    for (i = 0; i < n; i++) {
        printf("\nvec_mult_%d = %lf", i, vec_mult(x, a, n));
    }

    free(x); free(y);
    return 0;
}

У меня есть ощущение, что я мог ошибиться в распределении памяти, но не могу обнаружить свою ошибку и не уверен. В качестве примера я покажу вам мой вход , выход , который я ожидал, и фактический выход .

*My input*
Please enter n = 3
Please enter x_0 = 1
Please enter x_1 = 2
Please enter x_2 = 3
Please enter y_0 = 3
Please enter y_1 = 2
Please enter y_2 = 1
Please enter your scalar a = 6

*Output I expect/want*
vec_plus_0 = 19.000000
vec_plus_1 = 14.000000
vec_plus_2 = 9.000000
vec_mult_0 = 6.000000
vec_mult_1 = 12.000000
vec_mult_2 = 18.000000

*Actual output*
vec_plus_0 = 19.000000
vec_plus_1 = 37.000000
vec_plus_2 = 55.000000
vec_mult_0 = 330.000000
vec_mult_1 = 1980.000000
vec_mult_2 = 11880.000000

Вот как я представлял, что мой код будет работать, когда я его написал: Допустим, я взял тот же ввод , как упомянуто.

*My input*
Please enter n = 3
Please enter x_0 = 1
Please enter x_1 = 2
Please enter x_2 = 3
Please enter y_0 = 3
Please enter y_1 = 2
Please enter y_2 = 1
Please enter your scalar a = 6

То, что я представляю себе, происходит в этой части кода:

double vec_plus(double* x, double* y, double a, unsigned int n) {
    unsigned int i;
    for (i = 0; i < n; i++) { 
        x[i] = x[i] + (a * y[i]);
    }
    return *x;
}

function gets passed values of x, y, the scalar a and the length n.
now we get in the for loop with:
x[0] = x[0] + (a * y[0]); //I know the parentheses are redundant but i kind of tried all I could
x[0] = 1 + (6 * 3) // x[0] = 19

x[1] = x[1] + (a * y[1]);
x[1] = 2 + (6 * 2) // x[1] = 14

x[2] = x[2] + (a * y[2]);
x[2] = 3 + (6 * 1) // x[2] = 9

Теперь очевидно, что это не фактический вывод . Может кто-нибудь помочь мне решить эту проблему? Заранее спасибо и хорошего дня!

1 Ответ

0 голосов
/ 20 января 2020

vec_plus возвращает значение первого элемента массива x:

double vec_plus(double* x, double* y, double a, unsigned int n) {
    unsigned int i;
    for (i = 0; i < n; i++) { 
        x[i] = x[i] + (a * y[i]);
    }
    return *x;  // returns value of the first element of x, x[0].
}

Так что каждый раз, когда вы вызываете:

printf("\nvec_plus_%d = %lf", i, vec_plus(x, y, a, n));

внутри for-l oop в main() вы не получите ожидаемые значения x[0], x[1] и x[2] в этом порядке. Вы получаете и распечатываете значение x[0] на каждой итерации.

Кроме того, x[0] меняется каждый раз, когда вы вызываете функцию vec_plus:

x[i] = x[i] + (a * y[i]);  // x[0] is changing each time vec_plus() is called.

Так что вы не делаете получить значения x[1] и x[2], вы получите только измененное значение x[0], которое меняется при каждом вызове на vec_plus на каждой итерации в main():

x[i] = x[i] + (a * y[i]);
_________________________

1.Walkthrough, 1. call to vec_plus: 
x[0] = 1 + (6 * 3) // value of x[0] after this statement = 19

2.Walkthrough, 2. call to vec_plus:  
x[0] = 19 + (6 * 3) // value of x[0] after this statement = 37

3.Walkthrough, 3. call to vec_plus:  
x[0] = 37 + (6 * 3) //  value of x[0] after this statement = 55

Единственное, что вам нужно сделать, это изменить возвращаемое значение vec_plus:

return x[i];

и обернуть итерацию внутри vec_plus:

    unsigned int i;
    for (i = 0; i < n; i++) { 
        x[i] = x[i] + (a * y[i]);
    }

Вместо этого используйте i из итерации в main (). Обратите внимание на i в качестве аргумента / параметра vec_plus:

double vec_plus(double* x, double* y, double a, unsigned int n, unsigned int i) {

    x[i] = x[i] + (a * y[i]);

    return x[i];  
}

for-l oop в main ():

    for (i = 0; i < n; i++) {
        printf("\nvec_plus_%d = %lf", i, vec_plus(x, y, a, n, i));
    }

То же самое относится к * Функция 1044 *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...