Julia: بناء الجملة الجديد للتبديل

تم إنشاؤها على ١٥ مارس ٢٠١٧  ·  103تعليقات  ·  مصدر: JuliaLang/julia

الآن بما أن .op هو بشكل عام الشكل المتجه لـ op ، فإنه من المربك جدًا أن .' يعني التحويل بدلاً من الشكل المتجه لـ ' (معاير ، ويعرف أيضًا باسم ctranspose ). هذه المسألة لمناقشة صيغ بديلة من أجل تبديل و / أو معاوضة.

linear algebra parser

التعليق الأكثر فائدة

تعارض بشدة جعل تبديل المصفوفة tr(A) يعني - الجميع سيعتقد أنه يعني تتبع المصفوفة: https://en.wikipedia.org/wiki/Trace_ (linear_algebra)

ال 103 كومينتر

حاول Andreas Aᵀ (وربما Aᴴ ) في # 19344 ، لكن لم يتم استقباله جيدًا. يمكننا بالمثل التورية على ^ مع أنواع الأس الخاصة T (وربما H ) بحيث يتم تبديل A^T ، لكن هذا أمر مظلل أيضًا. لست متأكدًا من وجود العديد من الخيارات الجيدة الأخرى التي لا تزال تبدو وكأنها تدوين رياضي.

أعتقد نوعًا ما أن t(A) قد يكون الأفضل ، لكن من المؤسف أن "تسرق" اسمًا آخر مكونًا من حرف واحد.

نقل تعليقي من الموضوع الآخر (ليس أنه يحل أي شيء ، ولكن ...):

+1 لاستخدام شيء آخر غير .' .

لم أتمكن من العثور على لغات ذات بناء جملة خاص للتبديل ، باستثناء APL التي تستخدم غير الواضح للغاية ، و Python التي تستخدم *X (وهو ما سيكون محيرًا لجوليا). تستخدم عدة لغات transpose(X) ؛ يستخدم R t(X) . هذا ليس جميلًا ، لكنه ليس أسوأ من .' . على الأقل أنت أقل ميلًا لاستخدام ' من خلال الخلط بينه وبين .' : سيكون من الواضح أن هذه عمليات مختلفة تمامًا.

انظر كود روزيتا . (راجع للشغل ، مثال جوليا يوضح في الواقع تبديل المترافق ...)

هل يمكن استخدام إحدى القراد الأخرى؟ ` أو "

-100 لتغيير الوضع الملائم ، نظرًا لأنه أحد الأشياء الرائعة التي تجعل كتابة كود جوليا واضحًا مثل كتابة الرياضيات ، بالإضافة إلى أن التحويل المترافق عادة ما يكون ما تريده على أي حال ، لذا فمن المنطقي أن يكون لديك صيغة مختصرة لها.

طالما أن لدينا بناء جملة لطيفًا من أجل التحويل المترافق ، فإن عامل postfix للتبديل المنتظم يبدو غير ضروري في الغالب ، لذا يبدو أن مجرد إجراء مكالمة دالة عادية أمر جيد بالنسبة لي. transpose يعمل بالفعل ؛ ألا يمكننا استخدام ذلك فقط؟ أجد أن t(x) R-ism مؤسف ، لأنه ليس واضحًا من الاسم ما يفترض أن يفعله بالفعل.

قد يكون استخدام علامة مختلفة أمرًا غريبًا ، على سبيل المثال ، يمكن أن يبدو A` مثل A' اعتمادًا على الخط ، و A" يبدو كثيرًا مثل A'' .

إذا أجرينا التغيير في # 20978 ، فسيصبح تبديل postfix أكثر فائدة مما هو عليه الآن. على سبيل المثال ، إذا كان لديك متجهان x و y وتريد تطبيق f زوجيًا عليهما ، فيمكنك القيام بذلك على سبيل المثال f.(x, y.') ... مع # 20978 ، سيكون هذا قابلاً للتطبيق على مصفوفات من الأنواع العشوائية.

بصراحة ، أعتقد أن أفضل خيار لدينا هو ترك الأمر كما هو. لا يبدو أن أيًا من الاقتراحات يمثل تحسنًا واضحًا بالنسبة لي. يتمتع .' بميزة الألفة من Matlab. يتطابق . إلى حد ما مع بناء جملة dot-call في أمثلة مثل f.(x, y.') ، ويقترح (بشكل صحيح إلى حد ما) أن "الصمامات" المنقولة (لا تنتج نسخة مؤقتة بفضل RowVector والتعميمات المستقبلية منها).

