মতলবতে কখন বিএসএক্সফুন ব্যবহার করা অনুকূল?


135

আমার প্রশ্ন: আমি লক্ষ্য করেছি যে এসএসএর উপর মতলব প্রশ্নের প্রচুর ভাল উত্তর প্রায়শই ফাংশনটি ব্যবহার করে bsxfun। কেন?

অনুপ্রেরণা: এর জন্য মতলব ডকুমেন্টেশনে bsxfunনিম্নলিখিত উদাহরণটি সরবরাহ করা হয়েছে:

A = magic(5);
A = bsxfun(@minus, A, mean(A))

অবশ্যই আমরা ব্যবহার করে একই অপারেশন করতে পারি:

A = A - (ones(size(A, 1), 1) * mean(A));

এবং প্রকৃতপক্ষে একটি সাধারণ গতি পরীক্ষা দেখায় যে দ্বিতীয় পদ্ধতিটি প্রায় 20% দ্রুত। তাহলে কেন প্রথম পদ্ধতিটি ব্যবহার করবেন? আমি অনুমান করছি এমন কিছু পরিস্থিতি রয়েছে যেখানে bsxfun"ম্যানুয়াল" পদ্ধতির তুলনায় ব্যবহার করা আরও দ্রুত হবে। আমি কেন এমন পরিস্থিতির একটি উদাহরণ এবং কেন এটি দ্রুততর হয় তার ব্যাখ্যা দেখতে সত্যিই আগ্রহী হব।

এছাড়াও, এই প্রশ্নের একটি চূড়ান্ত উপাদান, আবার মতলব ডকুমেন্টেশন থেকে এর জন্য bsxfun: "সি = বিএসএক্সফুন (মজা, এ, বি) ফাংশন হ্যান্ডেল মজাদার দ্বারা নির্দিষ্ট করা উপাদান-বাই-উপাদান বাইনারি অপারেশন প্রয়োগ করে সিঙ্গেলটন সহ অ্যারে এবং এ। সম্প্রসারণ সক্ষম। "সিঙ্গেলটন সম্প্রসারণ সহ সক্ষম" শব্দটির অর্থ কী?


4
দ্রষ্টব্য যে আপনি যে দ্রুত গতি পেয়েছেন তা আপনার সম্পাদন করা পরীক্ষার উপর নির্ভর করে। মতলব পুনরায় চালু করার পরে যদি আপনি উপরের কোডটি চালান এবং কেবল tic...tocলাইনগুলি প্রায় লাগিয়ে দেন তবে কোডটির গতি মেমোরিতে ফাংশনগুলি পড়ার উপর নির্ভর করবে।
জোনাস

@ জোনাস হ্যাঁ, timeitআপনি / অ্যাংগেনার / ড্যানের লিঙ্কে ফাংশনটি পড়ে আমি কেবল এটি সম্পর্কে জানতে পারি ।
কলিন টি বোয়ার্স

উত্তর:


152

আমি ব্যবহার করার তিনটি কারণ রয়েছে bsxfun( ডকুমেন্টেশন , ব্লগ লিঙ্ক )

  1. bsxfunএর চেয়ে দ্রুত repmat(নীচে দেখুন)
  2. bsxfun টাইপিং কম প্রয়োজন
  3. ব্যবহার bsxfun, ব্যবহারের মতো accumarray, আমাকে মতলব সম্পর্কে আমার বোঝার বিষয়ে ভাল লাগায়।

bsxfunইনপুট অ্যারেগুলি তাদের "সিঙ্গেলটন মাত্রা" বরাবর প্রতিলিপি তৈরি করবে, অর্থাত অ্যারের আকার যে আকারের সাথে 1 হয়, যাতে তারা অন্য অ্যারের সাথে সম্পর্কিত মাত্রার আকারের সাথে মেলে। এটিকেই বলা হয় "সিঙ্গেলটন এক্সপেশন" " অন্যদিকে, একক মাত্রা হ'ল আপনি কল করলে তা বাদ দেওয়া হবেsqueeze

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

আমি repmatএবং এর মধ্যে একটি গতি তুলনা চালিয়েছিbsxfun আমার শালীন দ্রুত ল্যাপটপটিতে আর ২০১২ বি এর সাথে চালিয়েছি।

এখানে চিত্র বর্ণনা লিখুন

আমার জন্য, bsxfunতুলনায় প্রায় 3 গুণ দ্রুতrepmat । অ্যারে বড় হয়ে গেলে পার্থক্য আরও প্রকট হয়ে ওঠে

এখানে চিত্র বর্ণনা লিখুন

রানটাইমের লাফ repmat 1Mb এর অ্যারের আকারের চারপাশে ঘটে, যা আমার প্রসেসরের ক্যাশের আকারের সাথে কিছু করতে পারে -bsxfun একটি জাম্পের মতো খারাপ হয় না, কারণ এটির জন্য কেবল আউটপুট অ্যারে বরাদ্দ করা দরকার।

