मैट्रिक्स स्क्वायर रूट व्युत्क्रम की कुशल गणना


15

आंकड़ों में एक आम समस्या एक सममित सकारात्मक निश्चित मैट्रिक्स के वर्गमूल व्युत्क्रम की गणना कर रही है। यह कंप्यूटिंग का सबसे कुशल तरीका क्या होगा?

मुझे कुछ साहित्य (जो मैंने अभी तक नहीं पढ़े हैं), और कुछ आकस्मिक आर कोड यहाँ आए , जिन्हें मैं यहाँ अलग करने के लिए पुन: पेश करूँगा

# function to compute the inverse square root of a matrix
fnMatSqrtInverse = function(mA) {
  ei = eigen(mA)
  d = ei$values
      d = (d+abs(d))/2
      d2 = 1/sqrt(d)
      d2[d == 0] = 0
      return(ei$vectors %*% diag(d2) %*% t(ei$vectors))
}

मुझे पूरी तरह से यकीन नहीं है कि मैं लाइन को समझता हूं d = (d+abs(d))/2। क्या मैट्रिक्स स्क्वायर रूट व्युत्क्रम की गणना करने का एक अधिक कुशल तरीका है? R eigenफ़ंक्शन LAPACK को कॉल करता है


(+||)/2अधिकतम(,0)-1/2-1/2एक्स

@DanielShapero आपकी टिप्पणी के लिए धन्यवाद। इसलिए अगर मेरे पास PSD मैट्रिक्स है, तो मुझे उस लाइन की आवश्यकता नहीं है? मेरे आवेदन में जैसे द्विघात रूपों की गणना की आवश्यकता है । -1/2बी-1/2
tchakravarty

मैं R से परिचित नहीं हूं, लेकिन दी गई लाइन 7 मैं मानता हूं कि इसमें मैटलैब की तरह तार्किक अनुक्रमण है। यदि हां, तो मैं आपको लाइन 5 को फिर से लिखने का सुझाव देता हूं d[d<0] = 0, जो अधिक अभिव्यंजक है।
फेडरिको पोलोनी

क्या यह कोड सही है? मैंने इसे मैटलैब में एक सरल उदाहरण पर चलाया और गलत होने का उत्तर पाया। मेरा मैट्रिक्स सकारात्मक निश्चित है लेकिन निश्चित रूप से सममित नहीं है। कृपया नीचे मेरा उत्तर देखें: मैंने मैटलैब को कोड स्थानांतरित कर दिया है।
रौनी

जवाबों:


10

कोड है कि आप का उपयोग करता है गणना करने के लिए सममित मैट्रिक्स के eigenvalue अपघटन पोस्ट किया है -1/2

बयान

d = (d + पेट (घ)) / 2


6
=बीटीबीबीबीआर

5

मेरे अनुभव में, हिघम की ध्रुवीय-न्यूटन विधि बहुत तेजी से काम करती है ( एन.हिगम द्वारा मैट्रिसेस के कार्य के अध्याय 6 देखें )। में मेरा यह छोटे नोट भूखंडों कि प्रथम क्रम तरीकों के लिए इस विधि की तुलना कर रहे हैं। इसके अलावा, कई अन्य मैट्रिक्स-स्क्वायर-रूट दृष्टिकोणों के उद्धरण प्रस्तुत किए जाते हैं, हालांकि ज्यादातर ध्रुवीय न्यूटन पुनरावृत्ति सबसे अच्छा काम करने लगता है (और eigenvector गणना करने से बचता है)।

% compute the matrix square root; modify to compute inverse root.
function X = PolarIter(M,maxit,scal)
  fprintf('Running Polar Newton Iteration\n');
  skip = floor(maxit/10);
  I = eye(size(M));
  n=size(M,1);
  if scal
    tm = trace(M);
    M  = M / tm;
  else
    tm = 1;
  end
  nm = norm(M,'fro');

  % to compute inv(sqrt(M)) make change here
  R=chol(M+5*eps*I);

  % computes the polar decomposition of R
  U=R; k=0;
  while (k < maxit)
    k=k+1;
    % err(k) = norm((R'*U)^2-M,'fro')/nm;
    %if (mod(k,skip)==0)
    %  fprintf('%d: %E\n', k, out.err(k));
    %end

    iU=U\I;
    mu=sqrt(sqrt(norm(iU,1)/norm(U,1)*norm(iU,inf)/norm(U,inf)));
    U=0.5*(mu*U+iU'/mu);

   if (err(k) < 1e-12), break; end
  end
  X=sqrt(tm)*R'*U;
  X = 0.5*(X+X');
end

0

अपना कोड ऑप्टिमाइज़ करें:

विकल्प 1 - अपना R कोड ऑप्टिमाइज़ करें:
a। आप दोनों को और एक लूप में एक apply()फंक्शन कर सकते हैं । ख। सीधे संचालन का प्रयास करें ।dmax(d,0)d2[d==0]=0
ei$values

विकल्प 2 - C ++ का उपयोग करें: C ++
में पूरे फ़ंक्शन को फिर से लिखें RcppArmadillo। आप अभी भी इसे आर से कॉल कर पाएंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.