Home > Blockchain >  How to simulate all arguments combinations values of a function and obtain result as list
How to simulate all arguments combinations values of a function and obtain result as list

Time:09-04

Assume we have the following function :

     library("doBy")
     library("FNN")
      
     x=-0.5 1:6
     y=c(0.5,1.5)
     z=y 

   fct_3<function(x,y,z,Alpha=0.6,Max_N_sensors=4,N_targets=7,printing=TRUE,summarized_result=TRUE){
          
          distance=as.matrix(dist(expand.grid(x,y,z),diag = 1,upper = 1))
          
          P=as.matrix(Alpha*exp(-Alpha*distance))    
          
          print(c("P dimensions :",dim(P)))
          
          if(Max_N_sensors>=nrow(P)|| N_targets>=nrow(P) || Max_N_sensors N_targets>nrow(P) ){
            
            print("Error : incorrect inputs ")    
            
            return(0)
            
          }  
          
          diag(P)<-0
          
          rownames(P)<-paste("Sensor_location",1:nrow(P))
          
          colnames(P)<-paste("Target_location",1:nrow(P))
          
          R=P
          
          N_sensors=0
          
          Sensors_Positions=c()
          
          kn=get.knnx(P,rbind(apply(P,2,max)), k=Max_N_sensors)
          
          if(printing==TRUE){
           
          print("KNN")
            
          print(kn)  
          
          }
          
          while (N_sensors<=Max_N_sensors) { 
            
            N_sensors=N_sensors 1
            
            r_ind=kn$nn.index[N_sensors]
            
            r_val=mean(P[r_ind,])
            
            Sensors_Positions=c(Sensors_Positions,r_ind)
            
            if(printing==TRUE){
              
            print(c("Selected Sensor",r_ind , "Total of used sensors",N_sensors))
            
            print("Sensors_Positions")
            
            print(Sensors_Positions)
            
            }
            
            if(N_sensors==Max_N_sensors){
              
              means=apply(P,1,mean)
              
              Sensors_Positions=Sensors_Positions[!is.na(Sensors_Positions)]
              
              Targets_locations=setdiff(1:nrow(P),Sensors_Positions)
              
              if(printing==TRUE){
                
              print("Possible targets locations")
              
              print(Targets_locations)
              
              }
              
              R[Targets_locations,]=0  
              
              R[,Sensors_Positions]=0  
              
              R=cbind(R,cumulative_sensor_detection=apply(R, 1,function(x) 1-prod(1-x[x!=0 & !is.na(x)])  ))
              
              R=rbind(R,cumulattive_detection_by_Target=apply(R,2,function(x) 1-prod(1-x[x!=0 & !is.na(x)])))
              
              Targets_Positions=sort(R["cumulattive_detection_by_Target",][1:nrow(P)],decreasing = TRUE,index.return=TRUE)$ix[1:N_targets]
              
              result=list(R,K_nearests=kn,N_sensors=Max_N_sensors,sensors_positions=Sensors_Positions,Targets_locations=Targets_Positions,Targets_cum_detection=R[nrow(R),Targets_Positions])
              
              
              if(summarized_result==TRUE){
                
              result=list(N_sensors=Max_N_sensors,sensors_positions=Sensors_Positions,Targets_locations=Targets_Positions,Targets_cum_detection=R[nrow(R),Targets_Positions])
                
              }
              
              return(result)
              
            }
            
            
          }
          
          
        }

An example of a run :

list_1=fct_3(x,y,z,Alpha=0.4362923,Max_N_sensors=14,N_targets=2,printing=FALSE,summarized_result=TRUE)

What interest me the more is the 4th element of the returned list. I need it to draw some curves :

list_1[[4]],list_1[["Targets_cum_detection"]]

In the other hand , i have this combination of arguments / parameters :

  parameters=expand.grid(Alpha=seq(0,1,0.1),Max_N_sensors=1:22,N_targets=2)

nrow(parameters)
[1] 242

Sorting by Alpha :

