-1

im fairly new to C.

i've written the following code. and all the following functions are nearly identical. i just want to know is there is a way to reduce the following functions into a generic one

struct tensor add(struct tensor t1, struct tensor t2){

    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] + t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
}

struct tensor sub(struct tensor t1, struct tensor t2){

    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] - t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
}

struct tensor mul(struct tensor t1, struct tensor t2){

    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] * t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
}

there are more functions. one for every operator with the following format

struct tensor genericfunc(struct tensor t1, struct tensor t2){

    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] ?? t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
}
hammi
  • 804
  • 5
  • 14
  • 1
    it can be but it depends on how you can flexibly change that function. for example, is it possible for the generic function to receive third argument as an indicator? – Ben Eslami Dec 22 '20 at 22:57
  • yes, passing an indicator as is probable – hammi Dec 22 '20 at 22:58

3 Answers3

4
#define definefunc(name, op)                \
Tensor name(Tensor t1, Tensor t2) {         \
    int data[t1.size];                      \
    for (int i = 0; i < t1.size; ++i)       \
       data[i] = t1.data[i] op t2.data[i];  \
                                            \
    return Tensor(t1.rank, t1.shape, data); \
}

definefunc(add, +)
definefunc(sub, -)
definefunc(mul, *)

or

typedef int (*TensorOp)(int, int)

Tensor genericfunc(Tensor t1, Tensor t2, TensorOp op) {
    int data[t1.size];
    for (int i = 0; i < t1.size; ++i)
       data[i] = op(t1.data[i], t2.data[i]);

    return Tensor(t1.rank, t1.shape, data);
}

int TensorOp_add(int a, int b) { return a + b; }
int TensorOp_sub(int a, int b) { return a - b; }
int TensorOp_mul(int a, int b) { return a * b; }

Tensor add(Tensor t1, Tensor t2) { return genericfunc(t1, t2, TensorOp_add); }
Tensor sub(Tensor t1, Tensor t2) { return genericfunc(t1, t2, TensorOp_sub); }
Tensor mul(Tensor t1, Tensor t2) { return genericfunc(t1, t2, TensorOp_mul); }

The above snippets presume the following to avoid using struct everywhere:

typedef struct tensor Tensor;
ikegami
  • 367,544
  • 15
  • 269
  • 518
0

This honestly sounds like a problem that does not need a fix.

But you could do something like this:

struct tensor genericfunc(struct tensor t1, char op, struct tensor t2) {
    int data[t1.size];

    int i = 0;
    switch(op) {
    case '+': while (i < t1.size) { data[i] = t1.data[i] + t2.data[i]; i++; } break;
    // Implement the rest of the ops here
    }

    return Tensor(t1.rank, t1.shape, data);
}
klutt
  • 30,332
  • 17
  • 55
  • 95
0

yer you can add a decider on you'r parameters

struct tensor add(struct tensor t1, struct tensor t2,int decider){
    if(decider==1){
    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] + t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
    }

   if(decider ==2){

    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] - t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
}

if (decider ==3){

    int data[t1.size];

    int i = 0;
    while (i < t1.size) { data[i] = t1.data[i] * t2.data[i]; i++; }

    return Tensor(t1.rank, t1.shape, data);
}

well i hope that's what you wanted