/*! * This method is called at the commencement of a visual drag. If the offsets * to the caret are too big, this method will adjust them and shift the image * of the dragged text to a comfortable distance fromthe caret. * Returns true if the offsets are shifted. * UT_sint32 x pos of the caret * UT_sint32 y pos of the caret */ bool FV_VisualDragText::reposOffsets(UT_sint32 x, UT_sint32 y) { UT_sint32 dx = 0; UT_sint32 dy = 0; bool bAdjustX = false; bool bAdjustY = false; UT_sint32 iext = getGraphics()->tlu(3); dx = x - m_recCurFrame.left - m_recOrigLeft.width; dy = y - m_recCurFrame.top; UT_DEBUGMSG((" repos dx = %d \n",dx)); UT_DEBUGMSG((" repos dy = %d \n",dy)); UT_Rect expX(0,m_recCurFrame.top,0,m_recCurFrame.height); UT_Rect expY(m_recCurFrame.left,0,m_recCurFrame.width,0); if(abs(dx) > getGraphics()->tlu(40)) { bAdjustX = true; dx -= getGraphics()->tlu(20); m_iInitialOffX -= dx; expX.set(0,m_recCurFrame.top,0,m_recCurFrame.height); m_recCurFrame.left += dx; m_recOrigLeft.left += dx; m_recOrigRight.left += dx; } if(dy > getGraphics()->tlu(40)) { bAdjustY = true; dy -= getGraphics()->tlu(20); m_iInitialOffY -= dy; expY.set(m_recCurFrame.left,0,m_recCurFrame.width,0); m_recCurFrame.top += dy; m_recOrigLeft.top += dy; m_recOrigRight.top += dy; } if(bAdjustX && dx < 0) { expX.left = m_recCurFrame.left+m_recCurFrame.width -iext; expX.width = -dx + 2*iext; if(dy > 0) { expX.top -= iext; expX.height += dy + 2*iext; } else { expX.top -= iext; expX.height += (-dy + 2*iext); } } else if(bAdjustX) { expX.left = m_recCurFrame.left - dx - iext; expX.width = dx + 2*iext; if(dy > 0) { expX.top -= iext; expX.height += dy + 2*iext; } else { expX.top -= iext; expX.height += (-dy + 2*iext); } } expY.left -= iext; expY.width += 2*iext; if(bAdjustY && dy < 0) { expY.top = m_recCurFrame.top + m_recCurFrame.height -iext; expY.height = -dy + 2*iext; } else if(bAdjustY) { expY.top = m_recCurFrame.top - dy - iext; expY.height = dy + 2*iext; } if(bAdjustX && expX.width > 0) { getGraphics()->setClipRect(&expX); m_pView->updateScreen(false); } if(bAdjustY && (expY.height > 0)) { getGraphics()->setClipRect(&expY); m_pView->updateScreen(false); } if(bAdjustX || bAdjustY) { getGraphics()->setClipRect(NULL); drawImage(); if(m_recOrigLeft.width > 0) { getGraphics()->setClipRect(&m_recOrigLeft); m_pView->updateScreen(false); } if(m_recOrigRight.width > 0) { getGraphics()->setClipRect(&m_recOrigRight); m_pView->updateScreen(false); } return true; } return false; }
// Perform exact (and slower) NR test using the exact fisher information matrix. vector<double> LogisticRegression::newtonRaphson(const vector<vector<double> > &data, const vector<double> &response, vector<vector<double> > &invInfMatrix, double startVal) { vector<double> betas; // Variables used in the computation: alglib::real_1d_array tempBetas; alglib::real_2d_array tempData; alglib::real_2d_array tempDataTrans; alglib::real_1d_array oldExpY; alglib::real_2d_array hessian; // holds data' * w * data. Returned in last input param. alglib::real_1d_array expY; alglib::real_1d_array W; // holds diagonal of the w matrix above. alglib::real_1d_array adjy; alglib::real_1d_array work; double stop_var = 1e-10; int iter = 0; int maxIter = 200; int numVars = data.size(); if(numVars < 1){ throw NewtonRaphsonFailureEx(); } int numSamples = data.at(0).size(); if(numSamples < 1){ throw NewtonRaphsonFailureEx(); } tempBetas.setlength(numVars); tempData.setlength(numSamples,numVars); tempDataTrans.setlength(numVars, numSamples); oldExpY.setlength(numSamples); expY.setlength(numSamples); hessian.setlength(numVars, numVars); adjy.setlength(numSamples); W.setlength(numSamples); work.setlength(numVars); for(int i=0;i < numVars; i++){ for(int j=0;j < numSamples; j++){ tempData(j,i) = data.at(i).at(j); } tempBetas(i) = startVal; } for(int i=0;i < numSamples;i++){ oldExpY(i) = -1; adjy(i) = 0; // makes valgrind happier. } // End initial setup. // In each iteration, create a hessian and a first derivative. while(iter < maxIter){ //adjy <- data * tempBetas (get new y guess) matrixvectormultiply(tempData, 0, numSamples-1,0,numVars-1,false, tempBetas, 0, numVars-1, 1.0, adjy, 0, numSamples-1, 0.0); // adjy = 1 / (1 + exp(-adjy)) for(int i=0;i < numSamples; i++){ expY(i) = 1 / (1 + exp(-adjy(i))); } // build deriv. for(int i=0;i < numSamples; i++){ W(i) = expY(i) * (1 - expY(i)); } // adjy = adjy + (y-expy) ./ deriv for(int i=0;i<numSamples;i++){ adjy(i) = adjy(i) + (response.at(i) - expY(i)) / W(i); } // build data' * w * data // set to hessian. // Also doing secondary computation (see inside) for(int i=0; i < numVars; i++){ for(int j=0; j < numVars; j++) hessian(i,j) = 0.0; } for(int indiv=0; indiv < numSamples; ++indiv){ for(int i = 0; i < numVars; i++){ for(int j = 0; j < numVars; j++){ hessian(i,j) += W(indiv) * tempData(indiv, j) * tempData(indiv, i); } // NOTE: as a speedup, I'm also computing X' * W tempDataTrans(i, indiv) = W(indiv) * tempData(indiv, i); } } alglib::matinvreport report; alglib::ae_int_t reportInfo; rmatrixinverse(hessian, reportInfo, report); if(reportInfo != 1 ){ throw SingularMatrixEx(); } // Check condition number. if (report.r1 < condition_number_limit){ throw ConditionNumberEx(1.0/report.r1); } // work <- X'W * adjy matrixvectormultiply(tempDataTrans,0,numVars-1,0,numSamples-1,false, adjy,0,numSamples-1,1, work,0,numVars-1,0.0); // tempBetas <= invHessian * work matrixvectormultiply(hessian,0,numVars-1,0,numVars-1,false, work,0,numVars-1,1.0, tempBetas,0,numVars-1,0.0); #if DEBUG_NR cout << "Betas "; for(int i=0;i < numVars;i++) cout << tempBetas(i) << " " ; cout << endl; #endif double stop = 0.0; // Could be computed as a 1-norm. // This should be done as a sum of abs diff. for(int i=0;i < numSamples;i++){ stop += abs(expY(i) - oldExpY(i)); } if (stop < numSamples*stop_var){ break; } oldExpY = expY; iter++; } if(iter == maxIter){ throw NewtonRaphsonIterationEx(); } betas.clear(); for(int i=0;i<numVars;i++){ betas.push_back(tempBetas(i)); } for(int i=0;i<numVars;i++){ for(int j=0;j<numVars;j++){ invInfMatrix.at(i).at(j) = hessian(i,j); } } //dumpMatrix(invInfMatrix); return betas; }
void FV_VisualDragText::_mouseDrag(UT_sint32 x, UT_sint32 y) { // // Don't try to drag the entire document. // if(!m_bDoingCopy && (m_pView->isSelectAll() && !m_pView->isHdrFtrEdit())&&(m_iVisualDragMode != FV_VisualDrag_DRAGGING)) { setMode(FV_VisualDrag_NOT_ACTIVE); return; } if(m_iVisualDragMode == FV_VisualDrag_NOT_ACTIVE) { m_iInitialOffX = x; m_iInitialOffY = y; m_iVisualDragMode = FV_VisualDrag_WAIT_FOR_MOUSE_DRAG; UT_DEBUGMSG(("Initial call for drag -1\n")); return; } if((m_iInitialOffX == 0) && (m_iInitialOffY == 0)) { m_iInitialOffX = x; m_iInitialOffY = y; m_iVisualDragMode = FV_VisualDrag_WAIT_FOR_MOUSE_DRAG; UT_DEBUGMSG(("Initial call for drag -2 \n")); } if(m_iVisualDragMode == FV_VisualDrag_WAIT_FOR_MOUSE_DRAG) { double diff = sqrt((static_cast<double>(x) - static_cast<double>(m_iInitialOffX))*(static_cast<double>(x) - static_cast<double>(m_iInitialOffX)) + (static_cast<double>(y) - static_cast<double>(m_iInitialOffY))*(static_cast<double>(y) - static_cast<double>(m_iInitialOffY))); if(diff < static_cast<double>(getGraphics()->tlu(MIN_DRAG_PIXELS))) { UT_DEBUGMSG(("Not yet dragged enough.%f \n", diff)); // // Have to drag 4 pixels before initiating the drag // return; } else { m_iVisualDragMode = FV_VisualDrag_START_DRAGGING; XAP_Frame * pFrame = static_cast<XAP_Frame*>(m_pView->getParentData()); if (pFrame) pFrame->dragText(); } } if((m_iVisualDragMode != FV_VisualDrag_DRAGGING) && (m_iVisualDragMode != FV_VisualDrag_WAIT_FOR_MOUSE_DRAG) && !m_bDoingCopy) { // // Haven't started the drag yet so create our image and cut the text. // m_pView->getDocument()->beginUserAtomicGlob(); mouseCut(m_iInitialOffX,m_iInitialOffY); m_bTextCut = true; } clearCursor(); if(m_iVisualDragMode == FV_VisualDrag_START_DRAGGING) { reposOffsets(x,y); } m_iVisualDragMode = FV_VisualDrag_DRAGGING; xxx_UT_DEBUGMSG(("x = %d y = %d width \n",x,y)); bool bScrollDown = false; bool bScrollUp = false; bool bScrollLeft = false; bool bScrollRight = false; m_xLastMouse = x; m_yLastMouse = y; if(y<=0) { bScrollUp = true; } else if( y >= m_pView->getWindowHeight()) { bScrollDown = true; } if(x <= 0) { bScrollLeft = true; } else if(x >= m_pView->getWindowWidth()) { bScrollRight = true; } if(bScrollDown || bScrollUp || bScrollLeft || bScrollRight) { if(m_pAutoScrollTimer != NULL) { return; } m_pAutoScrollTimer = UT_Timer::static_constructor(_autoScroll, this); m_pAutoScrollTimer->set(AUTO_SCROLL_MSECS); m_pAutoScrollTimer->start(); return; } UT_sint32 dx = 0; UT_sint32 dy = 0; UT_Rect expX(0,m_recCurFrame.top,0,m_recCurFrame.height); UT_Rect expY(m_recCurFrame.left,0,m_recCurFrame.width,0); UT_sint32 iext = getGraphics()->tlu(3); dx = x - m_iLastX; dy = y - m_iLastY; m_recCurFrame.left += dx; m_recCurFrame.top += dy; m_recOrigLeft.left += dx; m_recOrigLeft.top += dy; m_recOrigRight.left += dx; m_recOrigRight.top += dy; if(dx < 0) { expX.left = m_recCurFrame.left+m_recCurFrame.width -iext; expX.width = -dx + 2*iext; if(dy > 0) { expX.top -= iext; expX.height += dy + 2*iext; } else { expX.top -= iext; expX.height += (-dy + 2*iext); } } else { expX.left = m_recCurFrame.left - dx - iext; expX.width = dx + 2*iext; if(dy > 0) { expX.top -= iext; expX.height += dy + 2*iext; } else { expX.top -= iext; expX.height += (-dy + 2*iext); } } expY.left -= iext; expY.width += 2*iext; if(dy < 0) { expY.top = m_recCurFrame.top + m_recCurFrame.height -iext; expY.height = -dy + 2*iext; } else { expY.top = m_recCurFrame.top - dy - iext; expY.height = dy + 2*iext; } if(!m_bNotDraggingImage && (expX.width > 0)) { getGraphics()->setClipRect(&expX); if(m_bSelectedRow) { m_pView->setSelectionMode(FV_SelectionMode_NONE); } m_pView->updateScreen(false); if(m_bSelectedRow) { m_pView->setSelectionMode(FV_SelectionMode_TableRow); } } if(!m_bNotDraggingImage && (expY.height > 0)) { xxx_UT_DEBUGMSG(("expY left %d top %d width %d height %d \n",expY.left,expY.top,expY.width,expY.height)); getGraphics()->setClipRect(&expY); if(m_bSelectedRow) { m_pView->setSelectionMode(FV_SelectionMode_NONE); } m_pView->updateScreen(false); if(m_bSelectedRow) { m_pView->setSelectionMode(FV_SelectionMode_TableRow); } } if(!m_bNotDraggingImage && (expX.height > 0)) { xxx_UT_DEBUGMSG(("expY left %d top %d width %d height %d \n",expX.left,expX.top,expX.width,expX.height)); getGraphics()->setClipRect(&expX); if(m_bSelectedRow) { m_pView->setSelectionMode(FV_SelectionMode_NONE); } m_pView->updateScreen(false); if(m_bSelectedRow) { m_pView->setSelectionMode(FV_SelectionMode_TableRow); } } if(!m_bNotDraggingImage) { getGraphics()->setClipRect(NULL); drawImage(); if(m_recOrigLeft.width > 0) { getGraphics()->setClipRect(&m_recOrigLeft); m_pView->updateScreen(false); } if(m_recOrigRight.width > 0) { getGraphics()->setClipRect(&m_recOrigRight); m_pView->updateScreen(false); } } m_iLastX = x; m_iLastY = y; getGraphics()->setClipRect(NULL); PT_DocPosition posAtXY = getPosFromXY(x,y); m_pView->_setPoint(posAtXY); xxx_UT_DEBUGMSG(("Point at visual drag set to %d \n",m_pView->getPoint())); // m_pView->_fixInsertionPointCoords(); drawCursor(posAtXY); }
/* * @depricated * * NR implementation by RTG. * * Note on matrix vector multiplication: * void matrixmatrixmultiply(const alglib::real_2d_array& a, * int ai1, * int ai2, * int aj1, * int aj2, * bool transa, * const alglib::real_2d_array& b, * int bi1, * int bi2, * int bj1, * int bj2, * bool transb, * double alpha, * alglib::real_2d_array& c, * int ci1, * int ci2, * int cj1, * int cj2, * double beta, * alglib::real_1d_array& work); * * transa is true if transposed. * Operation is: c = A * alpha * b + beta * C * * * @input const vector<vector<double>> data holds explantory variables. each inner vector is a variable. * @input const vector<double> response holds response variable. * @input vector<double> Place to return the information matrix inverse. Column major order. * Expects correct size. */ vector<double> LogisticRegression::newtonRaphsonFast(const vector<vector<double> > &data, const vector<double> &response , vector<vector<double> > &invInfMatrix, double startVal) { vector<double> betas; // Variables used in the computation: alglib::real_1d_array tempBetas; alglib::real_2d_array tempData; alglib::real_1d_array oldExpY; alglib::real_2d_array tempDeriv; // holds data' * w * data. Returned in last input param. alglib::real_1d_array expY; alglib::real_1d_array adjy; double stop_var = 1e-10; int iter = 0; int maxIter = 200; int numVars = data.size(); if(numVars < 1){ throw NewtonRaphsonFailureEx(); } int numSamples = data.at(0).size(); if(numSamples < 1){ throw NewtonRaphsonFailureEx(); } tempBetas.setlength(numVars); tempData.setlength(numSamples,numVars); oldExpY.setlength(numSamples); expY.setlength(numSamples); tempDeriv.setlength(numVars,numVars); adjy.setlength(numSamples); for(int i=0;i < numVars; i++){ for(int j=0;j < numSamples; j++){ tempData(j,i) = data.at(i).at(j); } tempBetas(i) = startVal; } for(int i=0;i < numSamples;i++){ oldExpY(i) = -1; adjy(i) = 0; // makes valgrind happier. } while(iter < maxIter){ //data * tempBetas matrixvectormultiply(tempData, 0, numSamples-1,0,numVars-1,false, tempBetas, 0, numVars-1, 1.0, adjy, 0, numSamples-1, 0.0); for(int i=0;i < numSamples; i++){ expY(i) = 1 / (1 + exp(-adjy(i))); } // build deriv. double deriv = -100000; for(int i=0;i < numSamples; i++){ if(expY(i) * (1 - expY(i)) > deriv) deriv = expY(i) * (1 - expY(i)); } if(stop_var * 0.001 > deriv) deriv = stop_var * 0.001; // adjy = adjy + (y-expy) ./ deriv for(int i=0;i<numSamples;i++){ adjy(i) = adjy(i) + (response.at(i) - expY(i)) / deriv; } // build data' * w * data alglib::real_1d_array work; work.setlength(numSamples); // This temporary workspace must be one larger than the longest // row or column that will be seen. Otherwise, the program // crashes or - worse! - corrupts data. matrixmatrixmultiply(tempData,0,numSamples-1,0,numVars-1,true, tempData,0,numSamples-1,0,numVars-1,false,deriv, tempDeriv,0,numVars-1,0,numVars-1,0.0,work); #if DEBUG_NR cout << "A' * w * A " << endl; cout << tempDeriv(0,0) << " " << tempDeriv(0,1) << endl; cout << tempDeriv(1,0) << " " << tempDeriv(1,1) << endl; cout << endl; #endif alglib::matinvreport report; alglib::ae_int_t reportInfo; rmatrixinverse(tempDeriv, reportInfo, report); if( reportInfo != 1 ){ throw SingularMatrixEx(); } #if DEBUG_NR cout << "inv(A' * w * A) " << endl; cout << tempDeriv(0,0) << " " << tempDeriv(0,1) << endl; cout << tempDeriv(1,0) << " " << tempDeriv(1,1) << endl; cout << endl; #endif matrixvectormultiply(tempData,0,numSamples-1,0,numVars-1,true, adjy,0,numSamples-1,deriv, work,0,numVars-1,0.0); matrixvectormultiply(tempDeriv,0,numVars-1,0,numVars-1,false, work,0,numVars-1,1.0, tempBetas,0,numVars-1,0.0); #if DEBUG_NR cout << "Betas "; for(int i=0;i < numVars;i++) cout << tempBetas(i) << " " ; cout << endl; #endif double stop = 0.0; for(int i=0;i < numSamples;i++){ stop += abs(expY(i) - oldExpY(i)); } if (stop < numSamples*stop_var){ break; } oldExpY = expY; iter++; } if(iter == maxIter){ throw NewtonRaphsonIterationEx(); } betas.clear(); for(int i=0;i<numVars;i++){ betas.push_back(tempBetas(i)); } for(int i=0;i<numVars;i++){ for(int j=0;j<numVars;j++){ invInfMatrix.at(i).at(j) = tempDeriv(i,j); } } return betas; }