في الواقع ، يمكننا حتى أن نأخذ الأمر إلى أبعد من ذلك ، ونجعل f.(x, g.(y).') عملية دمج. على سبيل المثال ، قمنا بتغيير .' Transpose ليكون غير تكراري ala # 20978 وقمنا بتوسيع دلالاته لتشمل الاندماج مع استدعاءات النقاط المتداخلة الأخرى. (إذا كنت تريد الإصدار غير المندمج ، يمكنك الاتصال بـ transpose .)

تعجبني هذه الخطة كثيرًا ،stevengj.

تجعد واحد: من المفترض أن الماكرو @. لا يحول y' إلى y.' (لأن ذلك سيكون خطأ). ومع ذلك ، يمكن أن يحول y' إلى نوع من العمليات المساعدة المدمجة.

تكمن المشكلة الرئيسية في إيجاد طريقة نظيفة لجعل f.(x, g.(y).') يحتوي على دلالات مدمجة. أحد الاحتمالات هو تحويله إلى f.(x, g.(y.')) ومن ثم إلى broadcast(x,y -> f(x, g(y)), x, y.') ؟

لاحظ أنه لكي يعمل هذا بشكل صحيح ، قد نحتاج إلى استعادة طريقة transpose(x) = x الاحتياطية ، وفي هذه الحالة قد ندع التبديل يظل متكررًا.

أعتقد أن تحديد ما إذا كان يجب أن يكون التحويل تكراريًا أم لا هو أمر متعامد مع ما إذا كنا نجعله يشارك في اندماج بناء الجملة النقطي. لا يكون الدافع وراء اختيار جعلها غير تكرارية هو ذلك.

StefanKarpinski ، إذا استعدت القيمة الاحتياطية transpose(x) = x ، فسيختفي معظم الدافع لتغييره ليكون غير متكرر.

ما هي المشكلة إذا تمت استعادة النسخ الاحتياطي ولكن لا يزال لدينا المنقول غير متكرر؟

jebej ، يكون التحويل العودي أكثر صحة عند استخدامه كعملية رياضية على عوامل التشغيل الخطية. إذا كنت أتذكر بشكل صحيح ، فإن السبب الرئيسي لجعلها غير متكررة هو أننا لا نضطر إلى تحديد transpose(x) = x الاحتياطي ، بدلاً من إلقاء خطأ MethodError.

ولكن لن يكون الأمر مخيفًا أن يكون لديك هذا التراجع ولكن لا يزال غير متكرر.

اسمحوا لي أن أضيف تعليقين (لقد نظرت في المناقشة السابقة ولم ألاحظها - آسف إذا حذفت شيئًا ما):

  • وثائق لـ permutedims تقول هذا تعميم لمصفوفات متعددة الأبعاد. transpose ، وهو ليس كذلك.
  • كيف يُفترض أن يقوم المرء بمحوّل متجه x=["a", "b"] ؟ في الواقع يعمل y=x.' وينشئ متغيرًا جديدًا ولكن فشل getindex فيه. AFAIK يجب عليك استخدام reshape(x, 1, :) أو أبطأ بكثير hcat(x...) لتحقيق ذلك ولكن من غير الطبيعي أن يكون لديك بناء جملة مختلف لـ Vector ( permutedims لا يعمل هنا ).

ما هي حالة استخدامك لنقل متجه من السلاسل؟

ضع في اعتبارك السيناريو التالي على سبيل المثال:

x = ["$(j+i)" for j in 1:3, i in 1:5]
y = ["$i" for i in 5:9]

وأريد إلحاق y بعد الصف الأخير من x . وأبسط طريقة هي تحويل vcat a y .

يأتي في الممارسة العملية عند تسجيل البيانات النصية بشكل متزايد إلى Matrix{String} (يمكنني استخدام Vector{Vector{String}} ) ، ولكن غالبًا ما تكون المصفوفة أكثر فائدة (أو بعد ذلك هناك سؤال حول كيفية تحويل Vector{Vector{String}} إلى Matrix{String} بسلسلة العناصر المتتالية رأسياً).

حالة استخدام أخرى: النقل هو أبسط طريقة لجعل متجهين متعامدين مع بعضهما البعض من أجل بث دالة على المنتج الديكارتي ( f.(v, w.') ).

نقطة البيانات: بالأمس واجهت طرفًا مرتبكًا من عامل التشغيل "ملحق البث" لما بعد الإصلاح ولماذا يتصرف مثل تبديل. أفضل!

FWIW ، أشعر بقوة أننا يجب أن نتخلص من بناء الجملة .' . باعتباري شخصًا أكثر دراية بجوليا أكثر من ماتلاب ، فقد توقعت أن يعني ذلك متجهًا إضافيًا وتعثرت حقًا عندما لم يحدث ذلك. جوليا ليست Matlab ولا يجب أن تكون ملزمة باتفاقيات Matlab - إذا كانت النقطة في Julia تعني توجيه الدالة المجاورة ، فيجب أن يكون هذا متسقًا عبر اللغة ولا يجب أن يحتوي بشكل عشوائي على الاستثناء الرهيب الوحيد وهو .' غير مرتبط رسميًا بـ ' .

أعتقد أنه من الجيد أن يكون لديك transpose بدون أي تدوين "علامة" خاص ، نظرًا لأنه يتم استدعاءه في مصفوفة من الأرقام الحقيقية في الغالبية العظمى من الوقت ، لذا فإن ' سيكون مكافئًا إذا تريد حقًا حفظ الكتابة. إذا أردنا عمل نسخة مدمجة من تبديل الموضع ، فأنا لا أعتقد حقًا أن .' هو الصيغة الصحيحة.

هذه نقطة جيدة. يمكن القول فقط أن المساعد يحتاج إلى بناء جملة مضغوط للغاية.

دعنا فقط نسمي هذا transpose ونوقف العمل .' . في المستقبل ، يمكننا أن نفكر فيما إذا كنا نريد .' كمؤشر نقطي أو إذا كنا نريد فقط تركه متوقفًا عن العمل لتجنب محاصرة مستخدمي Matlab.

لاحظ أنني استحوذت للتو على الحزم المسجلة ووجدت أكثر من 600 استخدام .' ، لذا فهي ليست نادرة بشكل رهيب. ومع الاستدعاءات النقطية / broadcast (والتي بدأت في 0.6 فقط في التعامل الكامل مع البيانات غير الرقمية) ، من المحتمل أن تصبح الرغبة في تبديل المصفوفات غير الرقمية (حيث يكون المساعد أقل منطقية) أكثر شيوعًا ، لذلك تم تعزيز حجة بناء الجملة إلى حد ما.

ثم من الأفضل أن نتخلى .' في أقرب وقت ممكن ، قبل أن يعلق المزيد من الأكواد في نمط استخدام سيء.

لماذا هو سيء؟

المشكلة هي أن .' الآن لا يعني ما يبدو أنه يعني عامل التشغيل المنقط.

كما قلت أعلاه ، لأنه ينتهك النمط العام الذي يعني أن . يعني Vectorization ، ويبدو أنه يعني ناقل متجه (خاصة بالنسبة لشخص ليس على دراية بـ Matlab).

أعتقد أن stevengj يقدم نقطة جيدة - هذا مرتبط بالرغبة في تبديل بسيط غير تكراري.

أعلم أنه لم يكن يحظى بشعبية ، لكنني بدأت في تفضيل Andreas '# 19344 مقابل . في هذه المرحلة ، أفضل إهمال استخدام _ all_ النصوص المرتفعة كمعرفات ، وتفسير _ أي _ النصوص المرتفعة باعتبارها عوامل postfix. يعطي هذا أيضًا مسارًا لحل بعض الخلافات حول literal_pow باستخدام الأرقام المرتفعة. نعم ، سيكون من المحزن خسارة χ² مثل الأسماء المتغيرة ، لكنني أعتقد أن الفوائد ستفوق السلبيات.

في هذه المرحلة ، أفضل إهمال استخدام _ all_ النصوص المرتفعة كمعرفات ، وتفسير _ أي _ النصوص المرتفعة باعتبارها عوامل postfix.

RIP الكود الخاص بي
screenshot from 2017-11-09 22-08-25

في هذه المرحلة ، أفضل إهمال استخدام جميع النصوص المرتفعة كمعرفات

لا أعتقد حقًا أن هذا سيكون ضروريًا ، عندما نريد فقط T وربما بضعة أشياء أخرى في المستقبل.

اتساق أحمق ...

نعم ، من غير المتسق استخدام .' للتبديل ، ولكن يبدو أن جميع البدائل المقترحة حتى الآن أسوأ. ليس من الأسوأ في العالم أن تقول " .' هو تبديل ، استثناء للقاعدة المعتادة حول عوامل تشغيل النقاط." تتعلم هذا وتنتقل.

هناك شيء واحد يجب ملاحظته والذي قد يساعد في أي ارتباك محتمل أكثر من .' ليس بثًا نقطيًا وهو أنه عامل postfix ، في حين أن بث البادئة هو op. و infix هو .op . لذلك يمكننا القول أن . لا يعني البث عندما يكون postfix. الاستخدام الآخر لـ postfix . هو البحث الميداني ، و getfield(x, ') لا معنى له ، لذلك فهو يختلف عن المعاني الأخرى.

(ومع ذلك ، فإنني أفضل transpose(x) على الاحتفاظ بـ .' .)

stevengj أراهن على أنه يمكن استبدال العديد (ربما معظم) استخدامات أكثر من 600 .' في الحزم المسجلة التي ذكرتها أعلاه بـ ' دون أي تكلفة للقراءة ، والكود ستواصل العمل.

ربما لا يكون شائعًا ، ولكن لا يزال من الممكن أن يكون هناك postfix " و ` ؟

يستخدم ل .' في الحزم المسجلة التي ذكرتها أعلاه ، يمكن استبدالها بـ "دون أي تكلفة للقراءة ، وسيستمر الرمز في العمل.

لاحظ أنه بمجرد وصول # 23424 إلى الأرض ، سنكون قادرين على استخدام transpose على مصفوفات من السلاسل وما إلى ذلك ، ولكن ليس adjoint . من المرجح أن تصبح أفضل ممارسة لاستخدام الجبر الخطي x.' شيئًا مثل conj(x') (نأمل أن يكون هذا كسولًا ، أي مجاني). على الرغم من أنني أحب استخدام .' لاكتنازه ، فربما يؤدي التخلص منه إلى إجبار مستخدمي الجبر الخطي على استخدام الشيء الصحيح ومصفوفات البيانات على مستخدمي مصفوفات البيانات المكتوبة transpose .

لا يزال من الممكن أن يكون هناك postfix "و"؟

يبدو بناء الجملة الجديد لـ transpose() سابقًا لأوانه. IMHO سيكون من الأفضل إهمال .' ليتم استبداله كما تقترح بـ conj(x') و transpose كما هو مطلوب.

لدي شعور بأن .' مفيد جدًا في matlab ويرجع ذلك أساسًا إلى إصرار matlab على أن "كل شيء عبارة عن مصفوفة" جنبًا إلى جنب مع عدم وجود قواعد التقطيع المتماسكة بحيث تحتاج غالبًا إلى إدخال عمليات نقل عشوائية في أماكن مختلفة الحصول على الأشياء للعمل.

لتلخيص الحجج هنا:

  1. .' هو الآن الصدارة الوحيدة كعامل منقط لا يعني "تطبيق عامل غير محدد بعنصر"؛ المستخدمين الجدد غير القادمين من Matlab يجدون أن هذا فخ مفاجئ.

  2. أصبح .' الآن غامضًا بشكل فعال: هل تقصد transpose أم أنك تقصد conj(x') ؟ من حيث المبدأ ، يجب فحص كل استخدام قديم لـ .' لتحديد ما إذا كان يغير مؤشرات مصفوفة ثنائية الأبعاد أو ما إذا كان يقوم "بعمل مساعد غير مقترن".

القضية الأولى إشكالية ولكنها ليست قاتلة في حد ذاتها ؛ المسألة الثانية هي المشكلة السيئة حقًا - لم تعد هذه عملية واحدة متماسكة ، بل سيتم تقسيمها إلى معنيين منفصلين.

لقد لاحظت للتو أنه إذا قمنا بتغيير .' ليعني "العنصر المقابل" ، فإن conj(x') سيعادل تقريبًا x'.' و conj(x)' x.'' وهو قريب جدًا من x.' 😬.

ربما لا يكون شائعًا ، ولكن لا يزال من الممكن أن يكون هناك postfix "و"؟

انسخ لصق الشفرة في Slack ورؤية أن إبراز بناء الجملة المدمر سيكون ...