আমি নীচের সময়টি ব্যবহার করার জন্য যে কোডটি ব্যবহার করেছি তা নীচে খুঁজে পাবেন:

n = 300;
k=1; %# k=100 for the second graph
a = ones(10,1);
rr = zeros(n,1);
bb=zeros(n,1);
ntt=100;
tt=zeros(ntt,1);
for i=1:n;
   r = rand(1,i*k);
   for it=1:ntt;
      tic,
      x=bsxfun(@plus,a,r);
      tt(it)=toc;
   end;
   bb(i)=median(tt);
   for it=1:ntt;
      tic,
      y=repmat(a,1,i*k)+repmat(r,10,1);
      tt(it)=toc;
   end;
   rr(i)=median(tt);
end

একটি দুর্দান্ত প্রতিক্রিয়া জন্য +1 ধন্যবাদ। আমি এটির উত্তরটি চিহ্নিত করেছি কারণ এটি সর্বাধিক বিস্তৃত আলোচনা এবং সর্বাধিক আপ-ভোটও পেয়েছে।
কলিন টি বোয়র্স

40

আমার ক্ষেত্রে, আমি ব্যবহার করি bsxfun কারণ এটি কলাম বা সারি সম্পর্কিত সমস্যাগুলি সম্পর্কে চিন্তা করতে আমাকে এড়িয়ে চলে।

আপনার উদাহরণ লিখতে যাতে:

A = A - (ones(size(A, 1), 1) * mean(A));

আমাকে বেশ কয়েকটি সমস্যা সমাধান করতে হবে:

1) size(A,1)বাsize(A,2)

2) ones(sizes(A,1),1)বাones(1,sizes(A,1))

3) ones(size(A, 1), 1) * mean(A)বাmean(A)*ones(size(A, 1), 1)

4) mean(A)বাmean(A,2)

আমি যখন ব্যবহার করি তখন আমাকে bsxfunকেবল শেষটি সমাধান করতে হবে:

ক) mean(A)বাmean(A,2)

আপনার মনে হতে পারে এটা অলস বা কিছু, কিন্তু যখন আমি ব্যবহার bsxfun, আমি কম বাগ এবং আমি দ্রুত প্রোগ্রাম

তদুপরি, এটি সংক্ষিপ্ত, যা টাইপিংয়ের গতি এবং পাঠযোগ্যতার উন্নতি করে


1
ওলি সাড়া দেওয়ার জন্য ধন্যবাদ। +1 হিসাবে আমি মনে করি এই উত্তরটি অ্যাঞ্জিনোর এবং জোনাসের প্রতিক্রিয়াগুলি ছাড়াও কিছু অবদান রেখেছে। আপনি নির্দিষ্টভাবে কোডের একটি লাইনে সমাধান করার জন্য যে সংবেদনশীল সমস্যার সংখ্যা নির্ধারণ করেছেন তা আমি বিশেষভাবে পছন্দ করেছি।
কলিন টি বোয়ার্স

16

খুব মজার প্রশ্ন! এই প্রশ্নের উত্তর দেওয়ার সময় আমি ঠিক ঠিক এমন পরিস্থিতি নিয়ে হোঁচট খেয়েছি । নিম্নলিখিত কোডটি বিবেচনা করুন যা ভেক্টরের মাধ্যমে 3 মাপের স্লাইডিং উইন্ডোর সূচকগুলিকে গণনা করে a:

a = rand(1e7,1);

