public static void SetupHotsunforRotateMDS() { PointVectorDimension = ManxcatCentral.Configuration.LocalVectorDimension; if (PointVectorDimension == 3) { Hotsun.npar = 7; } else if (PointVectorDimension == 2) { Hotsun.npar = 4; } else { Exception e = SALSAUtility.SALSAError("Unsupported Dimension " + PointVectorDimension.ToString()); } Hotsun.ndata = SALSAUtility.PointCount_Global * PointVectorDimension; Hotsun.ParameterVectorDimension = 1; GenericManxcat.SetupGenericManxcat(); return; }
// End SetupRotateMDS() public static bool Calcfg(Desertwind Solution) { // call Accum with value and derivative for each point bool violat = false; double Scale = 1.0; double DerivScale = 1.0; if (ScaleOption == 0) { if ((Solution.param[ScalePosition][0] < 0.0) && (RotationOption_invert == 0)) { violat = true; Solution.param[ScalePosition][0] = -Solution.param[ScalePosition][0]; } Solution.param[ScalePosition][0] = Math.Max(ScaleAlpha * FirstScale / SecondScale, Solution.param[ScalePosition][0]); Scale = Solution.param[ScalePosition][0]; } else { Solution.param[ScalePosition][0] = ProperAngle(Solution.param[ScalePosition][0]); Scale = CalculateScale(Solution.param[ScalePosition][0]); DerivScale = DifferentiateScale(Solution.param[ScalePosition][0]); // SALSAUtility.SALSAPrint(0, "Scale DerivScale " + Scale.ToString("E4") + " " + DerivScale.ToString("E4")); } // Force Angles between -PI and PI if (PointVectorDimension == 3) { for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { Solution.param[LocalVectorIndex + PointVectorDimension][0] = ProperAngle(Solution.param[LocalVectorIndex + PointVectorDimension][0]); } } if (PointVectorDimension == 2) { Solution.param[2][0] = ProperAngle(Solution.param[2][0]); } // End Force Angles between -PI and PI // Each Value is weight * (Scaling * Cosmic * Rotation * Second Vector + Translation - First Vector) // Each Derivative is weight * ( Scaling * Cosmic * Rotation Term * Second Vectot + Treanslation Term ) // Rotation, Rotation Term, Translation, Translation Term are independent of Point // weight depends on Option Used var Translation = new double[PointVectorDimension]; var Rotation = new double[PointVectorDimension, PointVectorDimension]; var DerivTranslation = new double[Hotsun.npar][]; var DerivRotationScale = new double[Hotsun.npar][, ]; var SubRotation = new double[NumberSubRotations][, ]; var SubDeriveRotation = new double[NumberSubRotations][, ]; for (int ipar = 0; ipar < Hotsun.npar; ipar++) { DerivTranslation[ipar] = new double[PointVectorDimension]; DerivRotationScale[ipar] = new double[PointVectorDimension, PointVectorDimension]; for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++) { DerivTranslation[ipar][LocalVectorIndex1] = 0.0; for (int LocalVectorIndex2 = 0; LocalVectorIndex2 < PointVectorDimension; LocalVectorIndex2++) { if (ipar < PointVectorDimension) { DerivRotationScale[ipar][LocalVectorIndex1, LocalVectorIndex2] = 0.0; } // Rotation Matrix Zero for Translations } } } for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { Translation[LocalVectorIndex] = Solution.param[LocalVectorIndex][0]; // Translations DerivTranslation[LocalVectorIndex][LocalVectorIndex] = 1.0; // Deriv of Translation } for (int SubRotationIndex = 0; SubRotationIndex < NumberSubRotations; SubRotationIndex++) { SubRotation[SubRotationIndex] = new double[PointVectorDimension, PointVectorDimension]; SubDeriveRotation[SubRotationIndex] = new double[PointVectorDimension, PointVectorDimension]; for (int LocalVectorIndex1 = 0; LocalVectorIndex1 < PointVectorDimension; LocalVectorIndex1++) { for (int LocalVectorIndex2 = 0; LocalVectorIndex2 < PointVectorDimension; LocalVectorIndex2++) { SubDeriveRotation[SubRotationIndex][LocalVectorIndex1, LocalVectorIndex2] = 0.0; SubRotation[SubRotationIndex][LocalVectorIndex1, LocalVectorIndex2] = 0.0; } } SetRotationMatrix(SubRotation[SubRotationIndex], SubRotationIndex, Solution.param[PointVectorDimension + SubRotationIndex][0], false); SetRotationMatrix(SubDeriveRotation[SubRotationIndex], SubRotationIndex, Solution.param[PointVectorDimension + SubRotationIndex][0], true); } if (PointVectorDimension == 3) { SetTotalRotation(Rotation, Scale, CurrentCosmicScaling, SubRotation[2], SubRotation[1], SubRotation[0]); SetTotalRotation(DerivRotationScale[PointVectorDimension], Scale, CurrentCosmicScaling, SubRotation[2], SubRotation[1], SubDeriveRotation[0]); // Rotation for First Angle SetTotalRotation(DerivRotationScale[PointVectorDimension + 1], Scale, CurrentCosmicScaling, SubRotation[2], SubDeriveRotation[1], SubRotation[0]); // Rotation for Second Angle SetTotalRotation(DerivRotationScale[PointVectorDimension + 2], Scale, CurrentCosmicScaling, SubDeriveRotation[2], SubRotation[1], SubRotation[0]); // Rotation for Third Angle SetTotalRotation(DerivRotationScale[ScalePosition], DerivScale, CurrentCosmicScaling, SubRotation[2], SubRotation[1], SubRotation[0]); // Rotation for Scale } if (PointVectorDimension == 2) { SetTotalRotation(Rotation, Scale, CurrentCosmicScaling, SubRotation[0]); SetTotalRotation(DerivRotationScale[PointVectorDimension], Scale, CurrentCosmicScaling, SubDeriveRotation[0]); // Rotation for First Angle SetTotalRotation(DerivRotationScale[ScalePosition], DerivScale, CurrentCosmicScaling, SubRotation[0]); // Rotation for Scale } // Set up Accum GenericManxcat.ReInitializeAccum(); // Finally Loop over entries in Chisq Parallel.For(0, SALSAUtility.ParallelOptions.MaxDegreeOfParallelism, SALSAUtility.ParallelOptions, (ThreadNo) => { var DerivativeFl = new double[PointVectorDimension][]; for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { DerivativeFl[LocalVectorIndex] = new double[Hotsun.npar]; } int indexlen = SALSAUtility.PointsperThread[ThreadNo]; int beginpoint = SALSAUtility.StartPointperThread[ThreadNo] - SALSAUtility.PointStart_Process; for (int DistributedPointIndex = beginpoint; DistributedPointIndex < indexlen + beginpoint; DistributedPointIndex++) { int GlobalIndex = SALSAUtility.PointStart_Process + DistributedPointIndex; // Setting weight to Math.Sqrt(1.0/SALSAUtility.PointCount_Global)* Fudge Factor/FirstScale double weight = Math.Sqrt(1.0 / SALSAUtility.PointCount_Global) * ManxcatCentral.ChisqFunctionCalcMultiplier / FirstScale; // RotationOption =0 is simple least squares sum; RotationOption = 1 implies use fractional errors if (RotationOption == 1) { double size = 0.0; for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { size += FirstData[GlobalIndex][LocalVectorIndex] * FirstData[GlobalIndex][LocalVectorIndex]; } size = Math.Sqrt(size); size = Math.Max(MinimumDistance, size); weight *= FirstScale / size; } var ValueFl = new double[PointVectorDimension]; MatrixVectorProduct(ValueFl, Rotation, SecondData[GlobalIndex]); VectorSum(ValueFl, Translation, +1.0, ValueFl); VectorSum(ValueFl, ValueFl, -1.0, FirstData[GlobalIndex]); for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { ValueFl[LocalVectorIndex] *= weight; } for (int ipar = 0; ipar < Hotsun.npar; ipar++) { if (ipar < PointVectorDimension) { // Translation Derivatives for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { DerivativeFl[LocalVectorIndex][ipar] = weight * DerivTranslation[ipar][ LocalVectorIndex]; } } else { var tempvector = new double[PointVectorDimension]; MatrixVectorProduct(tempvector, DerivRotationScale[ipar], SecondData[GlobalIndex]); for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { DerivativeFl[LocalVectorIndex][ipar] = weight * tempvector[LocalVectorIndex]; } } } for (int LocalVectorIndex = 0; LocalVectorIndex < PointVectorDimension; LocalVectorIndex++) { GenericManxcat.Accum(ThreadNo, ValueFl[LocalVectorIndex], DerivativeFl[LocalVectorIndex]); if (GlobalIndex <= 0) { string deriv = ""; for (int ipar = 0; ipar < Hotsun.npar; ipar++) { deriv += DerivativeFl[LocalVectorIndex][ipar].ToString("E4") + " "; } // SALSAUtility.SALSAPrint(0, "Val " + ValueFl[LocalVectorIndex].ToString("f4") + " Drv " + deriv); GenericManxcat.AccumDebug(GlobalIndex); } if (GlobalIndex > (SALSAUtility.PointCount_Global - 2)) { GenericManxcat.AccumDebug(GlobalIndex); } } } // End loop over points in this thread }); // End loop initialing Point dependent quantities // Add up MPI and Thread Contributions GenericManxcat.AddupChisqContributions(Solution); return(violat); }