protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix) { var watch = new Stopwatch(); if (mustInvert) { watch.Start(); if (isMatrixPositiveDefinite) { inverse = linearSystem.Matrix.FactorCholesky(factorizeInPlace).Invert(true); } else { inverse = linearSystem.Matrix.FactorLU(factorizeInPlace).Invert(true); } watch.Stop(); Logger.LogTaskDuration("Matrix factorization", watch.ElapsedMilliseconds); watch.Reset(); mustInvert = false; } watch.Start(); Matrix result = inverse.MultiplyRight(otherMatrix); watch.Stop(); Logger.LogTaskDuration("Back/forward substitutions", watch.ElapsedMilliseconds); Logger.IncrementAnalysisStep(); return(result); }
public void GenerateMatrices(IMatrixView matrix, IModelOverlappingDecomposition modelOverlappingDecomposition) { _modelOverlappingDecomposition = modelOverlappingDecomposition; var interpolationMatrix = modelOverlappingDecomposition.CoarseSpaceInterpolation.Transpose(); var coarseSpaceMatrix = interpolationMatrix.ThisTimesOtherTimesThisTranspose(matrix); inverseCoarseMatrix = coarseSpaceMatrix.Invert(); }
public void GmresTest() { IMatrixView matrix = Matrix.CreateFromArray(new double[9, 9] { { 2, 0, 0, -1, 0, 0, 0, 0, 0 }, { 0, 2, -1, 0, 0, 0, 0, 0, 0 }, { 0, -1, 2, 0, 0, 0, 0, 0, 0 }, { -1, 0, 0, 2, -1, 0, 0, 0, 0 }, { 0, 0, 0, -1, 2, -1, 0, 0, 0 }, { 0, 0, 0, 0, -1, 2, -1, 0, 0 }, { 0, 0, 0, 0, 0, -1, 2, -1, 0 }, { 0, 0, 0, 0, 0, 0, -1, 2, -1 }, { 0, 0, 0, 0, 0, 0, 0, -1, 2 } }); IVectorView rhs = Vector.CreateWithValue(9, 1.0); var solution = Vector.CreateZero(9); var gmresAlgorithmBuilder = new GmresAlgorithm.Builder() { MaximumIterations = 20, InnerIterationsProvider = new FixedMaxIterationsProvider(8), AbsoluteTolerance = 1e-8, RelativeTolerance = 1e-8 }; var gmres = gmresAlgorithmBuilder.Build(); gmres.Solve(matrix, rhs, solution, true, () => Vector.CreateZero(9)); var expectedSolution = Vector.CreateFromArray(new double[] { 3.5, 1.0, 1.0, 6.0, 7.5, 8.0, 7.5, 6.0, 3.5 }); for (int i = 0; i < expectedSolution.Length; i++) { Utilities.AreValuesEqual(expectedSolution[i], solution[i], 10e-9); } }
internal void AddElementMatrix(IMatrixView elementMatrix, int[] elementDofsFree, int[] subdomainDofsFree, int[] elementDofsConstrained, int[] subdomainDofsConstrained) { dokConstrFree.AddSubmatrix(elementMatrix, elementDofsConstrained, subdomainDofsConstrained, elementDofsFree, subdomainDofsFree); dokConstrConstr.AddSubmatrixSymmetric(elementMatrix, elementDofsConstrained, subdomainDofsConstrained); }
public virtual IMatrix StiffnessMatrix(IElement element) { double[, ,] afE = new double[iInt3, 6, 6]; for (int i = 0; i < iInt3; i++) { IMatrixView constitutive = materialsAtGaussPoints[i].ConstitutiveMatrix; for (int j = 0; j < 6; j++) { for (int k = 0; k < 6; k++) { afE[i, j, k] = constitutive[j, k]; } } } double[,] faXYZ = GetCoordinates(element); double[,] faDS = new double[iInt3, 24]; double[,] faS = new double[iInt3, 8]; double[, ,] faB = new double[iInt3, 24, 6]; double[] faDetJ = new double[iInt3]; double[, ,] faJ = new double[iInt3, 3, 3]; double[] faWeight = new double[iInt3]; double[] faK = new double[300]; CalcH8GaussMatrices(ref iInt, faXYZ, faWeight, faS, faDS, faJ, faDetJ, faB); CalcH8K(ref iInt, afE, faB, faWeight, faK); return(dofEnumerator.GetTransformedMatrix(SymmetricMatrix.CreateFromPackedRowMajorArray(faK))); }
/// <summary> /// See <see cref="IMatrixView.LinearCombination(double, IMatrixView, double)"/>. /// </summary> public IMatrix LinearCombination(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is Matrix2by2 casted) { return(LinearCombination(thisCoefficient, casted, otherCoefficient)); } else if (thisCoefficient == 1.0) { return(Axpy(otherMatrix, otherCoefficient)); } else { Preconditions.CheckSameMatrixDimensions(this, otherMatrix); return(new Matrix2by2(new double[, ] { { thisCoefficient *data[0, 0] + otherCoefficient * otherMatrix[0, 0], thisCoefficient *data[0, 1] + otherCoefficient * otherMatrix[0, 1] }, { thisCoefficient *data[1, 0] + otherCoefficient * otherMatrix[1, 0], thisCoefficient *data[1, 1] + otherCoefficient * otherMatrix[1, 1] }, })); } }
internal static void CheckNullSpace(IMatrixView unfactorizedMatrix, IReadOnlyList <double[]> nullSpaceBasis, double tolerance) { var comparer = new MatrixComparer(tolerance); // Check that each vector belongs to the nullspace int order = unfactorizedMatrix.NumColumns; //var zeroVector = Vector.CreateZero(order); int nullity = nullSpaceBasis.Count; var nullSpaceMatrix = Matrix.CreateZero(order, nullity); for (int j = 0; j < nullity; ++j) { var x = Vector.CreateFromArray(nullSpaceBasis[j]); nullSpaceMatrix.SetSubcolumn(j, x); // Check that each vector belongs to the nullspace IVector Ax = unfactorizedMatrix.Multiply(x); double normAx = Ax.Norm2() / Ax.Length; //comparer.AssertEqual(0.0, normAx); } // Check that the vectors are independent. // TODO: perhaps this should be included in the LinearAlgebra project, not just for tests. (Matrix rref, List <int> independentCols) = nullSpaceMatrix.ReducedRowEchelonForm(tolerance); for (int j = 0; j < nullity; ++j) { Assert.Contains(j, independentCols); } }
public virtual IMatrix StiffnessMatrix(IElement element) { double[,] coordinates = this.GetCoordinates(element); GaussLegendrePoint3D[] integrationPoints = this.CalculateGaussMatrices(coordinates); SymmetricMatrix stiffnessMatrix = SymmetricMatrix.CreateZero(8); int pointId = -1; foreach (GaussLegendrePoint3D intPoint in integrationPoints) { pointId++; IMatrixView constitutiveMatrix = materialsAtGaussPoints[pointId].ConstitutiveMatrix; double[,] b = intPoint.DeformationMatrix; for (int i = 0; i < 8; i++) { double[] eb = new double[3]; for (int iE = 0; iE < 3; iE++) { eb[iE] = (constitutiveMatrix[iE, 0] * b[0, i]) + (constitutiveMatrix[iE, 1] * b[1, i]) + (constitutiveMatrix[iE, 2] * b[2, i]); } for (int j = i; j < 8; j++) { double stiffness = (b[0, j] * eb[0]) + (b[1, j] * eb[1]) + (b[2, j] * eb[2]); stiffnessMatrix[i, j] += stiffness * intPoint.WeightFactor * Thickness; } } } return(stiffnessMatrix); }
public static Vector Multiply(IMatrixView matrix, IVectorView vector, bool transposeMatrix) { if (transposeMatrix) { Preconditions.CheckMultiplicationDimensions(matrix.NumRows, vector.Length); var result = Vector.CreateZero(matrix.NumColumns); for (int i = 0; i < result.Length; ++i) { for (int j = 0; j < vector.Length; ++j) { result[i] += matrix[j, i] * vector[j]; } } return(result); } else { Preconditions.CheckMultiplicationDimensions(matrix.NumColumns, vector.Length); var result = Vector.CreateZero(matrix.NumRows); for (int i = 0; i < result.Length; ++i) { for (int j = 0; j < vector.Length; ++j) { result[i] += matrix[i, j] * vector[j]; } } return(result); } }
/// <summary> /// See <see cref="IMatrixView.LinearCombination(double, IMatrixView, double)"/>. /// </summary> public IMatrix LinearCombination(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is CscMatrix otherCSC) // In case both matrices have the exact same index arrays { if (HasSameIndexer(otherCSC)) { // Do not copy the index arrays, since they are already spread around. TODO: is this a good idea? double[] resultValues = new double[values.Length]; if (thisCoefficient == 1.0) { Array.Copy(this.values, resultValues, values.Length); Blas.Daxpy(values.Length, otherCoefficient, otherCSC.values, 0, 1, this.values, 0, 1); } else if (otherCoefficient == 1.0) { Array.Copy(otherCSC.values, resultValues, values.Length); Blas.Daxpy(values.Length, thisCoefficient, this.values, 0, 1, resultValues, 0, 1); } else { Array.Copy(this.values, resultValues, values.Length); BlasExtensions.Daxpby(values.Length, otherCoefficient, otherCSC.values, 0, 1, thisCoefficient, resultValues, 0, 1); } return(new CscMatrix(NumRows, NumColumns, resultValues, this.rowIndices, this.colOffsets)); } } // All entries must be processed. TODO: optimizations may be possible (e.g. only access the nnz in this matrix) return(DenseStrategies.LinearCombination(this, thisCoefficient, otherMatrix, otherCoefficient)); }
//TODO: Use Skyline assembler private SkylineMatrix CreateGlobalKccStar(Dictionary <int, HashSet <INode> > cornerNodesOfSubdomains, FetiDPDofSeparator dofSeparator, Dictionary <int, IFetiDPSubdomainMatrixManager> matrixManagers) { int[] skylineColHeights = FindSkylineColumnHeights(cornerNodesOfSubdomains, dofSeparator); var skylineBuilder = SkylineBuilder.Create(dofSeparator.NumGlobalCornerDofs, skylineColHeights); for (int s = 0; s < subdomains.Count; ++s) { IFetiDPSubdomainMatrixManager matrices = matrixManagers[s]; // KccStar[s] = Kcc[s] - Krc[s]^T * inv(Krr[s]) * Krc[s] if (subdomains[s].StiffnessModified) { Debug.WriteLine($"{this.GetType().Name}: Calculating Schur complement of remainder dofs" + " for the stiffness of subdomain {s}"); matrices.CalcSchurComplementOfRemainderDofs(); //TODO: At this point Kcc and Krc can be cleared. Maybe Krr too. } int[] subdomainToGlobalIndices = dofSeparator.CornerBooleanMatrices[s].GetRowsToColumnsMap(); IMatrixView subdomainMatrix = matrices.SchurComplementOfRemainderDofs; skylineBuilder.AddSubmatrixSymmetric(subdomainMatrix, subdomainToGlobalIndices); } return(skylineBuilder.BuildSkylineMatrix()); }
/// <summary> /// Performs the matrix-vector multiplication: oper(this) * <paramref name="vector"/>. /// To multiply this * columnVector, set <paramref name="transposeThis"/> to false. /// To multiply rowVector * this, set <paramref name="transposeThis"/> to true. /// The resulting vector will be written in a new vector and returned. /// </summary> /// <param name="vector"> /// A vector with Length being equal to the <see cref="IIndexable2D.NumColumns"/> of oper(this). /// </param> /// <param name="transposeThis">If true, oper(this) = transpose(this). Otherwise oper(this) = this.</param> /// <exception cref="NonMatchingDimensionsException"> /// Thrown if <paramref name="vector"/>.Length is different than the <see cref="IIndexable2D.NumColumns"/> of oper(this). /// </exception> public static double[] Multiply(this IMatrixView matrix, double[] vector, bool transposeThis = false) { var result = new double[transposeThis ? matrix.NumColumns : matrix.NumRows]; matrix.MultiplyIntoResult(Vector.CreateFromArray(vector), Vector.CreateFromArray(result), transposeThis); return(result); }
public static void MultiplyIntoResult(IMatrixView matrix, IVectorView lhsVector, IVector rhsVector, bool transposeMatrix) { if (transposeMatrix) { Preconditions.CheckMultiplicationDimensions(matrix.NumRows, lhsVector.Length); Preconditions.CheckSystemSolutionDimensions(matrix.NumColumns, rhsVector.Length); for (int i = 0; i < rhsVector.Length; ++i) { for (int j = 0; j < lhsVector.Length; ++j) { rhsVector.Set(i, rhsVector[i] + matrix[j, i] * lhsVector[j]); } } } else { Preconditions.CheckMultiplicationDimensions(matrix.NumColumns, lhsVector.Length); Preconditions.CheckSystemSolutionDimensions(matrix.NumRows, rhsVector.Length); for (int i = 0; i < rhsVector.Length; ++i) { for (int j = 0; j < lhsVector.Length; ++j) { rhsVector.Set(i, rhsVector[i] + matrix[i, j] * lhsVector[j]); } } } }
public static void CheckStaticCondensation() { double tolerance = 1E-10; Model model = CreateModel(); int id = model.Subdomains.First().ID; var solver = (new SkylineSolver.Builder()).BuildSolver(model); var problem = new ProblemStructural(model, solver); // Prepare model model.ConnectDataStructures(); // Order dofs and initialize linear system solver.OrderDofs(true); ILinearSystem linearSystem = solver.LinearSystems.First().Value; linearSystem.Reset(); // Necessary to define the linear system's size // Build and assign global matrices (IMatrixView Kff, IMatrixView Kfc, IMatrixView Kcf, IMatrixView Kcc) = problem.CalculateSubMatrices(model.Subdomains.First()); linearSystem.Matrix = Kff; // Static condensation: Kcondensed = Kcc - Kcf * inv(Kff) * Kfc Dictionary <int, Matrix> invKffTimesKfc = solver.InverseSystemMatrixTimesOtherMatrix( new Dictionary <int, IMatrixView>() { { id, Kfc } }); IMatrixView condensedK = Kcc.Subtract(Kcf.MultiplyRight(invKffTimesKfc[id])); // Checks Assert.True(expectedCondensedK.Equals(condensedK, tolerance)); }
public GaussLegendrePoint3D(double ksi, double heta, double zeta, IMatrixView deformationMatrix, double weightFactor) { this.Ksi = ksi; this.Heta = heta; this.Zeta = zeta; this.B = deformationMatrix; WeightFactor = weightFactor; }
protected override Matrix InverseSystemMatrixTimesOtherMatrix(IMatrixView otherMatrix) { var watch = new Stopwatch(); // Factorization if (mustFactorize) { watch.Start(); factorization = CholeskySuiteSparse.Factorize(linearSystem.Matrix, useSuperNodalFactorization); watch.Stop(); Logger.LogTaskDuration("Matrix factorization", watch.ElapsedMilliseconds); watch.Reset(); mustFactorize = false; } // Substitutions watch.Start(); Matrix solutionVectors; if (otherMatrix is Matrix otherDense) { return(factorization.SolveLinearSystems(otherDense)); } else { try { // If there is enough memory, copy the RHS matrix to a dense one, to speed up computations. //TODO: must be benchmarked, if it is actually more efficient than solving column by column. Matrix rhsVectors = otherMatrix.CopyToFullMatrix(); solutionVectors = factorization.SolveLinearSystems(rhsVectors); } catch (InsufficientMemoryException) //TODO: what about OutOfMemoryException? { // Solution vectors int systemOrder = linearSystem.Matrix.NumColumns; int numRhs = otherMatrix.NumColumns; solutionVectors = Matrix.CreateZero(systemOrder, numRhs); Vector solutionVector = linearSystem.CreateZeroVectorConcrete(); // Solve each linear system separately, to avoid copying the RHS matrix to a dense one. for (int j = 0; j < numRhs; ++j) { if (j != 0) { solutionVector.Clear(); } Vector rhsVector = otherMatrix.GetColumn(j); factorization.SolveLinearSystem(rhsVector, solutionVector); solutionVectors.SetSubcolumn(j, solutionVector); } } } watch.Stop(); Logger.LogTaskDuration("Back/forward substitutions", watch.ElapsedMilliseconds); Logger.IncrementAnalysisStep(); return(solutionVectors); }
public IMatrix LinearCombination(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is SymmetricMatrix casted) { return(LinearCombination(thisCoefficient, casted, otherCoefficient)); } else { return(DoEntrywise(otherMatrix, (x1, x2) => thisCoefficient * x1 + otherCoefficient * x2)); //TODO: optimize this } }
/// <summary> /// See <see cref="IEntrywiseOperableView2D{TMatrixIn, TMatrixOut}.DoEntrywise(TMatrixIn, Func{double, double, double})"/>. /// </summary> public IMatrix DoEntrywise(IMatrixView other, Func <double, double, double> binaryOperation) { if (other is SymmetricMatrix casted) { return(DoEntrywise(casted, binaryOperation)); } else { return(DenseStrategies.DoEntrywise(this, other, binaryOperation)); //TODO: optimize this } }
public IMatrix Axpy(IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is SymmetricMatrix casted) { return(Axpy(casted, otherCoefficient)); } else { return(DoEntrywise(otherMatrix, (x1, x2) => x1 + otherCoefficient * x2)); //TODO: optimize this } }
/// <summary> /// See <see cref="IMatrix.AxpyIntoThis(IMatrixView, double)"/>. /// </summary> public void AxpyIntoThis(IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is TriangularLower casted) { AxpyIntoThis(casted, otherCoefficient); } else { throw new SparsityPatternModifiedException( "This operation is legal only if the other matrix is also lower triangular."); } }
/// <summary> /// See <see cref="IMatrix.AxpyIntoThis(IMatrixView, double)"/>. /// </summary> public void AxpyIntoThis(IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is CsrMatrix casted) { AxpyIntoThis(casted, otherCoefficient); } else { throw new SparsityPatternModifiedException( "This operation is legal only if the other matrix has the same sparsity pattern"); } }
/// <summary> /// See <see cref="IMatrix.LinearCombinationIntoThis(double, IMatrixView, double)"/>. /// </summary> public void LinearCombinationIntoThis(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is CscMatrix casted) { LinearCombinationIntoThis(thisCoefficient, casted, otherCoefficient); } else { throw new SparsityPatternModifiedException( "This operation is legal only if the other matrix has the same sparsity pattern"); } }
private readonly Vector lagrangesParticular; // only needed when separating the lagranges during PCG public ExactFeti1PcgConvergence(IMatrixView globalStiffness, IVectorView globalForces, double globalForcesNorm, Feti1Solver fetiSolver, Feti1ProjectedInterfaceProblemSolver interfaceProblemSolver, Feti1Projection projection, Vector lagrangesParticular) { this.globalStiffness = globalStiffness; this.globalForces = globalForces; this.globalForcesNorm = globalForcesNorm; this.fetiSolver = fetiSolver; this.interfaceProblemSolver = interfaceProblemSolver; this.projection = projection; this.lagrangesParticular = lagrangesParticular; }
public MatrixControlPrototype(IMatrixView parentView) { InitializeComponent(); _parentView = parentView; { var headerTapGesture = new TapGestureRecognizer(); headerTapGesture.Tapped += OnHeaderTapped; cnvTitle.GestureRecognizers.Add(headerTapGesture); } }
/// <summary> /// See <see cref="IMatrix.LinearCombinationIntoThis(double, IMatrixView, double)"/>. /// </summary> public void LinearCombinationIntoThis(double thisCoefficient, IMatrixView otherMatrix, double otherCoefficient) { if (otherMatrix is TriangularUpper casted) { LinearCombinationIntoThis(thisCoefficient, casted, otherCoefficient); } else { throw new SparsityPatternModifiedException( "This operation is legal only if the other matrix is also upper triangular."); } }
/// <summary> /// Performs the operation: result = transpose(<paramref name="dense"/>) * <paramref name="other"/> * <paramref name="dense"/> /// in an efficient way, by appropriately selecting which methods should be called for these matrices and in what order. /// </summary> /// <param name="dense">The matrix that will be multiplied "outside".</param> /// <param name="other">The matrix that will be multiplied "inside". It must be square.</param> public static Matrix ThisTransposeTimesOtherTimesThis(this Matrix dense, IMatrixView other) { //TODO: Perhaps this should not be a separate method than the one where other is Matrix if (other is Matrix otherDense) { return(dense.ThisTransposeTimesOtherTimesThis(otherDense)); } //TODO: perhaps I should dedice about the order of multiplications depending on the number of columns of each matrix Matrix temp = other.MultiplyRight(dense, false, false); return(dense.MultiplyRight(temp, true, false)); }
public static Matrix Transpose(IMatrixView matrix) { var result = Matrix.CreateZero(matrix.NumColumns, matrix.NumRows); for (int j = 0; j < matrix.NumColumns; ++j) { for (int i = 0; i < matrix.NumRows; ++i) { result[j, i] = matrix[i, j]; } } return(result); }
public void GenerateMatrices(IMatrixView matrix, IModelOverlappingDecomposition modelOverlappingDecomposition) { _modelOverlappingDecomposition = modelOverlappingDecomposition; _matrixOrder = matrix.NumRows; inverseMatrices = new Matrix[modelOverlappingDecomposition.NumberOfSubdomains]; for (int i = 0; i < modelOverlappingDecomposition.NumberOfSubdomains; i++) { var subdomainConnectivity = modelOverlappingDecomposition.GetConnectivityOfSubdomain(i); var submatrix = matrix.GetSubmatrix(subdomainConnectivity, subdomainConnectivity).CopyToFullMatrix(); inverseMatrices[i] = submatrix.Invert(); } }
/// <summary> /// Copies the entries of the matrix into a 2-dimensional array. The returned array has length(0) = number of rows /// and length(1) = number of columns. /// </summary> public static double[,] CopytoArray2D(this IMatrixView matrix) { var clone = new double[matrix.NumRows, matrix.NumColumns]; for (int i = 0; i < matrix.NumRows; ++i) { for (int j = 0; j < matrix.NumColumns; ++j) { clone[i, j] = matrix[i, j]; } } return(clone); }
public OverlappingAdditiveSchwarzPreconditioner(IMatrixView matrix, ICoarseProblemFactory coarseProblemFactory, LocalProblemsFactory localProblemsFactory, IModelOverlappingDecomposition modelOverlappingDecomposition, IAsymmetricModel model) { modelOverlappingDecomposition.DecomposeMatrix(); coarseProblemFactory.GenerateMatrices(matrix, modelOverlappingDecomposition); localProblemsFactory.GenerateMatrices(matrix, modelOverlappingDecomposition); var coarseProblemContribution = coarseProblemFactory.RetrievePreconditionerContribution(); var localProblemsContribution = localProblemsFactory.RetrievePreconditionerContribution(); var freeSubdomainDofs = model.GlobalRowDofOrdering.MapFreeDofsSubdomainToGlobal(model.Subdomains[0]); _preconditioner = coarseProblemContribution.Add(localProblemsContribution).GetSubmatrix(freeSubdomainDofs, freeSubdomainDofs); Order = _preconditioner.NumRows; }
/// <summary> /// See <see cref="IEntrywiseOperable2D{TMatrixIn}.DoEntrywiseIntoThis(TMatrixIn, Func{double, double, double})"/>. /// </summary> public void DoEntrywiseIntoThis(IMatrixView matrix, Func <double, double, double> binaryOperation) { if (matrix is Matrix2by2 casted) { DoEntrywiseIntoThis(casted, binaryOperation); } else { Preconditions.CheckSameMatrixDimensions(this, matrix); data[0, 0] = binaryOperation(data[0, 0], matrix[0, 0]); data[0, 1] = binaryOperation(data[0, 1], matrix[0, 1]); data[1, 0] = binaryOperation(data[1, 0], matrix[1, 0]); data[1, 1] = binaryOperation(data[1, 1], matrix[1, 1]); } }
public MatrixControl(IMatrixView parentView) { Padding = 1; var grd = new Grid () { RowSpacing = 1 }; grd.RowDefinitions.Add (new RowDefinition () { Height = GridLength.Auto }); grd.RowDefinitions.Add (new RowDefinition ()); { _cnvTitle = new ContentView () { BackgroundColor = Color.FromHex ("#4487CA"), IsVisible = false, Padding = new Thickness (Device.OnPlatform (5, 4, 5), 0, 0, 0) }; { _lblTitle = new Label () { TextColor = Color.White, FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Start, FontSize = Device.OnPlatform (10, 11, 10) }; _cnvTitle.Content = _lblTitle; } grd.Children.Add (_cnvTitle); } { _rootCanvas = new AbsoluteLayout (); Grid.SetRow (_rootCanvas, 1); grd.Children.Add (_rootCanvas); } Content = grd; _parentView = parentView; { var headerTapGesture = new TapGestureRecognizer (); headerTapGesture.Tapped += OnHeaderTapped; _cnvTitle.GestureRecognizers.Add (headerTapGesture); } }
private void DrawMatrix(IEnumerable<TreeMapItem> data, IMatrixView parentView) { if (_inProgress || ChildrenRect == null) return; rootCanvas.Children.Clear(); _inProgress = true; var gesture = new TapGestureRecognizer(); gesture.Tapped += _parentView.SelectCell; foreach (var rect in ChildrenRect) { View matrixCell = null; var treeMapItem = data.FirstOrDefault(gr => rect.ParentId == gr.ItemCode); if (treeMapItem != null) { var color = GetItemColor(treeMapItem); matrixCell = new MatrixCellControl(treeMapItem.ItemName, color, treeMapItem) { HeightRequest = rect.Height - cnvTitle.Height, WidthRequest = rect.Width }; matrixCell.GestureRecognizers.Add(gesture); } AbsoluteLayout.SetLayoutBounds(matrixCell, new Rectangle(rect.X, rect.Y, rect.Width - 3, rect.Height - 3)); rootCanvas.Children.Add(matrixCell); } _inProgress = false; }