From a6dd80098662d29ab49a85972bd016464583d3cc Mon Sep 17 00:00:00 2001 From: fanasina Date: Fri, 14 Jun 2024 01:41:50 +0200 Subject: [PATCH] add scalar product tensor --- tensor_t/src/tensor_t/tensor_t.c | 29 ++++++++++++++ tensor_t/src/tensor_t/tensor_t.h | 4 +- tensor_t/test/is_good.c | 67 ++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/tensor_t/src/tensor_t/tensor_t.c b/tensor_t/src/tensor_t/tensor_t.c index 604e61c..d1b4e9d 100644 --- a/tensor_t/src/tensor_t/tensor_t.c +++ b/tensor_t/src/tensor_t/tensor_t.c @@ -1086,6 +1086,35 @@ void tensorContractnProdNotOpt_##type(tensor_##type** MM, tensor_##type *M0, ten FREE_dM_S_ ; \ }\ \ +/* dot product = of 2 tensors same dimensions M0, M1, dim0, dim1 == contract (dim0 size) product of M0' M1' of dim0' and dim1' / dim0->perm = [1, dim0-> perm] and dim1'->perm = [dim1->perm, 1] */ \ +type scalarProduct_dep_contractProd_##type(tensor_##type *M0, tensor_##type *M1, size_t nbthreads ,void (*tensorContractVar)(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread )){\ + type ret = 0;\ + if(is_equal_dim(M0->dim, M1->dim)){/* */\ + dimension * d0 = create_dim(M0->dim->size + 1);\ + dimension * d1 = create_dim(M1->dim->size + 1);\ + size_t i;\ + d0->perm[0] = 1;\ + for(i=0; idim->size; ++i) d0->perm[i+1] = M0->dim->perm[i];\ + for(i=0; idim->size; ++i) d1->perm[i] = M1->dim->perm[i];\ + d1->perm[i] = 1;\ + tensor_##type *M_0=CREATE_TENSOR_##type(d0);\ + tensor_##type *M_1=CREATE_TENSOR_##type(d1);\ + copy_tensor_##type(M_0,M0);\ + copy_tensor_##type(M_1,M1);\ + tensor_##type *M_=NULL;\ + tensorContractVar(&M_,M_0,M_1,M0->dim->size,nbthreads);\ + ret = M_->x[0];\ + free_tensor_##type(M_0);\ + free_tensor_##type(M_1);\ + free_tensor_##type(M_);\ + }\ + return ret;\ +}\ +\ +type scalarProduct_0_##type(tensor_##type *M0, tensor_##type *M1){\ + return scalarProduct_dep_contractProd_##type(M0,M1,4,tensorContractnProdThread_##type);\ +\ +}\ \ /*format_file: [dim]((x,x,a)(a,x,a)) | example:[2,3,4](((a0,b0,c0,d0)(a1,b1,c1,d1)(a2,b2,c2,d2))((e0,f0,g0,h0)(e1,f1,g1,h1)(e2,f2,g2,h2)))*/\ tensor_##type * parseInput_withDim_to_tensor_##type(char *input){\ diff --git a/tensor_t/src/tensor_t/tensor_t.h b/tensor_t/src/tensor_t/tensor_t.h index a1435e5..03fd9da 100644 --- a/tensor_t/src/tensor_t/tensor_t.h +++ b/tensor_t/src/tensor_t/tensor_t.h @@ -20,7 +20,7 @@ tensor_##type* CREATE_TENSOR_FROM_CPY_DIM_##type(dimension *dim);\ void _RECREATE_TENSOR_IF_NOT_THE_SAME_DIM_OR_NULL_##type(tensor_##type **M, dimension *dd);\ tensor_##type* CLONE_TENSOR_##type(tensor_##type *tens);\ void free_tensor_##type(tensor_##type * tens); \ -void copy_tensor_##type(tensor_##type * dst, tensor_##type * src);\ +int copy_tensor_##type(tensor_##type * dst, tensor_##type * src);\ tensor_##type * sub_minus_tensor_head_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim); \ tensor_##type * sub_minus_tensor_tail_##type(tensor_##type *rootens, size_t minuSubdim, size_t rankInDim); \ tensor_##type * sub_tensor_head_##type(tensor_##type *rootens, size_t subdim, size_t rankInDim); \ @@ -42,6 +42,8 @@ void tensorProdThrea2d_##type(tensor_##type **MM, tensor_##type *M0, tensor_##ty void tensorContractnProdThread_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread); \ void tensorContractnPro2dThread_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread); \ void tensorContractnProdNotOpt_##type(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber); \ +type scalarProduct_dep_contractProd_##type(tensor_##type *M0, tensor_##type *M1, size_t nbthreads ,void (*tensorContractVar)(tensor_##type **MM, tensor_##type *M0, tensor_##type *M1, size_t contractionNumber, size_t nbthread ));\ +type scalarProduct_0_##type(tensor_##type *M0, tensor_##type *M1);\ void init_random_x_##type(tensor_##type *M, type minR, type maxR, int randomRange);\ tensor_##type * parseInput_withDim_to_tensor_##type(char *input);\ void parseInputOutput_withDim_to_tensors_##type(tensor_##type **Tpart1, tensor_##type **Tpart2, char *input, size_t pivotSplit);\ diff --git a/tensor_t/test/is_good.c b/tensor_t/test/is_good.c index 792d5ae..cfe7e7d 100644 --- a/tensor_t/test/is_good.c +++ b/tensor_t/test/is_good.c @@ -1759,6 +1759,73 @@ TEST(tensorContractnProd_TYPE_DOUBLE_2_2 ){ +TEST(scalProduct){ + dimension *d0=create_dim(3); + dimension *d1=create_dim(3); + + + dimension *d_0=create_dim(2); + dimension *d_1=create_dim(2); + + + d0->perm[0]=1; + d0->perm[1]=2; //3; + d0->perm[2]=3; //3; + + d1->perm[0]=2; + d1->perm[1]=3; //3; + d1->perm[2]=1; //3; + + + d_0->perm[0]=2; + d_0->perm[1]=3; //3; + d_1->perm[0]=2; + d_1->perm[1]=3; //3; + + + + + tensor_TYPE_DOUBLE *M0 = CREATE_TENSOR_TYPE_DOUBLE(d0); + tensor_TYPE_DOUBLE *M1 = CREATE_TENSOR_TYPE_DOUBLE(d1); + + tensor_TYPE_DOUBLE *M_0 = CREATE_TENSOR_TYPE_DOUBLE(d_0); + tensor_TYPE_DOUBLE *M_1 = CREATE_TENSOR_TYPE_DOUBLE(d_1); + + for(size_t i=0; idim->rank;++i) { + M0->x[i]=2 ; + M_0->x[i]=2 ; + } + for(size_t i=0; idim->rank;++i) { + M1->x[i]=3; + M_1->x[i]=3; + } + print_tensor_double(M0,"M0"); + print_tensor_double(M1,"M1"); + + tensor_TYPE_DOUBLE *M=NULL; + + tensorContractnProd_TYPE_DOUBLE(&M, M0,M1,2); + + print_tensor_double(M,"M"); + + double dotProd = scalarProduct_0_TYPE_DOUBLE(M_0,M_1); + + EXPECT_EQ_TYPE_DOUBLE(dotProd, M->x[0]); + + // for(size_t i=0;idim->rank;++i) + // EXPECT_EQ_TYPE_DOUBLE(M->x[i],MnO->x[i]); + + + free_tensor_TYPE_DOUBLE(M); + free_tensor_TYPE_DOUBLE(M0); + free_tensor_TYPE_DOUBLE(M1); + free_tensor_TYPE_DOUBLE(M_0); + free_tensor_TYPE_DOUBLE(M_1); + +} + + + int main(int argc, char **argv){