ম্যাট্রিক্স বর্গমূলের বিপরীতমুখী দক্ষ গণনা


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। ম্যাট্রিক্স বর্গমূলের বিপরীতমুখীকরণের আরও কার্যকর উপায় আছে কি? আর eigenফাংশনটি ল্যাপাককে কল করে


(+ +||)/2সর্বোচ্চ(,0)একজন-1/2একজন-1/2এক্স

@ ড্যানিয়েল শ্যাপারো আপনার মন্তব্যের জন্য ধন্যবাদ। সুতরাং আমার যদি পিএসডি ম্যাট্রিক্স থাকে তবে আমার সেই লাইনের দরকার নেই? আমার আবেদন যেমন দ্বিঘাত ফর্ম কম্পিউটিং প্রয়োজন । একজন-1/2বিএকজন-1/2
tchakravarty

আমি আর এর সাথে পরিচিত নই, তবে প্রদত্ত লাইন I আমি ধরে নিচ্ছি যে এটি মাতলাবের মতো লজিকাল সূচক রয়েছে। যদি তা হয়, তবে আমি আপনাকে 5 লাইনটি পুনরায় লেখার পরামর্শ দিচ্ছি d[d<0] = 0, যা আরও অভিব্যক্তিপূর্ণ।
ফেডেরিকো পোলোনি

এই কোডটি কি সঠিক? আমি এটি মাতলাব-এর একটি সাধারণ উদাহরণে চালিয়েছি এবং উত্তরটি ভুল বলে খুঁজে পেয়েছি। আমার ম্যাট্রিক্স ইতিবাচক সুনিশ্চিত তবে অবশ্যই প্রতিসাম্য নয়। দয়া করে নীচে আমার উত্তরটি দেখুন: আমি কোডটি মাতলাবে স্থানান্তর করেছি।
রনি

উত্তর:


10

কোড আছে, আপনি ব্যবহারসমূহ প্রতিসম ম্যাট্রিক্স eigenvalue পচানি পোস্ট করেছেন গনা । একজন-1/2

বিবৃতি

D = (ঘ + ABS (ঘ)) / 2

অ-নেতিবাচক এন্টারগুলি একা রেখে, কার্যকরভাবে ডি তে যে কোনও নেতিবাচক এন্ট্রি নেয় এবং এটি 0 তে সেট করে। অর্থাৎ কোন নেতিবাচক eigenvalue যেন এটা 0. ছিল তত্ত্ব, একটি এর eigenvalues সমস্ত অ-নেতিবাচক হওয়া উচিত চিকিত্সা করা হয়, কিন্তু বাস্তবে ছোট নেতিবাচক eigenvalues দেখতে এটা সাধারণ যখন আপনি একটি কল্পনানুসারে ইতিবাচক নির্দিষ্ট এর eigenvalues গনা কোভরিয়েন্স ম্যাট্রিক্স যা প্রায় একবাক্য। একজন

আপনার যদি সত্যই এর প্রতিসাম্য ম্যাট্রিক্স বর্গমূলের বিপরীতমুখী প্রয়োজন হয় , এবং যুক্তিযুক্তভাবে ছোট (1,000 বলে 1,000 বলে বড় নয়) তবে এটি আপনার ব্যবহার করা কোনও পদ্ধতির মতোই ভাল। একজনএকজন

অনেক ক্ষেত্রে আপনি পরিবর্তে কোভেরিয়েন্স ম্যাট্রিক্সের বিপরীত চোলস্কি ফ্যাক্টরটি ব্যবহার করতে পারেন (বা কার্যত একই, কোভেরিয়েন্স ম্যাট্রিক্সের চোলস্কি ফ্যাক্টর নিজেই।) কোলেস্কি ফ্যাক্টরটি গণনা করা সাধারণত এগ্রেনালু পচনকে গণনার চেয়ে দ্রুততরতার একটি ক্রম হয় is বড় এবং স্পার্স ম্যাট্রিক্সের জন্য ঘন ম্যাট্রিক্স এবং প্রচুর পরিমাণে দক্ষ (গণনার সময় এবং প্রয়োজনীয় স্টোরেজ উভয়) সুতরাং বড় এবং বিরল হয়ে গেলে Cholesky factorization ব্যবহার করা খুব আকাঙ্ক্ষিত হয়ে যায় । একজন


6
ব্রায়ানের উত্তরটি ভাল পরামর্শ দেয়: পরিবর্তে Cholesky ফ্যাক্টরটি ব্যবহার করুন (যদি পারেন তবে)। এর উপরে আপনি আরও একটি অপ্টিমাইজেশন করতে পারেন: আপনার পিএসডি ম্যাট্রিক্স গণনা করবেন না । প্রায়শই আপনি পেতে মত একটি গণনার থেকে সঙ্গে, আয়তক্ষেত্রাকার। এই ক্ষেত্রে, এটি একটি কিউ পচানি গনা যথেষ্ট Cholesky ফ্যাক্টর প্রাপ্ত এর অনেক ভালো সঠিকতা সঙ্গে। = বি টি বি বি বি আর একজনএকজনএকজন=বিটিবিবিবিআরএকজন
ফেডেরিকো পোলোনি

5

আমার অভিজ্ঞতা অনুসারে, হিগামের পোলার-নিউটন পদ্ধতিটি আরও দ্রুত কাজ করে ( এন। হিগাম দ্বারা ম্যাট্রিক্সের ফাংশনগুলির অধ্যায় 6 দেখুন )। ইন আমার এই সংক্ষিপ্ত নোট প্লট যে প্রথম-অর্ডার পদ্ধতি এই পদ্ধতি তুলনা আছে। এছাড়াও, বেশ কয়েকটি অন্যান্য ম্যাট্রিক্স-স্কোয়ার-রুটের পদ্ধতির উদ্ধৃতি উপস্থাপন করা হয়েছে, যদিও বেশিরভাগ মেরু নিউটনের পুনরাবৃত্তি সবচেয়ে ভাল কাজ করে বলে মনে হয় (এবং ইগেনভেেক্টর গণনা করা এড়ানো)।

% 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 - আপনার আর কোডটি অনুকূলিত করুন:
ক। আপনি যে উভয় এবং একটি লুপ apply()একটি ফাংশন করতে পারেন । খ। সরাসরি অপারেটিং চেষ্টা করুন ।dmax(d,0)d2[d==0]=0
ei$values

বিকল্প 2 - সি ++ ব্যবহার করুন:
সি ++ এর সাথে পুরো ফাংশনটি আবার লিখুন RcppArmadillo। আপনি এখনও এটি আর থেকে কল করতে সক্ষম হবেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.