tic;
idx = bsxfun(@plus, [0:2]', 1:numel(a)-2);
toc

% equivalent code from im2col function in MATLAB
tic;
idx0 = repmat([0:2]', 1, numel(a)-2);
idx1 = repmat(1:numel(a)-2, 3, 1);
idx2 = idx0+idx1;
toc;

isequal(idx, idx2)

Elapsed time is 0.297987 seconds.
Elapsed time is 0.501047 seconds.

ans =

 1

এই ক্ষেত্রে bsxfunপ্রায় দ্বিগুণ দ্রুততর! এটি দরকারী এবং দ্রুত কারণ এটি ম্যাট্রিক্সের জন্য মেমরির সুস্পষ্ট বরাদ্দ এড়ানোidx0 এবংidx1 এগুলিকে মেমরিতে সঞ্চয় করে এবং তারপরে কেবল তাদের যুক্ত করার জন্য এগুলি আবার পড়তে পারে। যেহেতু মেমরি ব্যান্ডউইথ একটি মূল্যবান সম্পদ এবং প্রায়শই আজকের আর্কিটেকচারের বাধা হয়ে থাকে তাই আপনি দক্ষতার সাথে এটি ব্যবহার করতে চান এবং কার্যকারিতা উন্নত করতে আপনার কোডের মেমরির প্রয়োজনীয়তা হ্রাস করতে চান।

bsxfunআপনাকে কেবল এটি করতে দেয়: ভেক্টরগুলির প্রতিলিপি তৈরির মাধ্যমে দুটি ম্যাট্রিকগুলিতে স্পষ্টত অপারেটিংয়ের পরিবর্তে দুটি ভেক্টরের সমস্ত জোড় উপাদানগুলিতে স্বেচ্ছাসেবক অপারেটরের প্রয়োগের ভিত্তিতে একটি ম্যাট্রিক্স তৈরি করুন। তা হ'ল সিঙ্গলটন সম্প্রসারণ । আপনি এটিকে BLAS থেকে বাহ্যিক পণ্য হিসাবেও ভাবতে পারেন :

v1=[0:2]';
v2 = 1:numel(a)-2;
tic;
vout = v1*v2;
toc
Elapsed time is 0.309763 seconds.

আপনি একটি ম্যাট্রিক্স পেতে দুটি ভেক্টরকে গুণান। কেবলমাত্র যে বাহ্যিক পণ্যটি কেবল গুণ করে এবং bsxfunস্বেচ্ছাসেবী অপারেটরগুলি প্রয়োগ করতে পারে। পার্শ্ব নোট হিসাবে, এটি দেখতে খুব আকর্ষণীয় যে bsxfunএটি BLAS বাইরের পণ্য হিসাবে তত দ্রুত। এবং BLAS সাধারণত সম্পাদনা প্রদান করা হয় ..

ড্যানের মন্তব্যে ধন্যবাদ সম্পাদনা করুন, লরেনের ঠিক এটি নিয়েই আলোচনা করা একটি দুর্দান্ত নিবন্ধ


7
এই নিবন্ধটি প্রাসঙ্গিক হতে পারে: ব্লগস.ম্যাথ ওয়ার্কস
ড্যান

@ ড্যান একটি দুর্দান্ত রেফারেন্সের জন্য ধন্যবাদ।
অ্যাঙ্গেইনর

একটি দুর্দান্ত সাড়া আঙ্গিকার জন্য ধন্যবাদ। bsxfunএকটি ভাল উদাহরণের প্রধান সুবিধাটি স্পষ্টভাবে প্রথম উল্লেখ করার জন্য +1 ।
কলিন টি বোয়র্স

13

R2016b হিসাবে, মতলব বিভিন্ন অপারেটরগুলির জন্য অন্তর্ভুক্ত সম্প্রসারণকে সমর্থন করে , তাই বেশিরভাগ ক্ষেত্রে এটি ব্যবহারের আর প্রয়োজন হয় না bsxfun:

পূর্বে, এই কার্যকারিতাটি ফাংশনের মাধ্যমে উপলব্ধ ছিল bsxfun। এখন আপনাকে সুপারিশ করা হয় যে আপনি bsxfunফাংশন এবং অপারেটরগুলিকে সরাসরি কল সহ বেশিরভাগ ব্যবহারগুলি প্রতিস্থাপন করুন যা অন্তর্নিহিত প্রসারণকে সমর্থন করে । ব্যবহার তুলনায় bsxfun, অন্তর্নিহিত সম্প্রসারণ অফার দ্রুত গতি , ভাল মেমোরি ব্যবহার , এবং কোডের উন্নত পাঠযোগ্যতা

একটা ব্যাপার বিস্তারিত আলোচনা এর অন্তর্নিহিত সম্প্রসারণ এবং লরেন এর ব্লগ উপর তার কর্মক্ষমতা। করার উদ্ধৃত MathWorks থেকে স্টিভ Eddins:

R2016b এ, অন্তর্নিহিত সম্প্রসারণbsxfun বেশিরভাগ ক্ষেত্রেের চেয়ে দ্রুত বা দ্রুত কাজ করে । অন্তর্নিহিত সম্প্রসারণের জন্য সেরা পারফরম্যান্স লাভগুলি হ'ল ছোট্ট ম্যাট্রিক্স এবং অ্যারের আকারের সাথে। বড় ম্যাট্রিক্স আকারের জন্য, অন্তর্নিহিত সম্প্রসারণ মোটামুটি একই গতিতে থাকে bsxfun


8

জিনিসগুলি সর্বদা 3 সাধারণ পদ্ধতির সাথে সামঞ্জস্যপূর্ণ নয় repmat:, সূচকগুলি অনুসারে এক্সপেনশন এবং bsxfun। এটি আরও আকর্ষণীয় হয়ে ওঠে যখন আপনি আরও বেশি করে ভেক্টরের আকার বাড়িয়ে তোলেন। প্লট দেখুন:

তুলনা

bsxfunঅন্য মুহুর্তে অন্য মুহুর্তের তুলনায় কিছুটা ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে দ্রুত গতি ফিরে আসবে 3x তাদের গতি পদক্ষেপে ঝাঁপিয়ে পড়ে মনে হয় এবং ক্রমটি সর্বদা সুসংগত হয় না। আমার ধারণা এটি প্রসেসর / মেমরি আকারের উপর নির্ভরশীলও হতে পারে তবে সাধারণত আমি মনে করি আমি bsxfunযখনই সম্ভব সম্ভব থাকব with

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