मैं एक MATLAB सरणी को किसी स्थानीय चर पर पहले असाइन किए बिना किसी फ़ंक्शन द्वारा कैसे लौटा सकता हूं?


363

उदाहरण के लिए, यदि मैं बीच का मान पढ़ना चाहता हूं, तो मैं magic(5)ऐसा कर सकता हूं:

M = magic(5);
value = M(3,3);

पाने के लिए value == 13। मैं इनमें से एक की तरह कुछ करने में सक्षम होना चाहता हूं:

value = magic(5)(3,3);
value = (magic(5))(3,3);

मध्यवर्ती चर के साथ वितरित करने के लिए। हालांकि, MATLAB Unbalanced or unexpected parenthesis or bracketपहले कोष्ठक पर पहले के बारे में शिकायत करता है 3

क्या किसी चर / मैट्रिक्स से मानों को पढ़ना संभव है, बिना पहले इसे एक चर में निर्दिष्ट किए बिना?


2
मुझे इस विषय पर निम्नलिखित लेख भी मिला: mathworks.com/matlabcentral/newsreader/view_thread/280225 इस विषय पर किसी को भी नई जानकारी है, क्या इसे लागू किया जाएगा?

2
यह सिंटैक्स वास्तव में ऑक्टेव में ठीक काम करता है। मुझे केवल इस समस्या का पता चला जब मेरे सहयोगी जो MATLAB का उपयोग करते हैं, मेरे कोड को चलाने में समस्याएँ थीं।
sffc

2
MATLAB संक्षेप में।
user76284

1
रिकर्सिव एक्सट्रैक्शन स्कैलाब ( scilab.org ) वर्जन 6. के बाद से भी काम करता है।
स्टीफन मोटललेट

testmatrix('magi', 5)(3, 3)साइलैब पर और magic(5)(3, 3)एक आकर्षण की तरह दोनों काम सप्टक पर!
फाद

जवाबों:


384

यह वास्तव में संभव है कि आप क्या चाहते हैं, लेकिन आपको अनुक्रमण ऑपरेटर के कार्यात्मक रूप का उपयोग करना होगा। जब आप एक अनुक्रमण ऑपरेशन का उपयोग करते हैं (), तो आप वास्तव में subsrefफ़ंक्शन को कॉल कर रहे हैं । तो, भले ही आप ऐसा नहीं कर सकते :

value = magic(5)(3, 3);

आप यह कर सकते हैं:

value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));

बदसूरत, लेकिन संभव है। ;)

सामान्य तौर पर, आपको बस इंडेक्सिंग स्टेप को एक फंक्शन कॉल में बदलना होगा ताकि आपके पास एक दूसरे के तुरंत बाद कोष्ठकों के दो सेट न हों। ऐसा करने का एक अन्य तरीका यह होगा कि आप अपने स्वयं के अनाम फ़ंक्शन को सबस्क्रिप्ट किए गए अनुक्रमण को परिभाषित करें । उदाहरण के लिए:

subindex = @(A, r, c) A(r, c);     % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3);  % Use the function to index the matrix

हालांकि, जब सभी ने कहा और किया जाता है अस्थायी स्थानीय चर समाधान है बहुत अधिक पठनीय है, और निश्चित रूप से मैं क्या सुझाव है।


26
ठीक है, आप क्या जानते हो! हालांकि मैं मानता हूँ कि यह बहुत बदसूरत है, और शायद एक अस्थायी संस्करण की तुलना में कम पठनीय है। प्रभावशाली अस्पष्ट matlab ज्ञान के लिए +1!
दूसरा

57
यह घृणित है, लेकिन एक बहुत ही स्पष्ट जवाब है। अच्छा कार्य! अनुमान लगाया जाना चाहिए कि इसमें एक बैक तरीका होगा। मुझे लगता है कि मैं अस्थायी चर के साथ ले जाऊँगा।
जो Kearney

29
ध्यान रखें कि मध्यवर्ती चर अभी भी पूरी तरह से बनाया गया है। तो अगर उद्देश्य एक अस्थायी स्थानीय चर बनाने से स्मृति को बचाने का है, तो कोई भाग्य नहीं।
सैम रॉबर्ट्स

8
@SamRoberts: आप वास्तव में मतलाब जैसी सख्त मूल्यांकन वाली भाषा के आसपास नहीं पहुँच सकते। मुख्य कारण लोग चाहते हैं कि यह संक्षिप्तता / पठनीयता हो, न कि स्मृति बचत।
मैकेनिकल घोंघा

5
@SamRoberts: सच है, लेकिन यह करता है बुला के बोझ से आप को बचाने clearअस्थायी पर (जो कोई भी कभी भी करता है) - अस्थायी आसपास लंबे समय तक रहना आदत
Rody Oldenhuis

131