تعد القدرة على نقل أي شيء أمرًا رائعًا لأنه يجعل من السهل "عبور المنتج" عبر آلية الإرسال وحالات استخدام موجزة أخرى من هذا القبيل. المشكلة مع عدم وجود احتياطي سهل لهذا النوع من الأشياء هو أن الاختراق الذي سنراه دائمًا هو تحديد transpose(x) = x احتياطيًا (أو على الأنواع الأساسية ، لذا اكتب القرصنة في الحزم) للقيام بذلك نوع من العمل يعمل بسهولة. هذا يجعلني أفكر: لماذا لا يكون Complex هو الشخص الغريب؟ إن معظم الأرقام المجاورة هي نفسها ، لذا فإن المعقد المقابل هو الذي يتخصص فيه: ألا يمكن أن يمتد إلى ما وراء الأرقام؟

أرى شيئين مرتبطين للغاية هنا:

1) x' لا يعمل مع الأنواع غير الرقمية ، لذلك نريد طريقة للقيام بذلك بسهولة للبيانات الأخرى
2) transpose(x) ليس بهذه البساطة x.' . هذا في الغالب لحالات (1) ، لأن حالات الاستخدام لنقل المصفوفات المعقدة نادرة للغاية.

ولكن بدلاً من الانحدار (2) ، لماذا لا تحاول إجراء إصلاح معقول لـ (1)؟

ربما يكون الإصلاح المعقول مجرد ماكرو يجعل تحويل ' يعني تبديلًا بدلاً من الوضع المساعد؟

ولكن بدلاً من الانحدار (2) ، لماذا لا تحاول إجراء إصلاح معقول لـ (1)؟

لقد مررنا بالفعل بهذا المسار والعديد من الأشياء المجاورة له. كان هناك قدر كبير من المناقشات الناتجة والتي ربما يمكن لشخص آخر أن يستخلصها ، لكن باختصار ، لم ينجح الأمر بشكل جيد. بشكل أساسي ، العملية الحسابية adjoint غير منطقية على الأشياء التي ليست أرقامًا. استخدام ' على غير الأرقام لمجرد أنك تحب الصياغة المقتضبة يعد أمرًا سيئًا - إنه أسوأ نوع من تأديب المشغلين ولا ينبغي أن يكون مفاجئًا أن تنشأ أشياء سيئة من هذا النوع من إساءة استخدام المعنى. يجب تحديد الوظيفة adjoint فقط للأشياء التي من المنطقي أخذ الملحق منها و ' يجب أن تستخدم فقط لتعني ذلك.

تذكر أن .' كما هو مستخدم حاليًا عبارة عن عمليتين مختلفتين في الأساس: تحويل المصفوفة والمعاشرة غير المقترنة. تسلط مشكلة التحويل العودية الضوء على حقيقة أن هذه عمليات مختلفة وأننا بالتالي بحاجة إلى طرق مختلفة للتعبير عنها. يبدو أن أصحاب الرياضيات مصرين على أن العملية المساعدة غير المقترنة هي (أ) مهمة ، و (ب) تختلف عن المقايضة البسيطة للأبعاد. على وجه الخصوص ، لكي يكون الأمر صحيحًا ، يجب أن يكون المساعد غير المترافق متكررًا. من ناحية أخرى ، يجب ألا يكون تبديل أبعاد المصفوفة العامة تعاوديًا بشكل واضح. لذلك يجب كتابة هذه العمليات بشكل مختلف ، ويجب توضيح الاستخدامات الحالية لـ .' على أنها تحمل معنى أو ذاك. إهمال .' طريقة لفرض ذلك.

أخيرًا ، بينما أشعر بقوة أن permutedims(x, (2, 1)) هو بالتأكيد غير مريح للغاية لمبادلة أبعاد مصفوفة ثنائية الأبعاد ، أجد الحجة القائلة بأن transpose(x) غير مريح للغاية وغير مقنع. هل هذه العملية شائعة لدرجة أن وجود اسم دالة بسيط وواضح يعد كثيرًا جدًا؟ حقا؟ هل تبديل أبعاد المصفوفة أكثر شيوعًا أو أهمية من كل الأشياء الأخرى في اللغة التي نستخدم فيها أسماء الوظائف وبناء جملة استدعاء الوظيفة؟ تدوين رب الأسرة يجعل adjoint مميزًا تمامًا لأننا نريد كتابة أشياء مثل v'v و v*v' و v'A*v . هذا هو السبب في أن adjoint يحصل على صيغة لطيفة حقًا. لكن مقايضة أبعاد المصفوفة؟ انها لا تضمن المشغل في رأيي.

ليست حجة قوية ، لكنني غالبًا ما أستخدم عامل التشغيل ' لطباعة مصفوفات أكثر ضغطًا (عند استخدامها كحاويات بسيطة) ، على سبيل المثال عندما أرغب في رؤية محتوى بعض المتجهات في نفس الوقت على شاشتي ( ودائمًا ما يصاب بالإحباط عندما يفشل لأنه لا يمكن تغيير موضع العناصر). لذا فإن بناء جملة قصير لـ REPL مفيد بالتأكيد. (أيضًا ، هذا يسهل على الأشخاص المعتادين على المصفوفات الرئيسية الصفوف ، الحصول على طريقة بسيطة "لتبديل الترتيب" ، لا سيما عند نقل الخوارزميات إلى جوليا باستخدام المصفوفات ثنائية الأبعاد ؛ ولكن بالتأكيد ليست حجة قوية أيضًا). فقط للقول إنها صيغة مقتضبة لطيفة وليست مفيدة فقط للجبر الخطي.

لقد علّقت على بعض أفكار بناء الجملة على https://github.com/JuliaLang/julia/pull/19344#issuecomment -261621763 ، كان في الأساس:

julia> const ᵀ, ᴴ = transpose, ctranspose;

julia> for op in (ᵀ, ᴴ)
           <strong i="7">@eval</strong> Base.:*(x::AbstractArray{T}, f::typeof($op)) where {T<:Number} = f(x)
       end

julia> A = rand(2, 2)
2×2 Array{Float64,2}:
 0.919332  0.651938
 0.387085  0.16784

julia>  Aᵀ = (A)ᵀ    # variable definition and function application are both available!
2×2 Array{Float64,2}:
 0.919332  0.387085
 0.651938  0.16784

julia> Aᴴ = (A)ᴴ
2×2 Array{Float64,2}:
 0.919332  0.387085
 0.651938  0.16784

ولكن بدون الاختراق بالطبع ، مجرد فكرة أنه يمكن أن يكون هناك "تطبيق وظيفة postfix" من نوع ما وأنه يتطلب الأقواس (x)f ، يمكن أن تكون الإصدارات المنقطة مثل هذا (x).f ( xf سيكون f رمزًا مرتفعًا).

هذا المثال الاختراق كان يعمل على 0.6 لكن الآن:

julia> Aᵀ = (A)ᵀ               
ERROR: syntax: invalid operator

julia> Aᵀ = (A)transpose       
2×2 Array{Float64,2}:          
 0.995848  0.549117            
 0.69401   0.908227            

julia> Aᴴ = (A)ᴴ               
ERROR: syntax: invalid operator

julia> Aᴴ = (A)ctranspose      # or adjoint or whatever
2×2 Array{Float64,2}:          
 0.995848  0.549117            
 0.69401   0.908227            

وهو أمر محزن ، لقد أردت في الأصل فعل ذلك من أجل القوى:

julia> square(n) = n^2; cube(n) = n^3;

julia> Base.:*(n, f::typeof(square)) = f(n)

julia> Base.:*(n, f::typeof(cube)) = f(n)

julia> const ² = square    # why?
syntax: invalid character "²"

julia> const ³ = cube    # why?
syntax: invalid character "³"

الذي اعتقدت بسذاجة أنه سيمكن بناء الجملة مثل: n² = (n)² و n³ = (n)³ لكن أي معرّف رقمي نوعاً ما محظور من أن يكون في الموضع الأول ، ولكن (A)⁻¹ يعمل أيضًا ، حيث ⁻¹ كان const ⁻¹ = inv .

لقد قمت بتنفيذ اختراق مماثل لـ InfixFunctions.jl .

بصفتي مستخدمًا ، يمكنني فقط تقديم حزمة PostfixFunctions.jl ، وأكون سعيدًا بكل ما تجده أفضل هنا. لكن في الوقت الحالي قيود بناء الجملة هذه:

  • لا يُسمح باستخدام المؤشرات الرقمية في بداية المعرف
  • superindex x * ᶠ في postfix (الضرب الضمني في الاختراق) (x)ᶠ غير مسموح به

