private void FixedUpdate() { FixUpdateCount += 1; Rx_MPC1 = Rx_Seen_MPC_Script.seen_MPC1; Rx_MPC1_att = Rx_Seen_MPC_Script.seen_MPC1_att; Rx_MPC2 = Rx_Seen_MPC_Script.seen_MPC2; Rx_MPC2_att = Rx_Seen_MPC_Script.seen_MPC2_att; Rx_MPC3 = Rx_Seen_MPC_Script.seen_MPC3; Rx_MPC3_att = Rx_Seen_MPC_Script.seen_MPC3_att; Tx_MPC1 = Tx_Seen_MPC_Script.seen_MPC1; Tx_MPC1_att = Tx_Seen_MPC_Script.seen_MPC1_att; Tx_MPC2 = Tx_Seen_MPC_Script.seen_MPC2; Tx_MPC2_att = Tx_Seen_MPC_Script.seen_MPC2_att; Tx_MPC3 = Tx_Seen_MPC_Script.seen_MPC3; Tx_MPC3_att = Tx_Seen_MPC_Script.seen_MPC3_att; /////////////////////////////////////////////////////////////////////////////////// /// LOS /////////////////////////////////////////////////////////////////////////////////// float dtLoS = 0; float PathGainLoS = 0; float LOS_distance = 0; if (!Physics.Linecast(Tx.transform.position, Rx.transform.position)) { Vector3 LoS_dir = (Tx.transform.position - Rx.transform.position).normalized; Vector3 Tx_fwd = Tx.transform.forward; Vector3 Rx_fwd = Rx.transform.forward; float cos_Tx = -1; float cos_Rx = -1; float K_antanne_pattern; if (Tx_Antenna_pattern) { cos_Tx = Vector3.Dot(-LoS_dir, Tx_fwd); } if (Rx_Antenna_pattern) { cos_Rx = Vector3.Dot(LoS_dir, Rx_fwd); } K_antanne_pattern = 0.25f * (1 - cos_Rx - cos_Tx + cos_Rx * cos_Tx); flag_LoS = 1; if (LoS_Start == 0) { LoS_Start = FixUpdateCount; Debug.Log("LoS Start " + LoS_Start); } // finding the start time of LoS if (LOS_Tracer) { Debug.DrawLine(Tx.transform.position, Rx.transform.position, Color.magenta); } LOS_distance = (Tx.transform.position - Rx.transform.position).magnitude; //Debug.Log("Distance = " + LOS_distance); //LOS_distance = 200; dtLoS = LOS_distance / SpeedofLight;// + 1000/SpeedofLight; PathGainLoS = (1 / (LOS_distance)) * K_antanne_pattern; float hbyd = 3.4f / LOS_distance; // 2h/d; h = 1.7meters float Rparallel = (RelativePermitivity * hbyd - Z) / (RelativePermitivity * hbyd + Z); float Rperpendicular = (hbyd - Z) / (hbyd + Z); float Rcoef = (float)Math.Sqrt(0.5f * (Rparallel * Rparallel + Rperpendicular * Rperpendicular)); //PathGainLoS -= PathGainLoS * Rcoef * Rcoef / 2; //float h2byd = 5.78f / LOS_distance; // 2 h^2/2 EdgeEffect(FixUpdateCount - LoS_Start, out EdgeEffect_LoS); // the follwing can be done due to manual calculation of the LoS End if (FixUpdateCount > 100 && FixUpdateCount < 126) { EdgeEffect(124 - FixUpdateCount, out EdgeEffect_LoS); } } /*else * { * if (flag_LoS == 1) * { * flag_LoS = 2; * LoS_End = FixUpdateCount; * Debug.Log("LoS End " + LoS_End); * // remember the last LoS channel * for (int i = 0; i < H_LoS.Length; i++) * { * H_old[i] = H_LoS[i]; * } * } // finding the end time of LoS * }*/ //Debug.Log("Edge effect coefficient = " + EdgeEffect_LoS); var dtLoSParallel = new NativeArray <float>(1, Allocator.TempJob); var distanceLoSParallel = new NativeArray <float>(1, Allocator.TempJob); var PathGainLoSParallel = new NativeArray <float>(1, Allocator.TempJob); for (int i = 0; i < dtLoSParallel.Length; i++) { dtLoSParallel[i] = dtLoS; distanceLoSParallel[i] = LOS_distance; PathGainLoSParallel[i] = PathGainLoS; } dtLoSParallel.Dispose(); distanceLoSParallel.Dispose(); PathGainLoSParallel.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// MPC1 /////////////////////////////////////////////////////////////////////////////////// var RxArray1 = new NativeArray <int>(Rx_MPC1.Count, Allocator.TempJob); var RxArray1_att = new NativeArray <float>(Rx_MPC1.Count, Allocator.TempJob); var TxArray1 = new NativeArray <int>(Tx_MPC1.Count, Allocator.TempJob); var TxArray1_att = new NativeArray <float>(Tx_MPC1.Count, Allocator.TempJob); var possiblePath1 = new NativeArray <Path1>(Tx_MPC1.Count, Allocator.TempJob); var dtMPC1Array = new NativeArray <float>(Tx_MPC1.Count, Allocator.TempJob); var PathGainMPC1 = new NativeArray <float>(Tx_MPC1.Count, Allocator.TempJob); for (int i = 0; i < Rx_MPC1.Count; i++) { RxArray1[i] = Rx_MPC1[i]; RxArray1_att[i] = Rx_MPC1_att[i]; } for (int i = 0; i < Tx_MPC1.Count; i++) { TxArray1[i] = Tx_MPC1[i]; TxArray1_att[i] = Tx_MPC1_att[i]; possiblePath1[i] = empty_path; } CommonMPC1Parallel commonMPC1Parallel = new CommonMPC1Parallel { Speed_of_Light = SpeedofLight, MPC1 = SeenMPC1Table, Array1 = RxArray1, Array1_att = RxArray1_att, Array2 = TxArray1, Array2_att = TxArray1_att, Rx_Point = Rx.transform.position, Tx_Point = Tx.transform.position, Output = possiblePath1, OutputDelays = dtMPC1Array, OutputAmplitudes = PathGainMPC1, }; JobHandle jobHandleMPC1 = commonMPC1Parallel.Schedule(TxArray1.Length, 2); jobHandleMPC1.Complete(); // transition from NativeArrays to Lists List <Path1> first_order_paths_full_parallel = new List <Path1>(); if (MPC1_Tracer) { for (int i = 0; i < possiblePath1.Length; i++) { if (possiblePath1[i].Distance > 0) { first_order_paths_full_parallel.Add(possiblePath1[i]); Debug.DrawLine(possiblePath1[i].Rx_Point, possiblePath1[i].MPC1, Color.cyan); Debug.DrawLine(possiblePath1[i].Tx_Point, possiblePath1[i].MPC1, Color.cyan); } } } RxArray1.Dispose(); RxArray1_att.Dispose(); TxArray1.Dispose(); TxArray1_att.Dispose(); possiblePath1.Dispose(); dtMPC1Array.Dispose(); PathGainMPC1.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// MPC2 Parallel /////////////////////////////////////////////////////////////////////////////////// var level2MPC2 = new NativeArray <int>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var level2MPC2_att = new NativeArray <float>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var possiblePath2 = new NativeArray <Path2>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var dtArrayMPC2 = new NativeArray <float>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var PathGainMPC2 = new NativeArray <float>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); for (int l = 0; l < Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists; l++) { level2MPC2[l] = Rx_MPC2[Mathf.FloorToInt(l / MaxLengthOfSeenMPC2Lists)]; level2MPC2_att[l] = Rx_MPC2_att[Mathf.FloorToInt(l / MaxLengthOfSeenMPC2Lists)]; possiblePath2[l] = empty_path2; } var TxMPC2Array = new NativeArray <int>(Tx_MPC2.Count, Allocator.TempJob); var TxMPC2Array_att = new NativeArray <float>(Tx_MPC2.Count, Allocator.TempJob); for (int l = 0; l < Tx_MPC2.Count; l++) { TxMPC2Array[l] = Tx_MPC2[l]; TxMPC2Array_att[l] = Tx_MPC2_att[l]; } Path2ParallelSearch path2ParallelSearch = new Path2ParallelSearch { // common data SeenMPC2Table = SeenMPC2Table, LookUpTable2 = LookUpTable2, LookUpTable2ID = LookUpTable2ID, // must be disposed Rx_MPC2Array = level2MPC2, Rx_MPC2Array_att = level2MPC2_att, Tx_MPC2 = TxMPC2Array, Tx_MPC2_att = TxMPC2Array_att, // other data Rx_Position = Rx.transform.position, Tx_Position = Tx.transform.position, MaxListsLength = MaxLengthOfSeenMPC2Lists, Speed_of_Light = SpeedofLight, SecondOrderPaths = possiblePath2, OutputDelays = dtArrayMPC2, OutputAmplitudes = PathGainMPC2, }; // create a job handle list JobHandle jobHandleMPC2 = path2ParallelSearch.Schedule(level2MPC2.Length, MaxLengthOfSeenMPC2Lists, jobHandleMPC1); jobHandleMPC2.Complete(); /// MPC2 List <Path2> second_order_paths_full_parallel = new List <Path2>(); if (MPC2_Tracer) { for (int l = 0; l < possiblePath2.Length; l++) { if (possiblePath2[l].Distance > 0) { second_order_paths_full_parallel.Add(possiblePath2[l]); Debug.DrawLine(possiblePath2[l].Rx_Point, possiblePath2[l].MPC2_1, Color.white); Debug.DrawLine(possiblePath2[l].MPC2_1, possiblePath2[l].MPC2_2, Color.white); Debug.DrawLine(possiblePath2[l].MPC2_2, possiblePath2[l].Tx_Point, Color.white); } } } level2MPC2.Dispose(); level2MPC2_att.Dispose(); possiblePath2.Dispose(); TxMPC2Array.Dispose(); TxMPC2Array_att.Dispose(); dtArrayMPC2.Dispose(); PathGainMPC2.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// MPC3 /////////////////////////////////////////////////////////////////////////////////// if (If_we_need_MPC3 == true) { // define how many elements should be processed in a single core int innerloopBatchCount = MaxLengthOfSeenMPC3Lists; Vector3 Rx_Point = Rx.transform.position; Vector3 Tx_Point = Tx.transform.position; NativeArray <int> Rx_Seen_MPC3 = new NativeArray <int>(Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> Rx_Seen_MPC3_att = new NativeArray <float>(Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <Path3Half> RxReachableHalfPath3Array = new NativeArray <Path3Half>(Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); for (int l = 0; l < Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists; l++) { Rx_Seen_MPC3[l] = Rx_MPC3[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; Rx_Seen_MPC3_att[l] = Rx_MPC3_att[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; RxReachableHalfPath3Array[l] = empty_path3Half; } NativeArray <int> Tx_Seen_MPC3 = new NativeArray <int>(Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> Tx_Seen_MPC3_att = new NativeArray <float>(Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <Path3Half> TxReachableHalfPath3Array = new NativeArray <Path3Half>(Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); for (int l = 0; l < Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists; l++) { Tx_Seen_MPC3[l] = Tx_MPC3[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; Tx_Seen_MPC3_att[l] = Tx_MPC3_att[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; TxReachableHalfPath3Array[l] = empty_path3Half; } HalfPath3Set RxhalfPath3Set = new HalfPath3Set { // common data SeenMPC3Table = SeenMPC3Table, LookUpTable3 = LookUpTable3, LookUpTable3ID = LookUpTable3ID, MaxListsLength = MaxLengthOfSeenMPC3Lists, // Car specific data Point = Rx_Point, // must be disposed Seen_MPC3 = Rx_Seen_MPC3, Seen_MPC3_att = Rx_Seen_MPC3_att, ReachableHalfPath3 = RxReachableHalfPath3Array, }; // create a job handle list NativeList <JobHandle> jobHandleList = new NativeList <JobHandle>(Allocator.Temp); JobHandle RxjobHandleMPC3 = RxhalfPath3Set.Schedule(Rx_Seen_MPC3.Length, innerloopBatchCount, jobHandleMPC2); jobHandleList.Add(RxjobHandleMPC3); HalfPath3Set TxhalfPath3Set = new HalfPath3Set { // common data SeenMPC3Table = SeenMPC3Table, LookUpTable3 = LookUpTable3, LookUpTable3ID = LookUpTable3ID, MaxListsLength = MaxLengthOfSeenMPC3Lists, // Car specific data Point = Tx_Point, // must be disposed Seen_MPC3 = Tx_Seen_MPC3, Seen_MPC3_att = Tx_Seen_MPC3_att, ReachableHalfPath3 = TxReachableHalfPath3Array, }; JobHandle TxjobHandleMPC3 = TxhalfPath3Set.Schedule(Tx_Seen_MPC3.Length, innerloopBatchCount, jobHandleMPC2); jobHandleList.Add(TxjobHandleMPC3); JobHandle.CompleteAll(jobHandleList); // storing nonempty path3s List <Path3Half> TxHalfPath3 = new List <Path3Half>(); List <Path3Half> RxHalfPath3 = new List <Path3Half>(); // introducing a little bit of randomness to the third order of paths selection int MPC3PathStep = 3; // otherwise, the sets of possible third order of paths become too big for (int l = 0; l < TxReachableHalfPath3Array.Length; l += MPC3PathStep) { if (TxReachableHalfPath3Array[l].Distance > 0) { TxHalfPath3.Add(TxReachableHalfPath3Array[l]); } } for (int l = 0; l < RxReachableHalfPath3Array.Length; l += MPC3PathStep) { if (RxReachableHalfPath3Array[l].Distance > 0) { RxHalfPath3.Add(RxReachableHalfPath3Array[l]); } } //float startTime2 = Time.realtimeSinceStartup; NativeArray <Path3Half> RxNativeArray = new NativeArray <Path3Half>(RxHalfPath3.Count, Allocator.TempJob); for (int i = 0; i < RxNativeArray.Length; i++) { RxNativeArray[i] = RxHalfPath3[i]; } NativeArray <Path3Half> TxNativeArray = new NativeArray <Path3Half>(TxHalfPath3.Count, Allocator.TempJob); for (int i = 0; i < TxNativeArray.Length; i++) { TxNativeArray[i] = TxHalfPath3[i]; } NativeArray <Path3> activepath3 = new NativeArray <Path3>(RxHalfPath3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> dtArrayMPC3 = new NativeArray <float>(RxHalfPath3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> PathGainMPC3 = new NativeArray <float>(RxHalfPath3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); Path3ActiveSet Rx_path3ActiveSet = new Path3ActiveSet { SeenMPC3Table = SeenMPC3Table, InputArray = RxNativeArray, CompareArray = TxNativeArray, MaxListsLength = MaxLengthOfSeenMPC3Lists, EmptyElement = empty_path3, Speed_of_Light = SpeedofLight, Output = activepath3, OutputDelays = dtArrayMPC3, OutputAmplitudes = PathGainMPC3 }; JobHandle Jobforpath3ActiveSet = Rx_path3ActiveSet.Schedule(activepath3.Length, MaxLengthOfSeenMPC3Lists, TxjobHandleMPC3); Jobforpath3ActiveSet.Complete(); List <Path3> third_order_paths_full_parallel = new List <Path3>(); if (MPC3_Tracer) { int trace_count = 0; for (int l = 0; l < activepath3.Length; l++) //for (int l = 0; l < 10; l++) { if (activepath3[l].Distance > 0) { trace_count += 1; third_order_paths_full_parallel.Add(activepath3[l]); Debug.DrawLine(activepath3[l].Rx_Point, activepath3[l].MPC3_1, Color.green); Debug.DrawLine(activepath3[l].MPC3_1, activepath3[l].MPC3_2, Color.blue); Debug.DrawLine(activepath3[l].MPC3_2, activepath3[l].MPC3_3, Color.yellow); Debug.DrawLine(activepath3[l].MPC3_3, activepath3[l].Tx_Point, Color.red); //if (trace_count == 10) //{ break; } } } } //Debug.Log("Number of 3rd order paths = " + third_order_paths_full_parallel.Count); TxNativeArray.Dispose(); RxNativeArray.Dispose(); activepath3.Dispose(); dtArrayMPC3.Dispose(); PathGainMPC3.Dispose(); //Debug.Log("Check 2: " + ((Time.realtimeSinceStartup - startTime2) * 1000000f) + " microsec"); Rx_Seen_MPC3.Dispose(); Rx_Seen_MPC3_att.Dispose(); RxReachableHalfPath3Array.Dispose(); Tx_Seen_MPC3.Dispose(); Tx_Seen_MPC3_att.Dispose(); TxReachableHalfPath3Array.Dispose(); } /////////////////////////////////////////////////////////////////////////////////// /// complete the works /////////////////////////////////////////////////////////////////////////////////// Y_output = new double[Nfft]; H_output = new double[Nfft]; Y_noise_output = new double[Nfft]; H_noise_output = new double[Nfft]; Drawing.drawChart(tfTime, X_inputValues, Y_output, "time"); Drawing.drawChart(tfFreq, X_inputValues, H_output, "frequency"); //Debug.Log("RSS = " + 10* Math.Log10( RSS ) ); }
private void FixedUpdate() { FixUpdateCount += 1; Rx_MPC1 = Rx_Seen_MPC_Script.seen_MPC1; Rx_MPC1_att = Rx_Seen_MPC_Script.seen_MPC1_att; Rx_MPC2 = Rx_Seen_MPC_Script.seen_MPC2; Rx_MPC2_att = Rx_Seen_MPC_Script.seen_MPC2_att; Rx_MPC3 = Rx_Seen_MPC_Script.seen_MPC3; Rx_MPC3_att = Rx_Seen_MPC_Script.seen_MPC3_att; Tx_MPC1 = Tx_Seen_MPC_Script.seen_MPC1; Tx_MPC1_att = Tx_Seen_MPC_Script.seen_MPC1_att; Tx_MPC2 = Tx_Seen_MPC_Script.seen_MPC2; Tx_MPC2_att = Tx_Seen_MPC_Script.seen_MPC2_att; Tx_MPC3 = Tx_Seen_MPC_Script.seen_MPC3; Tx_MPC3_att = Tx_Seen_MPC_Script.seen_MPC3_att; //NativeList<JobHandle> jobHandleList_Channel = new NativeList<JobHandle>(Allocator.Temp); /* * for (int i = 0; i < H.Length; i++) * { * H_LoS[i] = new System.Numerics.Complex(0, 0); * H_MPC1[i] = new System.Numerics.Complex(0, 0); * H_MPC2[i] = new System.Numerics.Complex(0, 0); * H_MPC3[i] = new System.Numerics.Complex(0, 0); * } */ /////////////////////////////////////////////////////////////////////////////////// /// LOS /////////////////////////////////////////////////////////////////////////////////// float dtLoS = 0; float PathGainLoS = 0; float LOS_distance = 0; if (!Physics.Linecast(Tx.transform.position, Rx.transform.position)) { Vector3 LoS_dir = (Tx.transform.position - Rx.transform.position).normalized; Vector3 Tx_fwd = Tx.transform.forward; Vector3 Rx_fwd = Tx.transform.forward; float cos_Tx = -1; float cos_Rx = -1; float K_antanne_pattern; if (Tx_Antenna_pattern) { cos_Tx = Vector3.Dot(-LoS_dir, Tx_fwd); } if (Rx_Antenna_pattern) { cos_Rx = Vector3.Dot(LoS_dir, Rx_fwd); } K_antanne_pattern = 0.25f * (1 - cos_Rx - cos_Tx + cos_Rx * cos_Tx); flag_LoS = 1; if (LoS_Start == 0) { LoS_Start = FixUpdateCount; Debug.Log("LoS Start " + LoS_Start); } // finding the start time of LoS if (LOS_Tracer) { Debug.DrawLine(Tx.transform.position, Rx.transform.position, Color.magenta); } LOS_distance = (Tx.transform.position - Rx.transform.position).magnitude; //LOS_distance = 200; dtLoS = LOS_distance / SpeedofLight;// + 1000/SpeedofLight; PathGainLoS = (float)Math.Pow(1 / LOS_distance, 2) * K_antanne_pattern; float hbyd = 3.4f / LOS_distance; // 2h/d; h = 1.7meters float Rparallel = (RelativePermitivity * hbyd - Z) / (RelativePermitivity * hbyd + Z); float Rperpendicular = (hbyd - Z) / (hbyd + Z); float Rcoef = (float)Math.Sqrt(0.5f * (Rparallel * Rparallel + Rperpendicular * Rperpendicular)); //PathGainLoS -= PathGainLoS * Rcoef * Rcoef / 2; //float h2byd = 5.78f / LOS_distance; // 2 h^2/2 EdgeEffect(FixUpdateCount - LoS_Start, out EdgeEffect_LoS); // the follwing can be done due to manual calculation of the LoS End if (FixUpdateCount > 100 && FixUpdateCount < 126) { EdgeEffect(124 - FixUpdateCount, out EdgeEffect_LoS); } } /*else * { * if (flag_LoS == 1) * { * flag_LoS = 2; * LoS_End = FixUpdateCount; * Debug.Log("LoS End " + LoS_End); * // remember the last LoS channel * for (int i = 0; i < H_LoS.Length; i++) * { * H_old[i] = H_LoS[i]; * } * } // finding the end time of LoS * }*/ //Debug.Log("Edge effect coefficient = " + EdgeEffect_LoS); var dtLoSParallel = new NativeArray <float>(1, Allocator.TempJob); var distanceLoSParallel = new NativeArray <float>(1, Allocator.TempJob); var PathGainLoSParallel = new NativeArray <float>(1, Allocator.TempJob); for (int i = 0; i < dtLoSParallel.Length; i++) { dtLoSParallel[i] = dtLoS; distanceLoSParallel[i] = LOS_distance; PathGainLoSParallel[i] = PathGainLoS; } ChannelParallel channelParallel = new ChannelParallel { //TimeDelayArray = dtLoSParallel, //FrequencyArray = Subcarriers, PathsGainArray = PathGainLoSParallel, TimeDelayArray = distanceLoSParallel, FrequencyArray = InverseWavelength, HH = H_LoS, }; JobHandle jobHandleLoSChannel = channelParallel.Schedule(Subcarriers.Length, 8); // we add the job to the list of jobs related to channel calculation in order to complete them all at once later //jobHandleList_Channel.Add(jobHandleLoSChannel); //JobHandle.CompleteAll(jobHandleList_Channel); jobHandleLoSChannel.Complete(); dtLoSParallel.Dispose(); distanceLoSParallel.Dispose(); PathGainLoSParallel.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// MPC1 /////////////////////////////////////////////////////////////////////////////////// var RxArray1 = new NativeArray <int>(Rx_MPC1.Count, Allocator.TempJob); var RxArray1_att = new NativeArray <float>(Rx_MPC1.Count, Allocator.TempJob); var TxArray1 = new NativeArray <int>(Tx_MPC1.Count, Allocator.TempJob); var TxArray1_att = new NativeArray <float>(Tx_MPC1.Count, Allocator.TempJob); var possiblePath1 = new NativeArray <Path1>(Tx_MPC1.Count, Allocator.TempJob); var dtMPC1Array = new NativeArray <float>(Tx_MPC1.Count, Allocator.TempJob); var PathGainMPC1 = new NativeArray <float>(Tx_MPC1.Count, Allocator.TempJob); for (int i = 0; i < Rx_MPC1.Count; i++) { RxArray1[i] = Rx_MPC1[i]; RxArray1_att[i] = Rx_MPC1_att[i]; } for (int i = 0; i < Tx_MPC1.Count; i++) { TxArray1[i] = Tx_MPC1[i]; TxArray1_att[i] = Tx_MPC1_att[i]; possiblePath1[i] = empty_path; } CommonMPC1Parallel commonMPC1Parallel = new CommonMPC1Parallel { Speed_of_Light = SpeedofLight, MPC1 = SeenMPC1Table, Array1 = RxArray1, Array1_att = RxArray1_att, Array2 = TxArray1, Array2_att = TxArray1_att, Rx_Point = Rx.transform.position, Tx_Point = Tx.transform.position, Output = possiblePath1, OutputDelays = dtMPC1Array, OutputAmplitudes = PathGainMPC1, }; JobHandle jobHandleMPC1 = commonMPC1Parallel.Schedule(TxArray1.Length, 2); jobHandleMPC1.Complete(); // transition from NativeArrays to Lists List <Path1> first_order_paths_full_parallel = new List <Path1>(); if (MPC1_Tracer) { for (int i = 0; i < possiblePath1.Length; i++) { if (possiblePath1[i].Distance > 0) { first_order_paths_full_parallel.Add(possiblePath1[i]); Debug.DrawLine(possiblePath1[i].Rx_Point, possiblePath1[i].MPC1, Color.cyan); Debug.DrawLine(possiblePath1[i].Tx_Point, possiblePath1[i].MPC1, Color.cyan); } } } // channel calculation ChannelParallel channelParallelMPC1 = new ChannelParallel { //TimeDelayArray = dtMPC1Array, //FrequencyArray = Subcarriers, PathsGainArray = PathGainMPC1, TimeDelayArray = dtMPC1Array, // changed to distances FrequencyArray = InverseWavelength, HH = H_MPC1, }; JobHandle jobHandleChannelMPC1 = channelParallelMPC1.Schedule(Subcarriers.Length, 8, jobHandleMPC1); // we add the job to the list of jobs related to channel calculation in order to complete them all at once later //jobHandleList_Channel.Add(jobHandleChannelMPC1); jobHandleChannelMPC1.Complete(); RxArray1.Dispose(); RxArray1_att.Dispose(); TxArray1.Dispose(); TxArray1_att.Dispose(); possiblePath1.Dispose(); dtMPC1Array.Dispose(); PathGainMPC1.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// MPC2 Parallel /////////////////////////////////////////////////////////////////////////////////// var level2MPC2 = new NativeArray <int>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var level2MPC2_att = new NativeArray <float>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var possiblePath2 = new NativeArray <Path2>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var dtArrayMPC2 = new NativeArray <float>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); var PathGainMPC2 = new NativeArray <float>(Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists, Allocator.TempJob); for (int l = 0; l < Rx_MPC2.Count * MaxLengthOfSeenMPC2Lists; l++) { level2MPC2[l] = Rx_MPC2[Mathf.FloorToInt(l / MaxLengthOfSeenMPC2Lists)]; level2MPC2_att[l] = Rx_MPC2_att[Mathf.FloorToInt(l / MaxLengthOfSeenMPC2Lists)]; possiblePath2[l] = empty_path2; } var TxMPC2Array = new NativeArray <int>(Tx_MPC2.Count, Allocator.TempJob); var TxMPC2Array_att = new NativeArray <float>(Tx_MPC2.Count, Allocator.TempJob); for (int l = 0; l < Tx_MPC2.Count; l++) { TxMPC2Array[l] = Tx_MPC2[l]; TxMPC2Array_att[l] = Tx_MPC2_att[l]; } Path2ParallelSearch path2ParallelSearch = new Path2ParallelSearch { // common data SeenMPC2Table = SeenMPC2Table, LookUpTable2 = LookUpTable2, LookUpTable2ID = LookUpTable2ID, // must be disposed Rx_MPC2Array = level2MPC2, Rx_MPC2Array_att = level2MPC2_att, Tx_MPC2 = TxMPC2Array, Tx_MPC2_att = TxMPC2Array_att, // other data Rx_Position = Rx.transform.position, Tx_Position = Tx.transform.position, MaxListsLength = MaxLengthOfSeenMPC2Lists, Speed_of_Light = SpeedofLight, SecondOrderPaths = possiblePath2, OutputDelays = dtArrayMPC2, OutputAmplitudes = PathGainMPC2, }; // create a job handle list JobHandle jobHandleMPC2 = path2ParallelSearch.Schedule(level2MPC2.Length, MaxLengthOfSeenMPC2Lists, jobHandleMPC1); jobHandleMPC2.Complete(); /// MPC2 List <Path2> second_order_paths_full_parallel = new List <Path2>(); if (MPC2_Tracer) { for (int l = 0; l < possiblePath2.Length; l++) { if (possiblePath2[l].Distance > 0) { second_order_paths_full_parallel.Add(possiblePath2[l]); Debug.DrawLine(possiblePath2[l].Rx_Point, possiblePath2[l].MPC2_1, Color.white); Debug.DrawLine(possiblePath2[l].MPC2_1, possiblePath2[l].MPC2_2, Color.white); Debug.DrawLine(possiblePath2[l].MPC2_2, possiblePath2[l].Tx_Point, Color.white); } } } // channel calculation ChannelParallel channelParallelMPC2 = new ChannelParallel { //TimeDelayArray = dtArrayMPC2, //FrequencyArray = Subcarriers, PathsGainArray = PathGainMPC2, TimeDelayArray = dtArrayMPC2, // changed to distances FrequencyArray = InverseWavelength, HH = H_MPC2, }; JobHandle jobHandleChannelMPC2 = channelParallelMPC2.Schedule(Subcarriers.Length, 8, jobHandleMPC2); // we add the job to the list of jobs related to channel calculation in order to complete them all at once later //jobHandleList_Channel.Add(jobHandleChannelMPC1); jobHandleChannelMPC2.Complete(); level2MPC2.Dispose(); level2MPC2_att.Dispose(); possiblePath2.Dispose(); TxMPC2Array.Dispose(); TxMPC2Array_att.Dispose(); dtArrayMPC2.Dispose(); PathGainMPC2.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// MPC3 /////////////////////////////////////////////////////////////////////////////////// // define how many elements should be processed in a single core int innerloopBatchCount = MaxLengthOfSeenMPC3Lists; Vector3 Rx_Point = Rx.transform.position; Vector3 Tx_Point = Tx.transform.position; NativeArray <int> Rx_Seen_MPC3 = new NativeArray <int>(Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> Rx_Seen_MPC3_att = new NativeArray <float>(Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <Path3Half> RxReachableHalfPath3Array = new NativeArray <Path3Half>(Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); for (int l = 0; l < Rx_MPC3.Count * MaxLengthOfSeenMPC3Lists; l++) { Rx_Seen_MPC3[l] = Rx_MPC3[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; Rx_Seen_MPC3_att[l] = Rx_MPC3_att[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; RxReachableHalfPath3Array[l] = empty_path3Half; } NativeArray <int> Tx_Seen_MPC3 = new NativeArray <int>(Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> Tx_Seen_MPC3_att = new NativeArray <float>(Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <Path3Half> TxReachableHalfPath3Array = new NativeArray <Path3Half>(Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); for (int l = 0; l < Tx_MPC3.Count * MaxLengthOfSeenMPC3Lists; l++) { Tx_Seen_MPC3[l] = Tx_MPC3[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; Tx_Seen_MPC3_att[l] = Tx_MPC3_att[Mathf.FloorToInt(l / MaxLengthOfSeenMPC3Lists)]; TxReachableHalfPath3Array[l] = empty_path3Half; } HalfPath3Set RxhalfPath3Set = new HalfPath3Set { // common data SeenMPC3Table = SeenMPC3Table, LookUpTable3 = LookUpTable3, LookUpTable3ID = LookUpTable3ID, MaxListsLength = MaxLengthOfSeenMPC3Lists, // Car specific data Point = Rx_Point, // must be disposed Seen_MPC3 = Rx_Seen_MPC3, Seen_MPC3_att = Rx_Seen_MPC3_att, ReachableHalfPath3 = RxReachableHalfPath3Array, }; // create a job handle list NativeList <JobHandle> jobHandleList = new NativeList <JobHandle>(Allocator.Temp); JobHandle RxjobHandleMPC3 = RxhalfPath3Set.Schedule(Rx_Seen_MPC3.Length, innerloopBatchCount, jobHandleMPC2); jobHandleList.Add(RxjobHandleMPC3); HalfPath3Set TxhalfPath3Set = new HalfPath3Set { // common data SeenMPC3Table = SeenMPC3Table, LookUpTable3 = LookUpTable3, LookUpTable3ID = LookUpTable3ID, MaxListsLength = MaxLengthOfSeenMPC3Lists, // Car specific data Point = Tx_Point, // must be disposed Seen_MPC3 = Tx_Seen_MPC3, Seen_MPC3_att = Tx_Seen_MPC3_att, ReachableHalfPath3 = TxReachableHalfPath3Array, }; JobHandle TxjobHandleMPC3 = TxhalfPath3Set.Schedule(Tx_Seen_MPC3.Length, innerloopBatchCount, jobHandleMPC2); jobHandleList.Add(TxjobHandleMPC3); JobHandle.CompleteAll(jobHandleList); // storing nonempty path3s List <Path3Half> TxHalfPath3 = new List <Path3Half>(); List <Path3Half> RxHalfPath3 = new List <Path3Half>(); // introducing a little bit of randomness to the third order of paths selection int MPC3PathStep = 3; // otherwise, the sets of possible third order of paths become too big for (int l = 0; l < TxReachableHalfPath3Array.Length; l += MPC3PathStep) { if (TxReachableHalfPath3Array[l].Distance > 0) { TxHalfPath3.Add(TxReachableHalfPath3Array[l]); } } for (int l = 0; l < RxReachableHalfPath3Array.Length; l += MPC3PathStep) { if (RxReachableHalfPath3Array[l].Distance > 0) { RxHalfPath3.Add(RxReachableHalfPath3Array[l]); } } //float startTime2 = Time.realtimeSinceStartup; NativeArray <Path3Half> RxNativeArray = new NativeArray <Path3Half>(RxHalfPath3.Count, Allocator.TempJob); for (int i = 0; i < RxNativeArray.Length; i++) { RxNativeArray[i] = RxHalfPath3[i]; } NativeArray <Path3Half> TxNativeArray = new NativeArray <Path3Half>(TxHalfPath3.Count, Allocator.TempJob); for (int i = 0; i < TxNativeArray.Length; i++) { TxNativeArray[i] = TxHalfPath3[i]; } NativeArray <Path3> activepath3 = new NativeArray <Path3>(RxHalfPath3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> dtArrayMPC3 = new NativeArray <float>(RxHalfPath3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); NativeArray <float> PathGainMPC3 = new NativeArray <float>(RxHalfPath3.Count * MaxLengthOfSeenMPC3Lists, Allocator.TempJob); Path3ActiveSet Rx_path3ActiveSet = new Path3ActiveSet { SeenMPC3Table = SeenMPC3Table, InputArray = RxNativeArray, CompareArray = TxNativeArray, MaxListsLength = MaxLengthOfSeenMPC3Lists, EmptyElement = empty_path3, Speed_of_Light = SpeedofLight, Output = activepath3, OutputDelays = dtArrayMPC3, OutputAmplitudes = PathGainMPC3 }; JobHandle Jobforpath3ActiveSet = Rx_path3ActiveSet.Schedule(activepath3.Length, MaxLengthOfSeenMPC3Lists, TxjobHandleMPC3); Jobforpath3ActiveSet.Complete(); // channel calculation ChannelParallel channelParallelMPC3 = new ChannelParallel { //TimeDelayArray = dtArrayMPC3, //FrequencyArray = Subcarriers, PathsGainArray = PathGainMPC3, TimeDelayArray = dtArrayMPC3, // changed to distances FrequencyArray = InverseWavelength, HH = H_MPC3, }; JobHandle jobHandleChannelMPC3 = channelParallelMPC3.Schedule(Subcarriers.Length, 8, Jobforpath3ActiveSet); // we add the job to the list of jobs related to channel calculation in order to complete them all at once later //jobHandleList_Channel.Add(jobHandleChannelMPC1); jobHandleChannelMPC3.Complete(); List <Path3> third_order_paths_full_parallel = new List <Path3>(); if (MPC3_Tracer) { int trace_count = 0; for (int l = 0; l < activepath3.Length; l++) //for (int l = 0; l < 10; l++) { if (activepath3[l].Distance > 0) { trace_count += 1; third_order_paths_full_parallel.Add(activepath3[l]); Debug.DrawLine(activepath3[l].Rx_Point, activepath3[l].MPC3_1, Color.green); Debug.DrawLine(activepath3[l].MPC3_1, activepath3[l].MPC3_2, Color.blue); Debug.DrawLine(activepath3[l].MPC3_2, activepath3[l].MPC3_3, Color.yellow); Debug.DrawLine(activepath3[l].MPC3_3, activepath3[l].Tx_Point, Color.red); //if (trace_count == 10) //{ break; } } } } //Debug.Log("Number of 3rd order paths = " + third_order_paths_full_parallel.Count); TxNativeArray.Dispose(); RxNativeArray.Dispose(); activepath3.Dispose(); dtArrayMPC3.Dispose(); PathGainMPC3.Dispose(); //Debug.Log("Check 2: " + ((Time.realtimeSinceStartup - startTime2) * 1000000f) + " microsec"); Rx_Seen_MPC3.Dispose(); Rx_Seen_MPC3_att.Dispose(); RxReachableHalfPath3Array.Dispose(); Tx_Seen_MPC3.Dispose(); Tx_Seen_MPC3_att.Dispose(); TxReachableHalfPath3Array.Dispose(); /////////////////////////////////////////////////////////////////////////////////// /// complete the works /////////////////////////////////////////////////////////////////////////////////// /// LoS // this part should be moved to the end at least after the completion of the list of the works //jobHandleList_Channel.Complete(); //double asd = System.Numerics.Complex.Abs( H_MPC2[0]); double factor = 10000000 * 32; // this corresponds to a -110 dBm noise floor; 32 comes from the sqrt of 1024 for (int i = 0; i < H.Length; i++) { double u1 = 1.0 - rand.NextDouble(); //uniform(0,1] random doubles double u2 = 1.0 - rand.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2) / factor; //H[i] = H_LoS[i]; //H[i] = H_MPC1[i]; //H[i] = H_MPC2[i]; //H[i] = H_LoS[i] + H_MPC1[i]; H[i] = H_LoS[i] * EdgeEffect_LoS + H_MPC1[i] + H_MPC2[i] + H_MPC3[i] + randStdNormal; H_pure[i] = H_LoS[i] * EdgeEffect_LoS + H_MPC1[i] + H_MPC2[i] + H_MPC3[i]; //H_noise[i] = randStdNormal; //H[i] = H_MPC3[i]; // zeroing all the inputs // H_LoS[i] = new System.Numerics.Complex(0,0); H_MPC1[i] = new System.Numerics.Complex(0, 0); H_MPC2[i] = new System.Numerics.Complex(0, 0); H_MPC3[i] = new System.Numerics.Complex(0, 0); } System.Numerics.Complex[] outputSignal_Freq = FastFourierTransform.FFT(H, false); System.Numerics.Complex[] outputNoise_Freq = FastFourierTransform.FFT(H_noise, false); Y_output = new double[H.Length]; H_output = new double[H.Length]; Y_noise_output = new double[H.Length]; H_noise_output = new double[H.Length]; //get module of complex number double RSS = 0; for (int ii = 0; ii < H.Length; ii++) { Y_output[ii] = 10 * Math.Log10(System.Numerics.Complex.Abs(outputSignal_Freq[ii])); // + 0.0000000000001); H_output[ii] = 10 * Math.Log10(System.Numerics.Complex.Abs(H[ii])); // + 0.0000000000001); //Y_noise_output[ii] = 10 * Math.Log10(System.Numerics.Complex.Abs(outputNoise_Freq[ii]));// + 0.0000000000001); //H_noise_output[ii] = 10 * Math.Log10(System.Numerics.Complex.Abs(H_noise[ii]));// + 0.0000000000001); // calculatig pure signal's RSSI, should be clarified //RSSI += System.Numerics.Complex.Abs(H_pure[ii]); RSS += 1000 * Math.Pow(System.Numerics.Complex.Abs(H_pure[ii]), 2); } //Drawing.drawChart(tfTime, X_inputValues, Y_noise_output, "time"); //Drawing.drawChart(tfFreq, X_inputValues, H_noise_output, "frequency"); Drawing.drawChart(tfTime, X_inputValues, Y_output, "time"); Drawing.drawChart(tfFreq, X_inputValues, H_output, "frequency"); //Debug.Log("RSS = " + 10* Math.Log10( RSS ) ); }