बस नहीं था अच्छा ब्लॉग पोस्ट पर मैटलैब की कला पर लोरेन कुछ दिनों पहले एक जोड़े जवाहरात कि हो सकता है मदद से। विशेष रूप से, सहायक कार्यों का उपयोग करना जैसे:

paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};

जहां paren()इस्तेमाल किया जा सकता है

paren(magic(5), 3, 3);

लौटूंगा

ans = 16

मैं यह भी समझूंगा कि यह gnovice के उत्तर की तुलना में तेज़ होगा, लेकिन मैंने जांच नहीं की है (प्रोफाइलर का उपयोग करें)। यह कहा जा रहा है, आपको इन फ़ंक्शन परिभाषाओं को भी कहीं न कहीं शामिल करना होगा। मैंने व्यक्तिगत रूप से उन्हें अपने पथ में स्वतंत्र कार्य किया है, क्योंकि वे सुपर उपयोगी हैं।

ये फ़ंक्शन और अन्य अब कार्यात्मक प्रोग्रामिंग कंस्ट्रक्शंस ऐड-ऑन पर उपलब्ध हैं जो MATLAB ऐड-ऑन एक्सप्लोरर या फ़ाइल एक्सचेंज के माध्यम से उपलब्ध है ।


2
यह gnovice के उत्तर के उत्तरार्ध का थोड़ा और सामान्य संस्करण है; यह भी अच्छा।
जो किर्न

किस बारे में myfunc().attr?
गुरित

@gerrit, कैसे मदद करता है? और x.attr () फ़ील्ड तब तक उपलब्ध नहीं है जब तक आपके पास डेटाबेस टूलबॉक्स नहीं है।
टी। फुरफारो

@ T.Furfaro हुह? यदि myfunc()कोई संरचना देता है जिसमें एक विशेषता शामिल है attr, तो attrवर्तमान में उपयोग करने के लिए मुझे करना होगा S = myfunc(); S.attr। सवाल हम की तरह एक सहायक कार्य हो सकता है अगर है getattr(myfunc(), 'attr')के सादृश्य में parenऔर curlyसहायकों। मुझे समझ नहीं आ रहा है कि डेटाबेस टूलबॉक्स के साथ इसका क्या करना है।
गेरिट

2
@gerrit क्षमा करें, कुल भ्रम (मुझे नहीं पता था कि आपका "attr" मनमाना था - db tb में इस तरह की फील्ड एक्सप्लिसिटी परिभाषित है)। मेरा मानना है कि आप के लिए है जो खोज रहे हैं () getfield
टी Furfaro

75

आप अनिर्दिष्ट सुविधाओं का उपयोग करने के बारे में कैसा महसूस करते हैं:

>> builtin('_paren', magic(5), 3, 3)               %# M(3,3)
ans =
    13

या सेल सरणियों के लिए:

>> builtin('_brace', num2cell(magic(5)), 3, 3)     %# C{3,3}
ans =
    13

जादू की तरह :)


अपडेट करें:

बुरी खबर, उपरोक्त हैक R2015b में अब काम नहीं करता है ! यह ठीक है, यह अनिर्दिष्ट कार्यक्षमता थी और हम एक समर्थित सुविधा के रूप में इस पर भरोसा नहीं कर सकते :)

इस तरह की चीज़ को खोजने के लिए सोच रहे लोगों के लिए, फ़ोल्डर में देखें fullfile(matlabroot,'bin','registry')। वहाँ XML फ़ाइलों का एक गुच्छा है जो सभी प्रकार के उपहारों को सूचीबद्ध करता है। सावधान रहें कि इनमें से कुछ कार्यों को सीधे कॉल करना आपके MATLAB सत्र को आसानी से क्रैश कर सकता है।


@RodyOldenhuis: मुझे अब याद नहीं है, मुझे लगता है कि मैंने इसे कुछ दफन कोड में पढ़ा होगा;)
अमरो

2
':'त्रुटि से बचने के लिए कोलोन (:) ऑपरेटर को एपोस्ट्रोफ के साथ उपयोग किया जाना चाहिए Undefined function or variable "builtin"
डोमिनिक