يبدو كثيرًا بالنسبة لي IMHO ، أود على الأقل أن أكون قادرًا على تحديد المعرفات التي يمكن أن تبدأ بالأحرف الرقمية المرتفعة ، أو بشكل عام ، فقط عدم السماح إلا بالأحرف الرقمية الفعلية من 0 إلى 9 مع دلالات الأرقام ، في بداية المعرف ، سيكون ذلك رائعًا. 😄

هتافات!

راجع # 10762 للحصول على بعض المناقشات حول أحرف الأرقام الأخرى كمعرفات.

المشكلة الأخرى تتعلق # 22089 ، لاحقات عامل التشغيل. +ᵀ الآن عامل صالح ، والذي (ربما عن طريق الخطأ) معرفات غير مسموح بها تتكون فقط من دمج الأحرف في السياقات التي يتوقع فيها عامل التشغيل. هذا يبدو وكأنه حشرة بالنسبة لي. من الغريب أيضًا أن يكون معرفًا صالحًا ولكن -ᵀ لا يفعل -(ᵀ) . ومع ذلك ، فهذه ليست نهاية العالم ، وإصلاح IMO لن يستحق خسارة الاستخدامات المحتملة الأخرى لـ .

لاحظ أن استخدام .' كعامل تحويل postfix ليس مطروحًا حتى على الجدول هنا (على الرغم مما يقوله موضوع المشكلة) ، الاعتبار هو في الواقع ما إذا كان يجب علينا الاحتفاظ بـ .' كمعامل postfix من أجل المساعد غير المترافق ، والذي سيكون تكراريًا. يحدث هذا غالبًا مثل التحويل ، ولكنه لا يكون نفس العملية بشكل عام. إذا كان الناس في الجبر الخطي على استعداد للسماح .' يعني تغيير المصفوفة العامة ، فهذه قصة مختلفة ، لكن انطباعي غير مقبول.

@ Ismael-VC ، يمكنني أن أرى السماح ب (x)ᵀ كصيغة دالة postfix للنصوص المرتفعة - بماذا يعني ذلك أيضًا؟ أعتقد أن المكان الذي يبدأ فيه اقتراحك في توجيه الناس بطريقة خاطئة هو السماح بتطبيق أي معرّف كوظيفة في صيغة ما بعد الإصلاح. أود أن أقصرها على الحروف العالية.

StefanKarpinski ، اعتقدت أن الإجماع كان على وجه التحديد للسماح لـ .' يعني تحويل المصفوفة غير المتكرر وغير المترافق (إذا كان لدينا هذا العامل على الإطلاق) ، بينما ' هو المتقارن المتكرر عملية معاونة.

أكره حقًا فكرة استخدام لمشغل تحويل postfix. من المفيد جدًا أن يكون لديك نص مرتفع في أسماء المتغيرات ، مثل aᵀa أو LᵀDL = ltdlfact(A) . (إلى جانب حقيقة أن استخدام فقط لمشغل بينما تكون الأحرف الفوقية الأخرى صالحة في المعرفات سيكون أمرًا غريبًا.)

لم يكن هذا ما أفهمه على الإطلاق - اعتقدت أن الأشخاص الذين يستخدمون Linalg كانوا يؤيدون الاحتفاظ بـ a.' كما هو ، أي بمعنى conj(a)' . الحفاظ .' مع تغيير معناه إلى تبديل مصفوفة مختلف تمامًا - لست متأكدًا من شعوري حيال ذلك. أوافق على أن وجود فقط كمشغل لما بعد الإصلاح سيكون أمرًا مزعجًا وغير متسق. أفضل عرض @ Ismael-VC's (a)ᵀ ، ومع ذلك ، والذي لن يمنع استخدام aᵀ كاسم.

ذكرياتي من تلك المناقشات تشبه ستيفن. إن التحويل التكراري غير المقترن نادر وغريب بشكل عام. ملخص لائق هنا: https://github.com/JuliaLang/julia/issues/20978#issuecomment -316141984.

أعتقد أننا نتفق جميعًا على أن postfix ' هو أمر ثانوي ويجب أن يبقى.
أعتقد أننا نتفق جميعًا على أن postfix .' هو بناء جملة دون المستوى الأمثل.
أعتقد أن معظمهم يتفقون على أن النقل غير التكراري (الهيكلي) أكثر فائدة من النقل العودي.

حسنًا ، يبدو أن النقاط التي يتفق عليها الجميع:

  1. استخدم a' مقابل adjoint(a)
  2. استخدم conj(a)' أو conj(a') للمقارن (غير).

لذا فإن نقطة الخلاف الوحيدة هي كيفية كتابة تبديل المصفوفة:

  • كـ a.' أو
  • كـ transpose(a) أو
  • كـ (a)ᵀ .

هل هذا التقييم صحيح؟

نعم ، أعتقد ذلك (حيث يكون "تبديل المصفوفة" غير تكراري).

أيضًا ، كما أفهمها ، يتفق الجميع على أن transpose(a) يجب أن يكون بالتأكيد بناء جملة صالحًا (وغير متكرر) ، ونقاط الخلاف الوحيدة هي ما إذا كان .' و / أو (a)ᵀ يجب أن يكون

النهج (1) من https://github.com/JuliaLang/julia/issues/20978#issuecomment -315902532 ، والذي حصل على قدر كبير من الدعم (على سبيل المثال https://github.com/JuliaLang/julia/issues/20978# issuecomment-316080448) ، يبقى احتمالًا. لدي فرع يدرك هذا النهج (تقديم flip(A) ) الذي يمكنني نشره.

لما يستحق ، أؤيد إهمال .' . الارتباك والغموض في هذا الخيط حجة قوية للقيام بذلك في حد ذاته. أفضل!

أعتقد أنه طالما لدينا postfix ' ، فإن الناس سيرغبون في استخدامه لبث f عبر منتج ديكارتي من المتجهات f.(v, w') . وسيرغب الناس في استخدامه لإعادة تشكيل متجه من السلاسل إلى متجه صف من الرؤوس لبنية تشبه الجدول. لذلك من الضروري أن يكون لدي بديل بسيط وسهل الاستخدام يمكننا توجيههم إليه.

إليك خيار لم نفكر فيه: A*' - رسم بيغراف جديد. قد يفسر تدوين الرياضيات النموذجي هذا على أنه conj(A)' ، وهو في الواقع قريب جدًا مما نريد. كان متاحًا في 0.6 ، ولكن في 0.7 نسمح باستخدام * لسلسلة الأحرف ... لا تزال قابلة للتطبيق ، على الرغم من ذلك.

لا أعتقد أن postfix " و ` متاحان بسبب تحليل القيم الحرفية للسلسلة المخصصة بعد نهاية السطر. Postfix * في حد ذاته غير متاح أيضًا لنفس السبب. من المحتمل أن يكون Postfix Prime A′ أحد أكثر معرّفات يونيكود شيوعًا ، لذا فهو أكثر من Aᵀ .

بصراحة ، بعد النظر إلى الكود الخاص بي ، لا أستخدم .' مثل على الإطلاق ، لذلك من المحتمل أن يكون transpose(a) جيدًا.

لاحظ أنني استوعبت للتو الحزم المسجلة ووجدت أكثر من 600 استخدام لـ. '، لذا فهي ليست نادرة بشكل رهيب.

هل تم فحص هذه البقعة على الإطلاق لمعرفة ما إذا لم يتم استخدام .' حيث كان ' سيكون بخير؟ بدأت أعتقد أن هذا قد يكون صحيحًا في كثير من الأحيان. خلاف ذلك ، المكان الوحيد الذي رأيت فيه استخدامًا شرعيًا لـ .' كان قبل أن تسمح تسميات Plots.jl بالمتجه (بدلاً من ذلك أراد متجهًا لصف السلاسل) ، لكن هذا تم تغييره. بالنسبة للرموز التي أحتاج إليها كثيرًا ، أعتقد أنني سأبدأ في عمل T = transpose محليًا ، أو طرح ماكرو لتغيير ' إلى transpose .

<strong i="17">@transpose</strong> A = A'*A*B'*B*C'*C

سيكون على ما يرام معي في هذه الحالة النادرة.