parameters=parameters[order(parameters[,1],decreasing=FALSE),]

Request :

Each row of parameters represent a run. Examples :

1/ First row :

list_1=fct_3(x,y,z,Alpha=parameters[1,1],Max_N_sensors=parameters[1,2],N_targets=parameters[1,3],printing=FALSE,summarized_result=TRUE) 

2/ Second row :

list_2=fct_3(x,y,z,Alpha=parameters[2,1],Max_N_sensors=parameters[2,2],N_targets=parameters[2,3],printing=FALSE,summarized_result=TRUE) 

etc...

I need to build the list of all runs based on parameters.

I tried without success :

lapply(1:nrow(parameters), function(x) return(fct_3(x,y,z,Alpha=parameters[x,1],Max_N_sensors=parameters[x,2],N_targets=2,printing=FALSE,summarized_result=TRUE)))

Doing this gives :

list_of_runs=lapply(1:nrow(parameters), function(x) return(fct_3(x,y,z,Alpha=parameters[x,1],Max_N_sensors=parameters[x,2],N_targets=2,printing=FALSE,summarized_result=TRUE)))
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "
[1] "Error : incorrect inputs "

For example , you will see that

list_of_runs[[242]]
[1] 0

However we obtain with the associated parameters[242,] the following results, list_of_runs[[242]] should be this :

fct_3(x,y,z,Alpha=parameters[242,1],Max_N_sensors=parameters[242,2],N_targets=2,printing=FALSE,summarized_result=TRUE)
$N_sensors
[1] 22

$sensors_positions
 [1]  9 10 15 16  4 21  3 22  8 14 11  5 17 23  2 20 13  7 18 12  1 24

$Targets_locations
[1]  6 19

$Targets_cum_detection
 Target_location 6 Target_location 19 
          0.956163           0.956163 

Hope my question clear and feasible.

Thanks before.

CodePudding user response:

The problem is already solved but here is a apply version. It avoids having to create the results list beforehand.

x <- -0.5   1:6
y <- c(0.5, 1.5)
z <- y 

parameters <- expand.grid(Alpha = seq(0, 1, 0.1),
                          Max_N_sensors = 1:22,
                          N_targets = 2)
parameters <- parameters[order(parameters[, 1], decreasing = FALSE), ]

list_of_runs <- apply(parameters, 1, \(params) {
  fct_3(x, y, z,
        Alpha = params[1],
        Max_N_sensors = params[2],
        N_targets = params[3],
        printing = FALSE,
        summarized_result = TRUE)
})
#> P dimensions : 24 24 
#> P dimensions : 24 24 
#> P dimensions : 24 24 
#> [omitted]
#> P dimensions : 24 24

list_of_runs[[242]]
#> $N_sensors
#> Max_N_sensors 
#>            22 
#> 
#> $sensors_positions
#>  [1]  9 10 15 16  4 21  3 22  8 14 11  5 17 23  2 20 13  7 18 12  1 24
#> 
#> $Targets_locations
#> [1]  6 19
#> 
#> $Targets_cum_detection
#>  Target_location 6 Target_location 19 
#>           0.956163           0.956163

Created on 2022-09-03 by the reprex package (v2.0.1)

CodePudding user response:

Problem solved.

I just tried :

list_of_runs=list()
    
for(i in 1:nrow(parameters)){
      
      list_of_runs[[i]]=fct_3(x,y,z,Alpha=parameters[i,1],Max_N_sensors=parameters[i,2],N_targets=2,printing=FALSE,summarized_result=TRUE)
    }

This gives the correct output:

list_of_runs[[242]]
$N_sensors
[1] 22

$sensors_positions
 [1]  9 10 15 16  4 21  3 22  8 14 11  5 17 23  2 20 13  7 18 12  1 24

$Targets_locations
[1]  6 19

$Targets_cum_detection
 Target_location 6 Target_location 19 
          0.956163           0.956163 
  •  Tags:  
  • r
  • Related