@Dominik: सही है, आप 2 कॉलम को स्लाइस करना चाहते हैं, वह यह होगा: builtin('_paren', magic(5), ':', 2)(कुछ निश्चित स्थानों में यह बिना किसी :विरोध के सीधे उद्धरणों के बिना काम करता है ':', जैसे कि कमांड प्रॉम्प्ट में चलने पर सीधे फ़ंक्शन के अंदर से नहीं। यह
अमरो

2
मुझे नहीं लगता कि इसके endसाथ उपयोग करने का कोई तरीका है ?
knedlsepp

2
@knedlsepp: नहीं, दुर्भाग्य से पूरे end-trickery इस वाक्य रचना में काम नहीं, तो आप अपने अनुक्रमण में स्पष्ट होना पड़ेगा करता .. (एक ही सीमा अधिकांश अन्य सूचीबद्ध जवाब के लिए लागू होता है)
एमरो

54

कम से कम MATLAB 2013a में आप इसका उपयोग कर सकते हैं getfield:

a=rand(5);
getfield(a,{1,2}) % etc

तत्व प्राप्त करने के लिए (1,2)


5
यह वास्तव में एक अच्छी विधि है। कोई कमियां?
mmumboss

6
@mmumboss: यह अनिर्दिष्ट व्यवहार है, यह कार्यक्षमता भविष्य के संस्करणों में सूचना के बिना गायब हो सकती है। इसके अलावा कोई नुकसान नहीं।
डैनियल

6
MATLAB2017b के रूप में, यह कार्यक्षमता प्रलेखित है।
njspeer

15

दुर्भाग्य से सिंटैक्स की तरह magic(5)(3,3)मैटलैब द्वारा समर्थित नहीं है। आपको अस्थायी मध्यवर्ती चर का उपयोग करने की आवश्यकता है। आप उपयोग के बाद मेमोरी को मुक्त कर सकते हैं, जैसे

tmp = magic(3);
myVar = tmp(3,3);
clear tmp

12

ध्यान दें कि यदि आप मानक समय के साथ चलने के समय की तुलना करते हैं (परिणाम को असाइन करें और फिर प्रविष्टियों तक पहुंचें), वे बिल्कुल समान हैं।

subs=@(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0103

>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)

ans =

0.0101

मेरी राय में, लब्बोलुआब यह है: MATLAB में संकेत नहीं हैं, आपको इसके साथ रहना होगा।


6

यदि आप एक नया कार्य करते हैं तो यह अधिक सरल हो सकता है:

function [ element ] = getElem( matrix, index1, index2 )
    element = matrix(index1, index2);
end

और फिर इसका उपयोग करें:

value = getElem(magic(5), 3, 3);

1
लेकिन यह वही है जो subrefकरता है ... लेकिन अधिक सामान्य तरीके से।
Shai

2
हां, अधिक सामान्य तरीका, लेकिन अनुकूल नहीं ... मेरी राय में बहुत बदसूरत।
वगर

4

आपका प्रारंभिक अंकन ऐसा करने का सबसे संक्षिप्त तरीका है:

M = magic(5);  %create
value = M(3,3);  % extract useful data
clear M;  %free memory

यदि आप एक लूप में ऐसा कर रहे हैं, तो आप हर बार एम को फिर से असाइन कर सकते हैं और साथ ही स्पष्ट कथन को भी अनदेखा कर सकते हैं।


6
मैं मानता हूं कि यह अधिक संक्षिप्त है, और क्लियरिंग में एक अच्छा विचार है, जैसा कि आप कहते हैं, लेकिन सवाल विशेष रूप से था कि क्या मध्यवर्ती असाइनमेंट से बचा जा सकता है।
जो किर्नी

1

अमरो के जवाब के पूरक के लिए, आप fevalइसके बजाय उपयोग कर सकते हैं builtin। कोई फर्क नहीं है, वास्तव में, जब तक आप ऑपरेटर फ़ंक्शन को अधिभारित करने की कोशिश नहीं करते हैं:

BUILTIN (...) FEVAL (...) के समान है, सिवाय इसके कि यह फ़ंक्शन के मूल अंतर्निहित संस्करण को कॉल करेगा भले ही एक अधिभार एक मौजूद हो (इसके लिए काम करने के लिए, आपको BUILTIN को कभी भी अधिभार नहीं देना चाहिए)।

>> feval('_paren', magic(5), 3, 3)               % M(3,3)
ans =
    13

>> feval('_brace', num2cell(magic(5)), 3, 3)     % C{3,3}
ans =
    13

दिलचस्प बात यह है कि कम से कम मतलबी (~ 3.5%) की fevalतुलना में थोड़ा तेज लगता है builtin, कम से कम मतलाब 2013 बी में, जो अजीब है कि fevalयह जांचने की जरूरत है कि फ़ंक्शन ओवरलोडेड है, इसके विपरीत builtin:

>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.

यह वास्तव में अजीब नहीं है: MATLAB परिभाषित कार्यों की एक सूची रखता है, ऐसा करने के लिए बहुत खोज नहीं है। feval"सामान्य" बात करता है और इसलिए इस सूची का पूर्ण उपयोग कर सकता है।builtinकहीं और खोजना होगा ताकि यह केवल कार्यों में निर्मित हो। संभवतः इस मामले को लगभग "सामान्य" मामले के रूप में अनुकूलित नहीं किया गया है, क्योंकि आप बहुत बार उपयोग नहीं की जाने वाली चीज़ के अनुकूलन में पैसा क्यों लगाएंगे?
संकट लुएंगो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.