سيرغب الناس في استخدامه لبث f على منتج ديكارتي من المتجهات مع f. (v ، w '). وسيرغب الناس في استخدامه لإعادة تشكيل متجه من السلاسل إلى متجه صف من الرؤوس لبنية تشبه الجدول. لذلك من الضروري أن يكون لدي بديل بسيط وسهل الاستخدام يمكننا توجيههم إليه.

إذا ظهر مرة واحدة فقط في البيان ، فهل من المقبول استخدام transpose فقط؟

بناء الجملة a*' للمقارن المساعد جميل جدًا ، على الرغم من أنه لا يبدو حقًا أن هذه هي العملية التي نحتاج إلى بناء جملة أفضل لها. سيتوفر &a قريبًا ويقترح تبديل الأشياء ، على الرغم من اختلافها تمامًا عن الرموز التقليدية لهذا الغرض.

ربما حان الوقت لاقتراع قش؟

كيف يجب أن نتهجى التحويل الهيكلي؟

(بترتيب العرض تقريبًا ؛ لا توجد أحكام بشأن أسماء الرموز التعبيرية هنا)

  • 👍: A.' - فقط غيّر المعنى ، وحافظ على بناء الجملة كما هو
  • 👎: transpose(A) - لا توجد صيغة خاصة
  • 😄: t(A) أو tr(A) - لا توجد صيغة خاصة ، ولكن قم بتصدير اسم أقصر
  • 🎉: Aᵀ - بـ فقط وربما واحد أو اثنين من الأحرف الفوقية الخاصة بغلاف خاص من المعرفات
  • 😕: (A)ᵀ - مع فصل جميع النصوص المرتفعة عن المعرفات التي تتصرف مثل معاملات postfix
  • ❤️: A*' - اللمعان مباشرة فوق هذا الوادي الخارق ، فهذا يعني تغيير هيكلي
  • إذا كنت تفضل &A ، فقم برمي 🎉 على منشور Stefan مباشرة أعلاه (نحن خارج الرموز التعبيرية)

لقد تحدثت مناقشات LinAlg بالفعل عن إهداء .’ لاستخدام التحويل غير التكراري ، نظرًا لأن conj(x’) غير شائع نسبيًا. ومع ذلك ، فإن هو بناء جملة رياضي ويجب أن يأخذ المعنى الرياضي (إن وجد).

تعارض بشدة جعل تبديل المصفوفة tr(A) يعني - الجميع سيعتقد أنه يعني تتبع المصفوفة: https://en.wikipedia.org/wiki/Trace_ (linear_algebra)

إذا لم يتم إهمال النصوص المرتفعة كمعرف (والذي من المحتمل أن يتم النظر فيه بجدية قبل الإصدار 1.0) ، فإن ᵀ(A) هو احتمال أيضًا.

فيما يتعلق بالاقتراح (A)ᵀ ، أعتذر عن عرقلة هذه المناقشة قليلاً مع الملاحظة التالية:

لم أهتم أبدًا بامتلاك متاحًا كمشغل أحادي ، خاصة وأنك ستنتهي على أي حال بكتابة √(...) بمجرد أن تريد تطبيقه على متغير أكثر من حرف أو عدة أحرف. علاوة على ذلك ، فقد وجدت دائمًا الفرق في الأداء بين و √a اصطناعيًا جدًا. ربما يكون من المنطقي أن تعرف عن فئات Unicode وما إلى ذلك ، ولكن بالنسبة لأي شخص آخر ، يجب أن يبدو هذا سخيفًا. من المؤكد أنه من المفيد أن يكون لديك كاسم متغير صالح ، ولكن بالمثل √a يمكن أن يكون اسمًا متغيرًا مفيدًا لتخزين الجذر التربيعي لـ a إذا كنت بحاجة إلى استخدامه عدة مرات مرات. أو تعبيرات أكثر تعقيدًا مثل a²b وجذرها التربيعي a√b ، حيث يكون الأول معرفًا صالحًا والأخير ليس كذلك. قبل كل شيء ، أنا أحب الاتساق.

لذلك ، من أجل الاتساق ، أحب اقتراح وجود عوامل تشغيل postfix عند استخدام الأقواس (A)ᵀ ، (a)² ، بالاقتران مع إزالة مشغل Unicode الأحادي (والأقارب) بحيث يمكن استخدامه أيضًا في المعرفات (بينما لا يزال متاحًا مثل استدعاء الوظيفة العادية √(a) ).

أتفق بنسبة 100٪ مع ما قاله Jutho وفكرت فيه في عدد من المناسبات. هل تمانع في فتح قضية ،Jutho؟ الاقتراح: السماح بـ في أسماء المعرفات ، يتطلب √(x) للاتصال كـ op.

السؤال التالي -> ماذا عن 2 |> √ ؟

دعونا نناقش في موضوع آخر ، ولكن باختصار 2 |> √ يعني √(2) .

البديل الآخر ، الذي لا يتطلب تغييرات في المحلل اللغوي ويكون من السهل كتابته ، سيكون A^T للتبديل (من خلال تحديد T ليكون نوعًا منفردًا بطريقة ^ ). ... أوه ، أرى أن mbauman لديه هذه الفكرة أيضًا. إنه قبيح بعض الشيء ، لكن ليس أكثر من A.' .

ليس لدي خبرة ، لكنني مستثمر جدًا في نتيجة هذه المناقشة حيث من المحتمل أن يكتب آلاف الأسطر التي تحتوي على تعبيرات المصفوفة في سياق عملي.

transpose(A) # with no special syntax هو الفائز في التصويت أعلاه ، ولكنه مؤلم لعيني وأصابع.

في Python ، من المحتمل أن يكون الاستخدام الشائع مع numpy والعديد من الأشياء التي تشبه ما يلي وليست سيئة للغاية:

import numpy as np
# define matrix X of n columns, with m rows of observations
error = X.dot(Theta.T) - Y
gradient = (1 / m) * (X.dot(Theta.T) - Y).T.dot(X)

لا أريد أن أفعل:

grad = 1/m * transpose(X * transpose(Theta) - Y)) * X

إنه يغير تمامًا المفهوم العقلي للمحول من الاصطلاح الذي استقر عليه تدوين الرياضيات ، وهو دلالة postfix ، عادةً Aᵀ أو Aᵗ .

أنا شخصياً سعيد للغاية بـ A' الذي يعمل في Julia v.0.6 ، قبل أن يتم التقاطه بواسطة المساعد. هل يتم استخدام المساعد في كثير من الأحيان؟

ها هي تعليقاتي في جدول:

Aᵀ or Aᵗ    if the world won't accept unicode operators, let them use transpose(A)
A'          close to math notation, easy to type and *especially* easy to read
A^'         this could signal `^` not to be parsed as Exponentiation.
A.'         conflicts with dotted operator syntax, but at face value OK
A^T or A^t  these are pretty good, but what if variable `T` is meant to be an exponent? 
A.T         same as numpy, same dotted operator collision
t(A)        nesting reverses semantics, 3 keystrokes and two of them with shift key.
transpose(A) with no special syntax     # please don't do this.

أنا شخصياً سعيد للغاية بـ A' الذي يعمل في Julia v.0.6 ، قبل أن يتم التقاطه بواسطة المساعد. هل يتم استخدام المساعد في كثير من الأحيان؟

لا أفهم ، كان A' دائمًا المساعد لـ A . اعتدنا على استدعاء الدالة الأساسية ctranspose للتبديل المترافق ، لكننا أعدنا تسميتها إلى المصطلح المكافئ adjoint بدون أي تغيير في الوظيفة.

إذا كنت تقوم بالجبر الخطي ، فمن الأرجح أنك تريد تبديل موحد على أي حال ، لذلك ستكتب A' بدلاً من transpose(A) . إن شعبية عدم تحديد بناء جملة خاص لعمليات النقل غير المقترنة ترجع جزئيًا (على الأرجح) إلى حقيقة أنه ليس من الشائع حقًا بالنسبة لمعظم الاستخدامات الجبرية الخطية أن ترغب في تبديل غير مترافق.

إذا كنت تقوم بالجبر الخطي إذن ...

إذا كانت أداتك مطرقة ثم ... :)

... عليك التفكير في إمكانية أن تتطور جوليا إلى لغة برمجة عامة.

ربما لا ، ربما سيبقى مجادل الجبر الخطي - وهو الاحتمال الذي يجب أن يفكر فيه المبرمجون مثلي. :)

mahiki ، أنت مثال على NumPy:

import numpy as np
# define matrix X of n columns, with m rows of observations
error = X.dot(Theta.T) - Y
gradient = (1 / m) * (X.dot(Theta.T) - Y).T.dot(X)

ستكتب حرفيا في جوليا على النحو التالي:

