/* Computation of the matrix W that is used in the function ComputeAlphasIQM(). * * Input: ndata = number of observation rectangles. * R = observation rectangles (in canonical form). * w = w[i]=1/max(P[i],tol), where P[i] is the mass in * observation rectangle R[i]. * m = number of maximal intersections with positive mass. * t = upper right corners of maximal intersections with positive mass * (in canonical form). * Output: W = matrix W used in the function ComputeAlphasIQM(). * W is a symmetric matrix. We only store its upper triangle * (including the diagonal), column by column. To translate between * the full matrix a[i][j], i=0..m-1, j=0..m-1 and the compactly stored * matrix W[i], i=0..m*(m+1)/2, use a[i][j] = W[i+j*(j+1)/2], for i<=j. */ void ComputeW(int ndata, SCanonRect *R, double *w, int m, SIntPoint *t, double *W) { int i, j, k, lengthW; lengthW = m*(m+1)/2; for (i=0; i<lengthW; i++) W[i] = 0; for (i=0; i<m; i++) { for (j=0; j<ndata; j++) { if (IsInRectangle(&t[i],&R[j])) { for (k=i; k<m; k++) { if (IsInRectangle(&t[k],&R[j])) W[i+k*(k+1)/2] += SQR(w[j]); /* add to element a[i][k] */ } } } } for (i=0; i<lengthW; i++) W[i] = W[i]/ndata; }
/* The following procedure computes the minimum of the derivatives of the * criterion function for the LS part (see Maathuis (2003, page 51, eq (5.10)). * At the end of the iteration loop, this minimum should be * nonnegative or bigger than some allowed negative tolerance. * * Input: ndata = number of observation rectangles * R = observation rectangles (in canonical form) * P = probability mass in each observation rectangle (not used if m==0) * w = w[i] = 1/max(tol,P[i]) * mm = number of maximal intersections * tt = upper right corners of maximal intersections (in canonical form) * m = number of maximal intersections that get positive mass * * Output: index = index (in 0,..mm-1) at which minimum occurs. * return value = minimum of the derivatives of the criterion function * for the least squares part. */ double ComputeMinimumIQM (int ndata, SCanonRect *R, double P[], double *w, int mm, SIntPoint *tt, int m, int *indexmin) { int j, k; double sum, min=0; if (m==0) { for (k=0; k<mm; k++) { sum = 0; for (j=0; j<ndata; j++) { if (IsInRectangle(&tt[k],&R[j])) sum -= w[j]; } sum *= 2; if (sum<min) { min = sum; *indexmin = k; } } return min; } /* else, if m>0: */ for (k=0; k<mm; k++) { sum = 0; for (j=0; j<ndata; j++) { if (IsInRectangle(&tt[k],&R[j])) { sum += P[j]*SQR(w[j]) - 2*w[j]; } } sum = sum/ndata + 1; if (sum<min) { min = sum; *indexmin = k; } } return min; }
/* Computation of the coefficients alpha that satisfy the equality part of * Maathuis (2003, page 50, eq (5.9)) for all alpha's with positive mass. * The alpha's are a solution of a linear system of equations with * a symmetric (but not positive definite) matrix of coefficients. It is solved using * the function SolveSymmetricLinearSystem(),which uses a LAPACK routine. * * Input: ndata = number of observation rectangles * R = observation rectangles (in canonical form) * w = w[i]=1/max(tol,P[i]), where P[i] is mass in observation rectangle R[i] * m = number of maximal intersections with positive mass * t = upper right corners of maximal intersections with positive mass * i_dummy_mm = dummy array needed in function SolveSymmetricLinearSystem * (this array is allocated in MLE_IQM() to limit number of memory allocations) * d_dummy_mm = right hand side of linear system. * (this array is allocated in MLE_IQM() to limit number of memory allocations) * * Output: alpha = alpha[i] is new probability mass corresponding to t[i]. */ void ComputeAlphasIQM (int ndata, SCanonRect *R, double *w, int m, SIntPoint *t, double alpha[], int *i_dummy_mm, double *d_dummy_mm) { int i, j; double *W; W = Calloc(m*(m+1)/2, double); /* compute matrix a, based on vectors R, w and t */ ComputeW(ndata,R,w,m,t,W); for (i=0; i<m; i++) { d_dummy_mm[i]=0; for (j=0; j<ndata; j++) { if (IsInRectangle(&t[i],&R[j])) d_dummy_mm[i] += w[j]; } } for (i=0; i<m; i++) d_dummy_mm[i] = 2*d_dummy_mm[i]/ndata - 1; SolveSymmetricLinearSystem(W,m,d_dummy_mm,1,i_dummy_mm); MemCopy(alpha,d_dummy_mm,m); Free(W); }
/* Computes P_F(R_i), probability masses in the observation rectangles * * Input: ndata = number of observation rectangles * R = observation rectangles (in canonical form) * m = number of maximal intersections * t = upper right corners of maximal intersections with positive mass * (in canonical form) * alpha = alpha[i] is probability mass corresponding to t[i] * * Output: P = P[i] is probability mass in observation rectangle R[i] */ void ComputeProbabilities(int ndata, SCanonRect *R, int m, SIntPoint *t, double alpha[], double P[]) { int i, k; for (i=0; i<ndata; i++) { P[i] = 0; for (k=0; k<m; k++) { if (IsInRectangle(&t[k],&R[i])) P[i] += alpha[k]; } } }
/* Computes nabla: vector of partial derivatives of object function w.r.t. alpha[j], * see Maathuis (2003, page 49, eq (5.5)) * * Input: ndata = number of observation rectangles * R = observation rectangles (in canonical form) * P = P[i] is probability mass in observation rectangle R[i] * m = number of maximal intersections with positive mass * t = upper right corners of maximal intersections with positive mass * (in canonical form) * * Output: nabla = vector of partial derivatives of object function w.r.t. alpha[j], j=0..m-1, see Maathuis (2003, page 49, eq (5.5)). */ void ComputeNabla(int ndata, SCanonRect *R, double P[], int m, SIntPoint *t, double tol, double nabla[]) { int j, k; double sum; for (k=0; k<m; k++) { sum = 0; for (j=0; j<ndata; j++) { if (IsInRectangle(&t[k],&R[j])) { if (P[j]>tol) sum += 1/P[j]; else sum += 1/tol; } } nabla[k] = 1.0 - sum/ndata; } }
inline void EndElement(layout_element *Element) { layout *Layout = Element->Layout; debug_state *DebugState = Layout->DebugState; r32 SizeHandlePixels = 4.0f; v2 Frame = V2(0, 0); if (Element->Size) { Frame.x = SizeHandlePixels; Frame.y = SizeHandlePixels; } v2 TotalDim = *Element->Dim + 2.0f * Frame; v2 TotalMinCorner = V2(Layout->At.x + Layout->Depth * 2.0f * Layout->LineAdvance, Layout->At.y - TotalDim.y); v2 TotalMaxCorner = TotalMinCorner + TotalDim; v2 InteriorMinCorner = TotalMinCorner + Frame; v2 InteriorMaxCorner = InteriorMinCorner + *Element->Dim; rectangle2 TotalBounds = RectMinMax(TotalMinCorner, TotalMaxCorner); Element->Bounds = RectMinMax(InteriorMinCorner, InteriorMaxCorner); if (Element->Interaction.Type && IsInRectangle(Element->Bounds, Layout->MouseP)) { DebugState->NextHotInteraction = Element->Interaction; } if (Element->Size) { PushRect(DebugState->RenderGroup, RectMinMax(V2(TotalMinCorner.x, InteriorMinCorner.y), V2(InteriorMaxCorner.x, InteriorMaxCorner.y)), 0.0f, V4(0, 0, 0, 1)); PushRect(DebugState->RenderGroup, RectMinMax(V2(InteriorMaxCorner.x, InteriorMinCorner.y), V2(TotalMaxCorner.x, InteriorMaxCorner.y)), 0.0f, V4(0, 0, 0, 1)); PushRect(DebugState->RenderGroup, RectMinMax(V2(InteriorMinCorner.x, TotalMinCorner.y), V2(InteriorMaxCorner.x, InteriorMinCorner.y)), 0.0f, V4(0, 0, 0, 1)); PushRect(DebugState->RenderGroup, RectMinMax(V2(InteriorMinCorner.x, InteriorMaxCorner.y), V2(InteriorMaxCorner.x, TotalMaxCorner.y)), 0.0f, V4(0, 0, 0, 1)); debug_interaction SizeInteraction = {}; SizeInteraction.Type = DebugInteraction_Resize; SizeInteraction.P = Element->Size; rectangle2 SizeBox = RectMinMax(V2(InteriorMaxCorner.x, TotalMinCorner.y), V2(TotalMaxCorner.x, InteriorMinCorner.y)); PushRect(DebugState->RenderGroup, SizeBox, 0.0f, InteractionIsHot(DebugState, SizeInteraction) ? V4(1, 1, 0, 1) : V4(1, 1, 1, 1)); if (IsInRectangle(SizeBox, Layout->MouseP)) { DebugState->NextHotInteraction = SizeInteraction; } } r32 SpacingY = Layout->SpacingY; if (0) { SpacingY = 0.0f; } Layout->At.y = GetMinCorner(TotalBounds).y - SpacingY; }
internal void DrawProfileIn(debug_state *DebugState, rectangle2 ProfileRect, v2 MouseP) { PushRect(DebugState->RenderGroup, ProfileRect, 0.0f, V4(0, 0, 0, 0.25f)); r32 BarSpacing = 4.0f; r32 LaneHeight = 0.0f; u32 LaneCount = DebugState->FrameBarLaneCount; u32 MaxFrame = DebugState->FrameCount; if (MaxFrame > 10) { MaxFrame = 10; } if (LaneCount > 0 && MaxFrame > 0) { r32 PixelsPerFramePlusSpacing = GetDim(ProfileRect).y / (r32)MaxFrame; r32 PixelsPerFrame = PixelsPerFramePlusSpacing - BarSpacing; LaneHeight = PixelsPerFrame / (r32)LaneCount; } r32 BarHeight = LaneHeight * LaneCount; r32 BarsPlusSpacing = BarHeight + BarSpacing; r32 ChartLeft = ProfileRect.Min.x; r32 ChartHeight = BarSpacing * (r32)MaxFrame; r32 ChartWidth = GetDim(ProfileRect).x; r32 ChartTop = ProfileRect.Max.y; r32 Scale = ChartWidth * DebugState->FrameBarScale; v3 Colors[] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 0.5f, 0}, {1, 0, 0.5f}, {0.5f, 1, 0}, {0, 1, 0.5f}, {0.5f, 0, 1}, {0, 0.5f, 1}, }; #if 1 for (u32 FrameIndex = 0; FrameIndex < MaxFrame; ++FrameIndex) { debug_frame *Frame = DebugState->Frames + DebugState->FrameCount - (FrameIndex + 1); r32 StackX = ChartLeft; r32 StackY = ChartTop - BarsPlusSpacing * (r32)FrameIndex; r32 PrevTimestampSeconds = 0.0f; for (u32 RegionIndex = 0; RegionIndex < Frame->RegionCount; ++RegionIndex) { debug_frame_region *Region = Frame->Regions + RegionIndex; // v3 Color = Colors[RegionIndex % ArrayCount(Colors)]; v3 Color = Colors[Region->ColorIndex % ArrayCount(Colors)]; r32 ThisMinX = StackX + Scale * Region->MinT; r32 ThisMaxX = StackX + Scale * Region->MaxT; rectangle2 RegionRect = RectMinMax(V2(ThisMinX, StackY - LaneHeight * (Region->LaneIndex + 1)), V2(ThisMaxX, StackY - LaneHeight * Region->LaneIndex)); PushRect(DebugState->RenderGroup, RegionRect, 0.0f, V4(Color, 1)); if (IsInRectangle(RegionRect, MouseP)) { debug_record *Record = Region->Record; char buf[512]; snprintf(buf, 512, "%s: %10llucy [%s(%d)]\n", Record->BlockName, Region->CycleCount, Record->FileName, Record->LineNumber); DEBUGTextOutAt(MouseP + V2(0.0f, 10.0f), buf); // HotRecord = Record; } } } #endif #if 0 PushRect(RenderGroup, V3(ChartLeft + 0.5f * ChartWidth, ChartMinY + ChartHeight, 0.0f), V2(ChartWidth, 1.0f), V4(1, 1, 1, 1)); #endif }