error = X*Θ' - Y
gradient = (1/m) * (X*Θ' - Y)' * X

أو بافتراض أن المتجهات عبارة عن صفوف في مثال NumPy وستكون أعمدة في Julia:

error = X'Θ - Y
gradient = (1/m) * (X'Θ - Y) * X'

الذي يبدو واضحًا ورياضيًا كما يحصل. إذا كانت بياناتك حقيقية ، فإن عملية الضبط والتبديل هي نفس العملية ، وقد يكون هذا هو سبب استخدامك للتبديل أعلاه - ولكن الربط رياضيًا هو العملية الصحيحة. كما قال ararslan ، فإن X' يعني دائمًا adjoint في جوليا (وفي Matlab أيضًا). كان يطلق عليه سابقًا ctranspose اختصارًا لـ " التحويل المترافق " ولكن هذا الاسم كان تسمية خاطئة نظرًا لأن الخاصية التعريفية للمشغل هي

dot(A*x, y) == dot(x, A'y)

وهي الخاصية المحددة للمقارب Hermitian ولكن يحدث أن يتم استيفائها من خلال منقول المرافق عندما يكون A مصفوفة معقدة. هذا هو السبب في أن "معايرة" هي المصطلح العام الصحيح لهذا العامل.

بعد كل ما قيل ، لقد قمت بالتصويت أعلاه لكل من transpose(a) و a.' لأنني أعتقد أنه سيكون من الجيد أن a.' يعني النقل الهيكلي. سيعمل كما هو متوقع ، وعلى الرغم من أنه لن يكون تكراريًا وبالتالي ليس "صحيحًا رياضيًا" في بعض التعليمات البرمجية العامة ، فإن جعله يعمل كما هو متوقع يبدو جيدًا بدرجة كافية. وإخبار الناس بالتفكير في استخدام conj(a') في رمز عام يبدو وكأنه شيء تعليمي وليس شيئًا نحتاجه حقًا لضرب الأشخاص فوق رؤوسهم.

mahiki إذا كنت بحاجة فعلاً لسبب ما إلى استخدام transpose بدلاً من adjoint عدة مرات في التعليمات البرمجية الخاصة بك ، فيمكنك تحديد ماكرو أقصر مثل @t تلك الأسماء المستعارة transpose (على الرغم من أنني أعلم أن هذا الحل ليس مثاليًا ، خاصة إذا كنت تكتب الكود الخاص بك مع أشخاص آخرين).

عليك التفكير في إمكانية أن تتطور جوليا إلى لغة برمجة عامة.

@ Liso77 هو بالفعل. كواحد فقط من العديد من الأمثلة ، يدير Nanosoldier خادم ويب يستمع إلى أحداث GitHub ويدير معايير الأداء عند الطلب ، كل ذلك في Julia. هذا استطرادي على الرغم من ذلك ، ولا أريد أن يخرج هذا الموضوع عن الموضوع.

إذا كنت تقوم بنقل مصفوفة من نوع ما باستخدام بيانات غير رقمية - وهي حالة استخدام صالحة تمامًا - فإن تدوين النقل الرياضي يبدو في الواقع وكأنه تورية سيئة. في هذه الحالة ، أشعر أنه سيكون من الأفضل أن تكون أكثر وضوحًا بشأن ما تطلبه ، على سبيل المثال transpose (أو حتى permutedims ، حسب احتياجاتك الخاصة).

إذا كنت تقوم بنقل مصفوفة من نوع ما باستخدام بيانات غير رقمية - وهي حالة استخدام صالحة تمامًا - فإن تدوين النقل الرياضي يبدو في الواقع وكأنه تورية سيئة.

نظرًا لأن A.' ليس حقًا "ترميزًا رياضيًا" بالمعنى المعتاد ، لا أرى أن هذه حجة مع أو ضد.

أعتقد أن ararslan لا يجادل ضد .' الموجود ولكن بدلاً من ذلك ضد إدخال بناء جملة superscript-T. أميل إلى الموافقة - إذا كنت تقصد مفهوم الجبر الخطي للوضع المساعد ، فيجب عليك استخدام ' (حتى لو كانت مصفوفتك حقيقية). وإذا كان لديك مصفوفة من البيانات غير الرقمية ، فمن الشرعي تمامًا بالطبع تبديل المؤشرين ، لكن هذه العملية ليست في الحقيقة "تبديل" كما نفكر فيها عادةً ، واستخدام تدوين رياضي مرتفع - T هو من المحتمل أن يكون للارتباك أكثر من التوضيح. الموقف الوحيد الذي يكون فيه الترميز المرتفع- T مناسبًا حقًا هو إذا كان لديك مصفوفة عددية تريد تبديل مؤشراتها ، لكنك حقًا لا تريد عامل التشغيل الخطي المساعد. توجد مثل هذه المواقف بالتأكيد ، لكنها قد تكون نادرة جدًا بحيث لا تبرر إدخال صياغة جديدة.

... لكن هذه العملية ليست حقًا "تبديل" كما نفكر بها عادة ، ...

إذا كان هذا غير معتاد ، فلماذا يصوت ararslan والعديد من الآخرين لصالح تبديل الهجاء الهجائي كـ transpose(A) ؟

شكرا @ StefanKarpinskiararslanttparker . كان عليّ أن أعود إلى نص الجبر الخطي وأعيد اكتشاف المساعد ، إنه هناك على ما يرام. أخذت ذلك قبل التحليل المركب ، ربما لماذا لم ألاحظه.

أحب أن أكون قادرًا على القيام بذلك
gradient = (1/m) * (X'Θ - Y) * X'

ينبع ارتباكي من الاستخدام الواسع لـ "تبديل" (كحرف T مرتفع) في المستندات المرجعية ، والأوراق ، والكتب المدرسية ، وما إلى ذلك ، على سبيل المثال ملاحظات محاضرة Andrew Ng's stanford CS229 ، حيث يستخدم رمز Julia المقابل adjoint مثل في مثالStefanKarpinski النظيف المظهر أعلاه. هذا لأن التقريب والتبديل متكافئان في ℝ (أليس كذلك؟) . تحديث: نعم

الآن تدويني المفضل للتبديل هو ببساطة كل ما هو متسق منطقيًا. من الواضح أن .' ليس بسبب التعارض مع بناء جملة عامل منقط ، وليس لدي أي اعتراض على transpose(A) بدون بناء جملة خاص ، لأنه لا يبدو أن هناك صيغة خاصة عاقلة متاحة ، باستثناء صيغة أحادية عالية.

أحب حل ttparker إذا وجدت نفسي أكتب الكثير من الماكرو المبدل ، @t الذي يسمي transpose .

مرة أخرى ، كنت مخطئًا في القول:

transpose(A) with no special syntax # please don't do this.

أشكركم على أخذ تعليقاتي على محمل الجد على الرغم من ضعفي في الرياضيات على مستوى الدراسات العليا.

(من الخطاب ).

أرغب في أن يكون ' عامل تشغيل ما بعد الإصلاح يقوم بتعيين f' إلى '(f) حيث Base.:'(x::AbstractMatrix) = adjoint(x) والمستخدم مجاني لإضافة طرق أخرى بها لا علاقة له بالمساعدات. (على سبيل المثال ، قد يرغب بعض الأشخاص في استخدام f' للإشارة إلى df / dt.)

مع إدخال لاحقات عامل التشغيل في 0.7 ، سيكون من الطبيعي بعد ذلك أن يتم تعيين f'ᵃ إلى 'ᵃ(f) ، وهكذا ، مما يسمح للمستخدم بتحديد عوامل postfix الخاصة به. هذا سيجعل من الممكن أن يكون لديك Base.:'ᵀ(x::AbstractMatrix) = transpose(x) و Base.:'⁻¹(x::Union{AbstractMatrix,Number}) = inv(x) ، إلخ.

ربما لا تكون كتابة A'ᵀ نظيفة مثل Aᵀ ، لكنها لن تتطلب إهمال الأسماء المتغيرة التي تنتهي بـ .

للوهلة الأولى يبدو أنه يمكن أن يكون ميزة غير منقطعة. إنه حل وسط ذكي للغاية. احب ذلك.

يبدو معقولا بالنسبة لي. أصعب جزء هو الحصول على اسم للدالة ' — لا يعمل بناء جملة البادئة في هذه الحالة.

أصعب جزء هو الخروج باسم الوظيفة

apostrophe ؟ قد تكون حرفية للغاية ...

هل من الممكن عمل بناء جملة البادئة على الإطلاق (على سبيل المثال ، مع بناء جملة (')(A) صريح؟)؟ إذا لم يكن الأمر كذلك ، فهذه مشكلة لأنها ستكسر قاعدة if-you-can-definition-the-icon-name-then-you-can-override-its-syntax المقدمة بواسطة https://github.com/JuliaLang / جوليا / سحب / 26380.

تحرير: يبدو أنه متاح:

julia> (')(A)


ERROR: syntax: incomplete: invalid character literal

julia> (')(A) = 2


ERROR: syntax: incomplete: invalid character literal

لسوء الحظ ، يعد ' من أصعب الأحرف في الاستخدام كاسم معرف ، لأنه يقدم نوعًا مختلفًا من الذرة (الأحرف) ، والتي لها أسبقية عالية جدًا (تساوي أسبقية المعرفات نفسها). على سبيل المثال ، هل (')' تطبيق ' لنفسه ، أم قوس مفتوح متبوعًا بحرفية ')' ؟

أحد الخيارات غير العملية على المدى القصير هو التصريح بأن القيم الحرفية للأحرف لا تساوي ' ، واستخدام سلسلة ماكرو مثل c"_" بدلاً من ذلك.

ماذا عن إذا كان ' يوزع كمعرف عندما يسبقه نقطتان ، بحيث يعمل Base.:' ؟

بالطبع (@__MODULE__).:'(x) = function_body قد يكون كتابة مرهقة بعض الشيء ، لكن (x)' = function_body يجب أن يعمل بنفس الطريقة. تحرير: لا ، نظرًا لأنه يجب تعيين (x)' لاستدعاء ' في Base . قد يكون تحديد دالة ' في الوحدة النمطية الحالية مرهقًا ، ولكن لن يكون هناك أي سبب للقيام بذلك أيضًا.

أو ماذا عن السماح بتحليل '' كمعرّف ' بينما كان سيتم تحليله كحرف حرفي فارغ (وهو حاليًا خطأ على مستوى التحليل). وبالمثل ، يمكن تحليل ''ᵃ باعتباره المعرف 'ᵃ ، وما إلى ذلك.

سيظل تحليل كل شيء ليس خطأً في بناء الجملة كما كان من قبل (على سبيل المثال ، 2'' تم تطبيق postfix ' مرتين على 2 ) ، لكن 2*'' سيفعل ذلك الآن تحليل مثل مرتين ' .

يبدو محيرًا أنه سيكون لدينا a'' === a لكن ''(a) === a' . يبدو من الأفضل استخدام Base.apostrophe كاسم بدلاً من ذلك (أو شيء من هذا القبيل).

هل من الأفضل تقسيم هذه المناقشة إلى مشكلة جديدة في Github ، نظرًا لأنها تدور حول بناء جملة ' ولا يرتبط ارتباطًا مباشرًا بنقل المصفوفة؟

هل هناك طريقة آلية لتقسيم المشكلات ، أم ينبغي علي ببساطة فتح واحدة جديدة والارتباط بالمناقشة هنا؟

الأخير

الموقف الوحيد الذي يكون فيه الترميز المرتفع- T مناسبًا حقًا هو إذا كان لديك مصفوفة عددية تريد تبديل مؤشراتها ، لكنك حقًا لا تريد عامل التشغيل الخطي المساعد. توجد مثل هذه المواقف بالتأكيد ، لكنها قد تكون نادرة جدًا بحيث لا تبرر إدخال صياغة جديدة.

أعتقد أنني تأخرت كثيرًا عن المناقشة ، لكني أود أن أشير إلى استخدام واحد أعتقد أنه جدير بالذكر: تطبيق تمايز الخطوة المعقدة على دالة ذات قيمة حقيقية تحتوي على transpose بداخلها هو - هي. (لقد اكتشفت شخصيًا أنني بحاجة إلى .' في MATLAB و Julia لهذا السبب بالذات.)

سأعطي مثالاً مع مرات متعددة transpose (ربما يمكنني تجنب القيام بذلك بهذه الطريقة؟)

using LinearAlgebra

# f : Rⁿ → R
#     x  ↦ f(x) = xᵀ * x / 2
f(x) = 0.5 * transpose(x) * x

# Fréchet derivative of f
# Df : Rⁿ → L(Rⁿ, R)
#      x  ↦ Df(x) : Rⁿ → R (linear, so expressed via multiplication)
#                   h  ↦ Df(x)(h) = Df(x) * h
Df(x) = transpose(x) 

# Complex-step method version of Df
function CSDf(x) 
    out = zeros(eltype(x), 1, length(x))
        for i = 1:length(x)
        x2 = copy(x) .+ 0im
        h = x[i] * 1e-50
        x2[i] += im * h
        out[i] = imag(f(x2)) / h
    end
    return out
end

# 2nd Fréchet derivative
# D2f : Rⁿ → L(Rⁿ ⊗ Rⁿ, R)
#       x  ↦ D2f(x) : Rⁿ ⊗ Rⁿ → R (linear, so expressed via multiplication)
#                     h₁ ⊗ h₂ ↦ D2f(x)(h₁ ⊗ h₂) = h₁ᵀ * D2f(x) * h₂
D2f(x) = Matrix{eltype(x)}(I, length(x), length(x))

# Complex-step method version of D2f
function CSD2f(x)
    out = zeros(eltype(x), length(x), length(x))
    for i = 1:length(x)
        x2 = copy(x) .+ 0im
        h = x[i] * 1e-50
        x2[i] += im * h
        out[i, :] .= transpose(imag(Df(x2)) / h)
    end
    return out
end 

# Test on random vector x of size n
n = 5
x = rand(n)
Df(x) ≈ CSDf(x)
D2f(x) ≈ CSD2f(x)

# test that the 1st derivative is correct Fréchet derivative
xϵ = √eps(norm(x))
for i = 1:10
    h = xϵ * randn(n) # random small y
    println(norm(f(x + h) - f(x) - Df(x) * h) / norm(h)) # Fréchet check
end

# test that the 2nd derivative is correct 2nd Fréchet derivative
for i = 1:10
    h₁ = randn(n) # random h₁
    h₂ = xϵ * randn(n) # random small h₂
    println(norm(Df(x + h₂) * h₁ - Df(x) * h₁ - transpose(h₁) * D2f(x) * h₂) / norm(h₂)) # Fréchet check
end
# Because f is quadratic, we can even check that f is equal to its Taylor expansion
h = rand(n)
f(x + h) ≈ f(x) + Df(x) * h + 0.5 * transpose(h) * D2f(x) * h

النقطة الأساسية هي أنه يجب تحديد f و Df باستخدام transpose ويجب ألا يستخدموا المضاعف.

لا أعتقد أن طريقة الخطوة المعقدة مناسبة جدًا لجوليا. أليس من الاختراق الأنيق / الحل البديل الحصول على تمايز تلقائي في الحالات التي تدعم فيها اللغة الأرقام المعقدة المضمنة الفعالة ، ولكن لا يمكن تحديد نوع الرقم Dual الذي يكافئ ذلك؟ هذا ليس هو الحال في جوليا ، التي لديها مكتبات تفاضل تلقائية لطيفة حقًا.

أوافق على استخدام الأرقام المزدوجة بدلاً من طريقة الخطوة المعقدة وهذه نقطة جيدة جدًا تقوم بها (أنا شخصياً استبدلت بالفعل جميع تقييمات أسلوب الخطوة المعقدة بأرقام ثنائية في جوليا). ومع ذلك ، أعتقد أن هذه لا تزال حالة استخدام صالحة ، لأغراض العرض التوضيحي ، وحيل التدريس (انظر ، على سبيل المثال ، نيك هيغام يتحدث عن طريقة الخطوة المعقدة في Julia Con 2018 ) ، وقابلية النقل (بمعنى آخر ، أشعر بالقلق من ذلك نسخة MATLAB من الكود أعلاه باستخدام الأرقام المركبة ستكون أكثر وضوحًا).

قادمًا من عالم المهندسين وربما الفيزيائيين الذين يستخدمون المصفوفات المعقدة أكثر من المصفوفات الحقيقية ، فإن عدم وجود عامل تبديل يمثل بعض الألم. (التمثيل الطوري المعقد للاعتماد على الوقت التوافقي موجود في كل مكان في مجالنا.) أنا شخصياً أفضل بناء الجملة المعقدة لـ xH و xT ، على الرغم من أن اعتباري الوحيد هو الإيجاز.

كثافة عامل التحويل بالنسبة إلى تحويل Hermitian حوالي 1 إلى 1 في الكود الخاص بي. لذا فإن التبديل غير المقترن مهم بنفس القدر بالنسبة لي. الكثير من استخدامات التحويل هو إنشاء منتجات خارجية ولحجم المصفوفات بشكل صحيح للتفاعل مع كود آخر أو لمضاعفة المصفوفة.

أعتزم في الوقت الحالي توفير وظيفة ماكرو أو حرف واحد للعملية ، ولكن ما هو المكافئ المناسب للوظيفة القديمة ، أو تبديل () أو permutedims ()؟

تم تصميم transpose للجبر الخطي وهو متكرر ، و permutedims مخصص للترتيب غير التكراري للبيانات من أي نوع.

من المثير للاهتمام أن تقول إنك تستخدم تبديل الموضع بقدر ما هو مساعد. اعتدت أن أكون متماثلًا ، ولكن في الغالب لأنني كنت أميل إلى ارتكاب أخطاء حيث كانت بياناتي حقيقية ، لذلك كنت أميل إلى التبديل ولكن في الواقع كانت العملية المساعدة هي العملية الصحيحة (معممة للحالة المعقدة - كانت الوظيفة المساعدة هي العملية الصحيحة لخوارزمية). هناك (العديد) من الاستثناءات الصحيحة بالطبع.

في كل ما يتعلق بالديناميكا الكهربائية ، غالبًا ما تستخدم متجهات تشبه الفراغ وتريد استخدام عمليات المتجه في R ^ n (عادةً n = 3) ، على سبيل المثال transpose وجه الخصوص ، على الرغم من أن المتجهات الخاصة بك ذات قيمة معقدة لأنك لقد اتخذت تحويل فورييه. يبدو أن mattcbro يتحدث عن هذا النوع من التطبيقات.

ومع ذلك ، عند قراءة مناقشات بناء الجملة ، غالبًا ما أفكر في أنه بالنسبة لي شخصيًا ، لم أستطع أن أتخيل أن بناء الجملة الأكثر تفصيلًا هو الشيء الذي يبطئ من سرعة البرمجة أو كفاءتها. يستغرق التفكير في الخوارزمية نفسها والطريقة الأكثر طبيعية / فعالية لتنفيذها وقتًا أطول بكثير.

في كل ما يتعلق بالديناميكا الكهربائية ، غالبًا ما تستخدم متجهات تشبه الفراغ وتريد استخدام عمليات المتجهات في R ^ n (عادةً n = 3) ، أي تبديل على وجه الخصوص ، على الرغم من أن المتجهات الخاصة بك ذات قيمة معقدة لأنك أخذت فورييه تحول.

ليس بالضرورة. غالبًا ما تريد كميات متوسط ​​الوقت من سعة فورييه ، وفي هذه الحالة تستخدم المنتج النقطي المركب ، على سبيل المثال ½ℜ [𝐄 * × 𝐇] هو تدفق بوينتينغ لمتوسط ​​الوقت من مكونات فورييه المعقدة و ¼ε₀ | 𝐄 | ² هو كثافة طاقة الفراغ متوسط ​​الوقت. من ناحية أخرى ، نظرًا لأن عامل تشغيل ماكسويل (عادةً) عامل متماثل معقد ("مقلوب") ، فغالبًا ما تستخدم "منتج داخلي" غير مقترن للجبر (اللانهائي الأبعاد) في الحقول 𝐄 (𝐱) وما إلى ذلك. كل الفضاء.

هذا صحيح ، لقد كانت الكلمة غالبًا في الجملة الأولى ، لكنني أزلتها على ما يبدو :-).

حسنًا ، إذا كنت تريد الذهاب إلى هناك ، فإن الكميات الكهرومغناطيسية مكتوبة بشكل أكثر إيجازًا في صيغة Clifford Algebraic ، وغالبًا ما تسمى الجبر الهندسي. هذه الجبر لها العديد من الأشكال التلقائية ومضادات الأشكال التي تلعب دورًا مهمًا في صياغة النظرية ، خاصة عند النظر في مشاكل التشتت.

عادةً ما تحتوي هذه الجبر على تمثيل مصفوفة موجز وغالبًا ما يتم حساب هذه الأشكال بسهولة عبر التحويل المعقد ، والتبديل الهرمي والاقتران.

ومع ذلك ، كما ذكرت سابقًا ، فإن استخدامي الأساسي للتبديل غالبًا ما يكون لترتيب المصفوفات الخاصة بي للتفاعل مع مصفوفات أخرى ، وكود آخر ، والحصول على مصفوفة مضاعفة للعمل مقابل البعد الصحيح للصفيف المسطح.

أنا شخصيا أفضل بناء الجملة numpy من xH و xT

سهل التنفيذ الآن في الإصدار 1.0 ، ويجب أن يكون فعالاً:

function Base.getproperty(x::AbstractMatrix, name::Symbol)
    if name === :T
        return transpose(x) 
    #elseif name === :H # can also do this, though not sure why we'd want to overload with `'`
    #    return adjoint(x)
    else
        return getfield(x, name)
    end
end 

هذا سهل بشكل مدهش وأنيق نوعًا ما. يبدو أن الجانب السلبي هو أن الاستخدامات المتعامدة لـ getproperty لا تؤلف مع بعضها البعض. لذا فإن أي شخص يقوم بتنفيذ getproperty على نوع المصفوفة الخاص به سيحتاج إلى تنفيذ السلوك العام يدويًا.

الاستخدامات المتعامدة لـ getproperty لا تؤلف

همم. أتساءل عما إذا كان ذلك يعني أنه تم تخفيض xT إلى getproperty(x, Val(:T)) . أنا أرتجف عندما أفكر في ما يمكن أن يفعله ذلك للمترجم الفقير بالرغم من ذلك.

أنا متأكد من أن كل شخص لديه آرائه - ولكن بالنسبة لي يكاد يكون من السمات أنه من الصعب إنشاء واجهة عامة من بناء الجملة. لا تفهموني بشكل خاطئ ، إنها ميزة رائعة حقًا ورائعة لتعريف الهياكل التي تشبه tuple-like ، وما إلى ذلك.

(من الممكن أيضًا إضافة طبقة إرسال Val إلى الأنواع الخاصة بك بسهولة تامة).

يعمل كود @ c42f مثل السحر. لسوء حظي ، أحاول كتابة رمز يعمل على الإصدارات 0.64 وما فوق ، مما يجبرني على استخدام إما تبديل الموضع أو وظيفتي المحددة T (A) = تبديل (A). ربما كان الماكرو أنظف قليلاً وأكثر كفاءة قليلاً.

لكي أكون واضحًا ، لا أقترح تحديد هذا getproperty تحديدًا فكرة جيدة لكود المستخدم. من المحتمل فقط كسر الأشياء على المدى الطويل ؛-) على الرغم من أنه ربما في يوم من الأيام سيكون لدينا شعور جيد بما يكفي للعواقب التي يمكن أن x.T في Base .

لكن بشكل عام ، أتساءل لماذا يعتبر استخدام هذا النوع من الخاصية لتعريف "الحاصل" في الواجهات العامة أمرًا سيئًا في الواقع. على سبيل المثال ، تحتوي وظائف الحصول على الحقول العامة حاليًا على مشكلة كبيرة في مساحة الاسم والتي يتم حلها ببساطة عن طريق الاستخدام الحكيم لـ getproperty . من الأجمل كتابة x.A من كتابة MyModule.A(x) ، بعض أسماء الوظائف القبيحة الأطول مثل get_my_A(x) ، أو تصدير الاسم العام للغاية A من مستخدم وحدة. المشكلة الوحيدة كما أراها ، هي القدرة المتوقعة على تجاوز معنى .B للأنواع الفرعية بشكل مستقل عن .A الذي يتم تعريفه بشكل عام على النوع الممتاز. ومن هنا التعليق نصف الجاد حول Val .

فكرة مضحكة:

julia> x'̄
ERROR: syntax: invalid character "̄"

تبدو الشخصية وكأنها T لكنها في الواقع ' مع شريط فوقه. لست متأكدا إذا كان الأمر جادا...

screen shot 2018-09-10 at 11 29 56

نعم ، يبدو هذا على GitHub بالنسبة لي أيضًا. لكنها فوقية. نسخ ولصق في العروض الطرفية الخاصة بي:

screen shot 2018-09-10 at 10 31 24 am

ذكي جدا ولطيف. ما زلت أحب دمج الأحرف ، رغم ذلك ، وأعتقد أن 'ᵀ جميل.

-100 لتغيير الوضع الملائم ، نظرًا لأنه أحد الأشياء الرائعة التي تجعل كتابة كود جوليا واضحًا مثل كتابة الرياضيات ، بالإضافة إلى أن التحويل المترافق عادة ما يكون ما تريده على أي حال ، لذا فمن المنطقي أن يكون لديك صيغة مختصرة لها.

هناك نوع من الغطرسة لبيان مثل هذا. ضع في اعتبارك أن هناك نسبة محدودة من المطورين صراحةً _ لا يريدون_ adjoint() لكن _need_ transpose() .

الحالة والنقطة بالنسبة لنا عند العمل مع العمليات الحسابية الرمزية لنمذجة عامل التشغيل الافتراضي ' قد يتسبب على سبيل المثال في إرجاع شبه عكسي (A'*A)\(A * b) أو نموذج تربيعي v'*A*v لإرجاع خطأ نتائج طويلة ومعقدة لا يمكن اختزالها.

ربما يكون الحل هو نوع من توجيه المترجم الذي يوضح معنى ' .

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات