Julia: Arraypocalypse بين الحين والآخر

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

هذه المسألة تحل محل العمل 0.4 نحو السكينة مجموعة (# 7941)، وسوف مسارات القضايا ونحن نهدف إلى استكمال خلال 0.5 وما بعده - تحديث الآن من خلال العمل على 0.7. هذه مشكلة شاملة وستتتبع مهام محددة في قضايا أخرى. لا تتردد في إضافة الأشياء التي فاتني.

التقنيات الأساسية المطلوبة

  • [x] فحص وإزالة حدود جوليا الأصلية (# 7799). تم إجراء العديد من المحاولات في هذا الصدد ، لكنني أعتقد أن خطة العمل الحالية تتمثل في جعل كتل كود elide @inbounds مخفية داخل ماكرو @boundscheck ، ونشر مستوى واحد فقط من التضمين (https: / /github.com/JuliaLang/julia/issues/7799#issuecomment-117362695). هذا مطلب قوي للخطوات اللاحقة. (نُفذ في 14474 #)
  • [x] ReshapedArrays (# 10507). يتطلب أداء أفضل: https://groups.google.com/d/msg/julia-dev/7M5qzmXIChM/kOTlGSIvAwAJ

تغيير كبير في سلوك كسر 0.5

  • [x] أبعاد الإسقاط مفهرسة بواسطة مقياس (https://github.com/JuliaLang/julia/issues/4774#issuecomment-81228816 ؛ بشكل عام ، تقطيع نمط APL حيث تكون رتبة الشريحة هي مجموع رتب الفهارس ، انظر أدناه). PR على # 13612.
  • [x] اقلب المفتاح في إهمال التسلسل (# 8599)
  • [x] إزالة سلوك عدم التشغيل الافتراضي لـ (c) تبديل (# 13171)
  • [x] تغيير سلوك sub إلى slice (# 16846)

التغييرات الرئيسية 0.6 سلوك كسر

  • [x] ترجع Vector Transpose عامل تحويل (https://github.com/JuliaLang/julia/issues/4774#issuecomment-81228816). التنفيذ في # 19670.
  • [x] يُرجع اقتران المتجه برنامج التضمين البطيء (# 20047)

التغييرات المحتملة في المستقبل

  • [x] تبديل المصفوفة والتصريف يعيدان أغلفة كسولة (# 25364)
  • [] عودة الشرائح كطرق عرض. لا يزال من غير الواضح ما إذا كانت تغييرات الأداء المحتملة متسقة وكبيرة بما يكفي لتكون جديرة بالكسر. انظر https://github.com/JuliaLang/julia/issues/3701.
  • [] هل يجب أن تسقط التخفيضات الأبعاد؟ # 16606

وظائف جديدة

  • [x] السماح بالتعبير عن varargs بطول محدد (# 11242). هذا يسمح لنا بالاستفادة الكاملة من # 10525.
  • [x] تخلص من التخفيض الخاص لـ Ac_mul_Bt ، استخدم الإرسال على أغلفة النقل البطيئة بدلاً من ذلك. (# 5332 ، # 25217)
  • [x] الأبعاد المفهرسة بواسطة المصفوفات متعددة الأبعاد تضيف أبعادًا (نمط APL الكامل: أبعاد النتيجة هي مجموع أبعاد المؤشرات). (# 15431)
  • [x] السماح بأي نوع فهرس في الفهرسة غير العددية (# 12567). قم بتشديد الفهرسة العددية للمؤشرات <: Integer وقم بتوسيع الفهرسة غير العددية إلى <: Union{Number, AbstractArray, Colon} (https://github.com/JuliaLang/julia/pull/12567#issuecomment-170982983). تحويل أكثر انتظامًا للمؤشرات مثل أي نوع فهرس يمكن تحويله إلى Int أو AbstractArray : # 19730
  • [] إنشاء أسهل للمصفوفات الثابتة باستخدام tuples و # 12113.

احتمالات المضاربة الأخرى

  • [] نوع مخزن مؤقت قابل للتغيير بحجم ثابت ، والذي يسمح بتعريف جوليا الأصلي Array (# 12447) ؛ يمكن أيضًا استخدام هذا النوع للمخازن المؤقتة للإدخال / الإخراج وتخزين السلسلة.
  • [x] الأساس IndexSet IntSet على BitArray أو ربما أي AbstractArray{Bool} . (# 20456)
  • [x] إعادة عمل الفهرسة غير القياسية لمنع استدعاء find على المصفوفات المنطقية ولفها ببساطة بـ IndexSet LogicalIndex بدلاً من ذلك؟ (# 19730)
  • [] الفهرسة السلبية مع مكمل IndexSet (https://github.com/JuliaLang/julia/issues/1032) أو خاص Not النوع؟ (ربما في حزمة: https://github.com/mbauman/InvertedIndices.jl)
  • [x] إهمال الخطية للأبعاد الزائدة عند توفير أكثر من مؤشر واحد (فهرسة خطية جزئية). (# 20079)
  • [x] السماح فقط بالفهرسة في مصفوفات ذات أبعاد N ذات مؤشرات 1 أو N ، مما يؤدي إلى إهمال الفهرسة "الجزئية" وتتبع أبعاد المفرد (https://github.com/JuliaLang/julia/issues/5396 and # 14770).
  • [] ابحث عن صيغة بديلة للمصفوفات المكتوبة - الفهرسة في نوع ( T[...] ) هي نوع من التورية السيئة. هذه الصيغة سيئة بشكل خاص لأن بعض الاختلافات يتم تحليلها كفهرسة إلى نوع بينما يتم تحليل البعض الآخر كأشكال خاصة (مكتوبة hvcat ، فهم مكتوب)
  • [x] قم بتغيير التجزئة إلى ترميز طول التشغيل لفرق المصفوفات ، مما سيسمح لنطاقات الأعداد الصحيحة والمصفوفات بالتجزئة على قدم المساواة مرة أخرى. (https://github.com/JuliaLang/julia/issues/12226#issuecomment-122952826، # 16401)
  • [x] انقل المصفوفات المتناثرة خارج القاعدة إلى حزمة قياسية. (# 25249)
  • [x] السماح بالمؤشرات غير التقليدية (# 16260)
  • [x] @sub @view ماكرو (# 16564)
arrays linear algebra

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

يمكن أن يستخدم كل من Base و ArrayViews view . بعد كل شيء ، يستخدم ImageView أيضًا view :)

ال 276 كومينتر

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

يوم الثلاثاء ، 15 سبتمبر 2015 ، Matt Bauman [email protected]
كتب:

هذه المسألة تحل محل 0.4 العمل نحو مصفوفة نيرفانا (# 7941
https://github.com/JuliaLang/julia/issues/7941) ، وسوف تتبع ملف
القضايا التي نهدف إلى إكمالها خلال 0.5. هذه مظلة وإرادة
تتبع مهام محددة في قضايا أخرى. لا تتردد في إضافة الأشياء
لقد فاتني (على الأقل خلال النصف الأول من 0.5).

_التقنيات الأساسية المطلوبة_

  • فحص حدود جوليا الأصلية وإزالتها (# 7799
    https://github.com/JuliaLang/julia/issues/7799). عدة محاولات لها
    في هذا ، لكنني أعتقد أن خطة العمل الحالية هي القيام بذلك
    inbounds elide كتل التعليمات البرمجية المخفية داخل ماكرو boundscheck ،
    نشر أسفل مستوى واحد فقط من التضمين (# 7799 (تعليق)
    https://github.com/JuliaLang/julia/issues/7799#issuecomment-117362695).
    هذا مطلب قوي للخطوات اللاحقة.
  • ReshapedArrays (# 10507
    https://github.com/JuliaLang/julia/pull/10507). يتطلب أفضل
    أداء:
    https://groups.google.com/d/msg/julia-dev/7M5qzmXIChM/kOTlGSIvAwAJ

_التغييرات في سلوكيات الاختراق_

  • أبعاد الإسقاط مفهرسة بواسطة عددي (# 4774 (تعليق)
    https://github.com/JuliaLang/julia/issues/4774#issuecomment-81228816)
  • إرجاع الشرائح كطرق عرض. كانت المحاولة الأولى في هذا رقم 9150
    https://github.com/JuliaLang/julia/pull/9150. اهتمام خاص قد
    تكون مطلوبة لـ BitArrays.
  • اقلب المفتاح الموجود في إهمال التسلسل (# 8599
    https://github.com/JuliaLang/julia/pull/8599)

_ وظائف جديدة_

  • السماح بالتعبير عن varargs بطول محدد (# 11242
    https://github.com/JuliaLang/julia/pull/11242). هذا يسمح لنا
    استفد بالكامل من # 10525
    https://github.com/JuliaLang/julia/pull/10525.
  • إرجاع Transpose نوع covector أو نوع تبديل (# 4774 (تعليق)
    https://github.com/JuliaLang/julia/issues/4774#issuecomment-81228816)
  • تخلص من التخفيض الخاص لـ Ac_mul_Bt ، استخدم الإرسال بدلاً من ذلك.
  • تضيف الأبعاد المفهرسة بواسطة مصفوفات متعددة الأبعاد أبعادًا (كاملة
    نمط APL: أبعاد النتيجة هي مجموع
    أبعاد المؤشرات)
  • السماح بأي نوع فهرس في الفهرسة غير العددية (# 12567
    https://github.com/JuliaLang/julia/pull/12567)
  • إنشاء أسهل للمصفوفات غير القابلة للتغيير باستخدام tuples و # 12113
    https://github.com/JuliaLang/julia/pull/12113.

_إمكانيات مضاربة أخرى_

  • نوع مخزن مؤقت قابل للتغيير بحجم ثابت ، والذي من شأنه أن يسمح بامتداد
    تعريف مصفوفة جوليا الأصلية (# 12447
    https://github.com/JuliaLang/julia/issues/12447)
  • قاعدة الفهرس على BitArray أو ربما أي AbstractArray {Bool}.
  • إعادة صياغة الفهرسة غير المتدرجة لمنع استدعاء البحث في المصفوفات المنطقية
    ولفها ببساطة باستخدام IndexSet بدلاً من ذلك؟
  • الفهرسة السلبية مع IndexSet مكملة؟ (ربما في عبوة)

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/13157.

نعم ، قائمة رائعة! دعونا نشمر عن سواعدنا!

هل هناك أي أجزاء من هذا لا يطالب بها أحد؟ أود المساعدة ، لكني
لا تريد أن تطأ أصابع قدم أي شخص.

في يوم الثلاثاء الموافق 15 سبتمبر 2015 ، أرسل Jeff Bezanson [email protected]
كتب:

نعم ، قائمة رائعة! دعونا نشمر عن سواعدنا!

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/13157#issuecomment -140586293.

إنها قائمة استثنائية. في الواقع ، لا يوجد سوى عدد قليل من التغييرات المتقطعة للغاية ، وهو أمر رائع ، لكن هذه التغييرات مهمة بما يكفي.

هناك بالتأكيد عمل أكثر من كافٍ للقيام به! لا أعتقد أنه تم المطالبة بأي من هذه المهام.

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

المشاهدات صعبة ، عليك أن تجعلها من خلال التمهيد بدون: hocho: نفسك في: العيون:.

بعد أن قمت للتو بمجموعة من العمل لإجراء تغييرات على السلسلة من خلال التمهيد ، أميل إلى تصديق ذلك.

شكرا لفعل هذا mbauman ، الكثير

لقد أضفت "إزالة سلوك عدم التشغيل الافتراضي لـ (ج) تبديل" كعنصر. أتوقع الكثير من الشكوى ، ولكن كما ناقشنا من قبل ، من الخطأ ببساطة افتراض أن <:Any هو تضمين التغريدة

أعتقد أننا بحاجة إلى التفكير مليًا في الخيارات لذلك. من الاصطلاح أن تكتب A' لنقل مصفوفة غير معقدة.

أليس من الممكن أن يحل غلاف النقل (ج) هذه المشكلة؟ هناك الكثير من أعمال التصميم التي ستحتاج إلى الخوض فيها ، ولكن:

transpose(A::AbstractVectorOrMatrix) = TransposeType(A) # Will call `transpose` upon indexing, too
transpose(::AbstractArray) = error("cannot take transpose of 3+ dim array") # yeah, error methods aren't the best…
transpose(x) = x

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

أليس من الممكن أن يحل غلاف النقل (ج) هذه المشكلة؟

يمكن؛ علينا التفكير في الأمر.

مشكلة المنع في المرة الأخيرة هي أن التحويل يجب أن يكون متكررًا للتعامل مع حالات مثل Matrix{Matrix} (مثال: A = [rand(1:5, 2, 2) for i=1:2, j=1:2]; A' ) بشكل صحيح ، لكن الناس يريدون كتابة A' على المصفوفات ثنائية الأبعاد على غير -الأنواع الرقمية (مثل الصور as Matrix{<:Colorant} ) وتوقع ألا يتم تطبيق التحويل على العناصر العددية. توجد طريقة no-op transpose(x::Any) للتعامل مع هذه الحالات. ومع ذلك ، يتعارض هذا التعريف مع كائنات تشبه المصفوفة ، والتي تحتوي على دلالات جبرية للمصفوفات ولكن لا يتم تخزينها داخليًا في أي شكل يشبه المصفوفة ، وبالتالي يجب ألا يكون الرقم 987 AbstractArray ( QRCompactWYQ هو الطفل الملصق ، لكن لدينا العديد من الأمثلة). إذا أدخلت نوعًا جديدًا يشبه المصفوفة ، فيجب عليك تحديد (c)transpose بشكل صريح وإلا ستحصل على احتياطي عدم التشغيل الذي يعد مصدرًا للعديد من الأخطاء.

لكي نكون واضحين ، فإن السلوك الذي سنتخلى عنه صراحة هو المطالبة (التي يمكنك العثور عليها في المساعدة مقابل permutedims )

يُعادل التحويل المتغير (A، [2،1]).

هذا التكافؤ لا معنى له بالنسبة للأنواع التي ليست AbstractArray s والتي هي AbstractArray s من non-scalars ، ولدينا بالفعل أنواع تشبه المصفوفة تحتاج إلى هذا الإحساس المجرد أكثر للتبديل.

أعتقد أن افتراض أن المصفوفة {Matrix} سوف تتكرر تلقائيًا
تبديل العناصر سيء وخطير. أفضل رؤية نوع خاص
BlockMatrix {Matrix} التي تقوم بما تبحث عنه.

يوم الأربعاء ، 16 سبتمبر 2015 ، الساعة 10:30 صباحًا ، Jiahao Chen [email protected]
كتب:

أليس من الممكن أن يحل غلاف النقل (ج) هذه المشكلة؟

يمكن؛ علينا التفكير في الأمر.

مشكلة الحظر في المرة الأخيرة هي أن التحويل يجب أن يكون تكراريًا إلى
معالجة حالات مثل Matrix {Matrix} (مثال: A = [rand (1: 5، 2، 2) for
أنا = 1: 2 ، ي = 1: 2] ؛ A ') بشكل صحيح. ومع ذلك ، يريد الناس كتابة A 'على 2D
المصفوفات على الأنواع غير الرقمية (مثل الصور ، مثل Matrix {<: Colorant}) و
توقع أن لا يتم تطبيق التحويل على العناصر العددية. إن no-op
توجد طريقة تبديل (x :: أي) للتعامل مع هذه الحالات. ومع ذلك، هذا
التعريف يتعارض مع العناصر الشبيهة بالمصفوفة ، والتي لها الجبر
دلالات المصفوفات ولكن لا يتم تخزينها داخليًا في أي شكل يشبه المصفوفة ،
وبالتالي من خلال # 987 https://github.com/JuliaLang/julia/issues/987 يجب
لا تكون مصفوفة Abstract (QRCompactWYQ هو الطفل الملصق ، ولكن لدينا
العديد من هذه الأمثلة). إذا أدخلت نوعًا جديدًا يشبه المصفوفة ، فيجب عليك ذلك
حدد صراحة (ج) تبديل وإلا ستحصل على احتياطي عدم الرجوع الذي
هو مصدر للعديد من الحشرات.

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

يُعادل التحويل المتغير (A، [2،1]).

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

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/13157#issuecomment -140759002.

tbreloff هذا بالضبط وجهة نظري. يعتقد معظم الناس أنه من الغريب أن يكون التحويل تكراريًا ، ولكن يجب أن يكون نقلًا صحيحًا رياضيًا ، وهذا القلق يكشف حالات الزاوية التي لا يكون فيها التحويل مجرد permutedims(A, [2,1]) . (على الرغم من صحة أن Matrix{Matrix}} ليس في الحقيقة نوع مصفوفة محظورة ، لأنه لا توجد ضمانات على الإطلاق بأن المصفوفات الداخلية لها أبعاد تتوافق مع أي تقسيم لمصفوفة أكبر.)

آه ، نعم ، لقد نسيت كل الأشياء التي تشبه Tensor التي ليست مصفوفات مجردة. بغض النظر عما يحدث ، سيحتاج مؤلفو الكائنات الشبيهة بـ Tensor إلى التواصل مع Julia بطريقة أو بأخرى بأنها ليست مقاييس (تكون أحيانًا أعمال AbstractArray ، ولكن ليس دائمًا) ، أو سيحتاج مؤلفو الكائنات التي تشبه Scalar إلى القيام بذلك العكس (أحيانًا يكون الرقم يعمل ، ولكن ليس دائمًا) ، أو كلاهما. هذا النوع نفسه من الأسئلة العددية أو غير العددية يطل برأسه في كل مكان ... على سبيل المثال ، الفهرسة: https://github.com/JuliaLang/julia/pull/12567.

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

نظرًا لأنه لا يمكننا توصيل هذا من خلال الأنواع الفائقة (https://github.com/JuliaLang/julia/issues/987#issuecomment-31531602) ، أعتقد أنه يجب أن يكون إما من خلال توثيق أفضل للطرق المطلوبة أو وجود تلك الطرق مشفرة بشكل صريح في نظام قائم على السمات. وإذا أزلنا جميع العناصر الاحتياطية (التي تضمن السلوك الصحيح على حساب الأساليب المفقودة للجميع) ، أعتقد أننا بحاجة إلى تبسيط ذلك قدر الإمكان مع السمات.

+1

أعتقد حقًا أننا يجب أن نبدأ في تعداد السمات لـ AbstractArray's. يبدو أن الفهرسة الخطية كانت مثالًا رائعًا على قوة بعض قرارات التصميم الدقيقة التي تنطوي على سمات.

يتمثل أحد الحلول الممكنة في الاحتفاظ بـ AbstractArray <: Any ، وتقديم AbstractNonArrayTensor <: Any بجانبه. كل شيء آخر سيعتبر "عددًا" فيما يتعلق بالفهرسة والجبر الخطي.

لاحظ أن هذا يختلف عن التمييز بين Atom مقابل Collection مقابل A[:] = (1,2,3) و A[:] = "123" بشكل مختلف تمامًا عن A[:] = 1:3 مقابل A = Array(Any, 3) ، كما ينبغي.

أعتقد حقًا أننا يجب أن نبدأ في تعداد السمات لـ AbstractArray's.

johnmyleswhite بأي حال من الأحوال ، هل تقصد أن اللغة تدعم "السمات"؟ هذا شيء أردت حقًا أن أراه في اللغة منذ JuliaCon.

نعم ، قصدت السمات المدعومة باللغة.

هل لديك أي أفكار / اقتراحات حول كيفية إضافة السمات إلى جوليا ، نحويًا؟ ستكون مفيدة جدًا للمصفوفات والسلاسل والتشفيرات على أقل تقدير.

أفضل ترك تلك القرارات لجيف بدلاً من التكهن.

بالنظر إلى أن هذه مشكلة شاملة ، سيكون من الجيد مناقشة عناصر محددة في قضاياهم الخاصة.

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

يرجى نقل مناقشة السمات إلى رقم 5 ، و (ج) تبديل المسألة إلى # 13171.

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

حسنًا ، نقطة جيدة ، طالما يتم التفكير في السمات كجزء من التصميم.

العلوي والسفلي للمصفوفات المثلثية؟ هؤلاء يبدون كأنهم مرشحون جيدون لكونهم صفات لي.

تمت إضافة عنصر المضاربة لاستبدال الفهرسة في نوع ما لبناء جملة للمصفوفات المكتوبة.

أفضل عدم نقل المصفوفات المتفرقة من القاعدة في 0.5. أعتقد أننا يجب أن نهدف إلى جعل SparseVectors في Base مقابل 0.5 ، والتأكد من وجود تطبيق افتراضي عالي الجودة حقًا.

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

ماذا عن مهمة تنظيف المنزل الصغيرة هنا أيضًا - نقل كل كود المصفوفة إلى دليل فرعي ووحدة نمطية في Base؟

هناك مجموعة من الأشياء التي تم تحديدها على أنها معلم 0.5. أود أن أقترح أن يتم وضع علامة على المشكلات المشار إليها هنا على أنها 0.5 blocker ، والباقي 0.5 هو أساسًا 0.5 nice to have . يمكننا بعد ذلك الحصول على فترة زمنية تتراوح من أسبوع إلى أسبوعين لتجميع قائمة كاملة بمشكلات 0.5 blocker ، وإصدار 0.5 بمجرد الانتهاء من جميع أدوات الحظر. أي شيء جميل أن يكون لديك مشكلات يتم إصلاحها في نفس الإطار الزمني سوف يصل إلى 0.5 ، لكن الإصدار لن يحظر أي ميزة لطيفة ليست جاهزة.

أود أن أضيف بعض الاحتمالات الإضافية. أنا متحمس للغاية بشأن Arraypocolypse!

أولاً ، أعتقد أنه سيكون من المنطقي وجود عوامل تشغيل لمجموع موتر ومنتج موتر. يمكن أن تكون هذه الرموز ++ و ** ، أو يمكن أن تكون رموز Unicode \otimes و \oplus . يمكن أن يحل منتج Tensor محل kron() . يعطي Tensor sum تسلسلًا للمتجهات ، وبغض النظر عن ذلك ، فهو وصف رائع لسلسلة السلسلة (كان هناك العديد والعديد من المحادثات حول هذا ، ويبدو أن مطوري Julia الأساسيين قلقون من أن + يتوافق مع monoid غير صحيح هنا - وهكذا انتقل إلى * لأنه ربما يبدو أقل تبادليًا - بينما أجادل بشدة أن العملية الصحيحة هي Tensor sum \oplus وهي أيضًا ليست تبادلية). يمكن استخدام هذه أيضًا للمصفوفات / الموترات ذات الترتيب الأعلى (انظر أدناه) وربما (أنا أتوقع هنا) عمليات الجبر العلائقي على DataFrames ؟.

ثانيًا ، لقد خطر لي أن جوليا قد تكون جيدة حقًا في إجراء الجبر متعدد الخطوط بتركيب جيد للغاية. لقد كنت ألعب بحزمة لتعيين أسماء لكل فهرس كمصفوفة كجزء من النوع باستخدام نوع Tuple{...} . يتم تحويل المصفوفة إلى موتر عن طريق فهرستها مثل A[Tuple{:index1,:index2}] وإذا كانت Julia 0.5 تستخدم {} مقابل Tuple{} فسيتم تحسينها كثيرًا إلى A[{:index1,:index2}] وحصلنا على بعد الذهول:

  1. التبديل: A[{1,2,3}] = B[{3,2,1}]
  2. طريقة جديدة لعمل المصفوفة و / أو الضرب المتجه ، A[{:a}] = B[{:b,:a}] * C[{:b}] (العقود التي تزيد عن :b ، لذا A = B' * C ).
  3. وبالمثل ، تقلص موتر تعسفي وعالي الدرجة (ويعرف أيضًا باسم einsum): على سبيل المثال A[{:a,:b}] = B[{:a,:c,:d}] * C[{:c,:e}] * D[{:d,:f}] * E[{:e,:f:,:b}] يمكن استخدام الأقواس لاختيار ترتيب الانكماش الأسرع.
  4. يعتبر مجموع Tensor ومنتج Tensor منطقيًا هنا أيضًا - بحيث يمكن للأشخاص أخذ المنتجات الخارجية من مصفوفات ترتيب أعلى ووضع المؤشرات بالترتيب المطلوب بسهولة ، على سبيل المثال.

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

لست متأكدًا مما إذا كان الناس يرغبون في هذا النهج في الجبر متعدد الخطوط (يعتمد على الوظائف المولدة قليلاً) ولكني سأرحب بأي تعليقات!

هل يمكنك أن تشرح قليلاً عن مجموع الموتر وسلسلة المتجهات (والسلسلة)؟ أعتقد أنه سيكون من الرائع أن يكون لديك عامل تسلسل "عام" ، والذي يحبه علماء الرياضيات أيضًا.

مجموع الموتر (أو المجموع المباشر لـ v = [v_1، v_2، v_3] و w = [w_1، w_2، w_3] مكتوب v \ oplus w = [v_1، v_2، v_3، w_1، w_2، w_3]. (تخيل أنا أستخدم LaTeX - \ oplus and \ otimes تعمل بالفعل في Julia REPL وتبدو + (أو مرات) مرسومة بدائرة حولها).

الموتر / المبلغ المباشر هو حقًا الطريقة الرياضية لسلسلة المتجهات (مثل vcat ) وأود أن أقترح سلاسل أيضًا. بالنسبة للمصفوفات A \ oplus B هي المصفوفة الأكبر ذات الكتلة المائلة [A 0؛ 0 ب] ، (وهو مرشح جيد يتم تمثيله بواسطة BlockedArray s المذكورة أعلاه). بالنسبة إلى المتجهات المنقولة (الصفية) ، فإن مجموع الموتر هو مرة أخرى مجرد التسلسل المعطى بواسطة hcat ، لذلك يجب التعامل مع هذا بشكل مختلف اعتمادًا على ما إذا كان لديك متجه صف أو مصفوفة 1 × n (والتي نأمل أن يجب أن يكون جيدًا في Julia 0.5).

لذلك إذا فكرنا في السلاسل على أنها نواقل للأحرف ، فإن مجاميع التنسور المباشرة هي السبيل للذهاب إذا كان المطورون الأساسيون سيستخدمون كلمات مثل "أحادية الصيغة" كمبدأ بناء جملة إرشادي. هل يمكن اعتبار معالجة الأوتار على أنها فئة أحادية حيث تكون الأسهم المتوازية عبارة عن سلاسل ؟؟ بالتأكيد ، الجبر متعدد الخطوط على الأعداد الحقيقية (أو المعقدة) يتم إعطاؤه بواسطة (خنجر) فئات ثنائية أحادية اللون متماثلة حيث الموتر / المجموع المباشر (\ oplus) والموتر / المنتج الخارجي / المباشر (\ otimes) هما "أحاديات".

andyferris الرجاء فتح إصدار جديد أو العلاقات العامة لسلسلة الموتر. هذه المشكلة طويلة ومعقدة بدرجة كافية دون طرح المزيد من الميزات.

تمت مناقشة العلاقة بين المصفوفات متعددة الأبعاد والجبر متعدد الخطوط في أدبيات APL في السبعينيات ، ولا سيما من قبل Trenchard More وآخرون يعملون على APL2.

نعم ، هذا يستحق إصدارًا جديدًا ، فهذا يعد انحرافًا كبيرًا عن العمل الرئيسي هنا.

( andyferris ، راجع أيضًا https://github.com/Jutho/TensorOperations.jl ، https://github.com/mbauman/AxisArrays.jl ، https://github.com/timholy/AxisAlgorithms.jl.)

أود أن أشارككم بعض الرموز التي قمت بها منذ فترة وأعتقد أن المقابض تصل إلى نقطة واحدة في مساحة التصميم لعمليات المصفوفة التي تعكس المنطقة المحلية وتدعم متناثرًا كفئة أولى. قد يتطلب نقلها سمات أظن ، ولكن قد تجد بعض الأفكار مفيدة https://github.com/wellposed/numerical/tree/master/src/Numerical/Array/Layout وحدات التخطيط على وجه التحديد

شكرا timholy على تلك الروابط ؛ لم أكن على علم بالآخرتين.

ماذا عن مهمة تنظيف المنزل الصغيرة هنا أيضًا - نقل كل كود المصفوفة إلى دليل فرعي ووحدة نمطية في Base؟

ViralBShah تبدو هذه فكرة جيدة جدًا - قم أيضًا بنقل اختبارات وحدة المصفوفة بحيث يكون هناك توافق لطيف 1-1 بين ملفات التنفيذ والاختبار.

هل يجب أن نحصل على الكرة تتدحرج هنا عن طريق قلب المفتاح الموجود في إهمال التسلسل (# 8599)؟

+1

mbauman لديه فرع حيث تم تنفيذ معظم تغييرات النقل. jiahao سوف mbauman هل تعتقد أن ذلك سيكون ممكنًا وهل لديك الوقت لإجراء هذا الفصل إذا قررنا أنه طريقة مفيدة للمتابعة؟

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

أصعب جزء في الاتجاه الذي اتجهت إليه في mb / transpose هو أنني حاولت أيضًا إزالة التخفيض الخاص إلى Ax_mul_Bx. هذا الجزء عبارة عن طن من العمل ، حيث يحتوي كل مشغل على مئات من التباديل لأنواع النقل وأنواع المصفوفات الخاصة وأنواع العناصر المتوافقة مع BLAS. لم أصل إلى نهاية النفق مقابل mul ، ولم أبدأ حتى في التعامل مع المشغلين الآخرين في هذا الفرع. إزالة التخفيض الخاص هو أيضًا النقطة التي نحتاج فيها إلى اتخاذ قرار بشأن تبديل المتجه.

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

أعتقد أنه ينبغي أن يكون من الممكن إضافة احتياطيات بسيطة ، على سبيل المثال ، *(A::Transpose, B::AbstractArray) = At_mul_B(untranspose(A),B) ، من أجل الحصول على عروض تبديل تعمل مع النظام الحالي دون لمس مئات الطرق. وقتي محدود للغاية هذه الأيام ، لذا لا يمكنني أن أعدك بأنني سأجد الوقت للقيام بذلك بنفسي. لكن أعتقد أن هذا يمكن أن يتم في علاقات عامة صغيرة نسبيًا. الجميع مرحب به لالتقاط الشعلة هنا.

لا يمكن أن نبدأ بتعريف أساليب Ax_mul_Bx من حيث
أنواع تبديل؟

في يوم الخميس 5 نوفمبر 2015 ، كتب Matt Bauman [email protected] :

تنفيذ أنواع التحويل نفسها
https://github.com/JuliaLang/julia/blob/335200c142e368cad9aba885df5539d2755195ad/base/transpose.jl
بسيط نوعًا ما - بضع عشرات من LOC.

أصعب جزء في الاتجاه الذي اتجهت إليه في mb / transpose هو
أنني حاولت أيضًا إزالة التخفيض الخاص إلى Ax_mul_Bx. ذلك
الجزء هو _ton_ من العمل ، مع كل عامل يحتوي على المئات من
تباديل أنواع التحويل وأنواع المصفوفات الخاصة والمتوافقة مع BLAS
أنواع العناصر. لم أصل إلى نهاية النفق تمامًا ،
ولم أبدأ حتى في التعامل مع المشغلين الآخرين في هذا الفرع.
إزالة التخفيض الخاص هي أيضًا النقطة التي نحتاج فيها إلى إنشاء ملف
قرار حول ناقل ناقل.

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

أعتقد أنه من الممكن إضافة احتياطات بسيطة ، على سبيل المثال ، * (A :: Transpose،
B :: AbstractArray) = At_mul_B (untranspose (A)، B). وقتي محدود للغاية
في هذه الأيام ، لا يمكنني أن أعدك بأنني سأجد الوقت للقيام بذلك بنفسي. لكن أنا
أعتقد أن هذا يمكن أن يتم في علاقات عامة صغيرة نسبيًا. أي شخص مرحب به في
التقط الشعلة من هنا.

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/13157#issuecomment -154101995.

كيف تسير الأمور مع Arraypocalypse؟ هل الخطة الأصلية هي الحصول على إصدار 0.5 بنهاية شهر يناير مع بقاء جميع الأشياء المذكورة أعلاه في الكتب؟

تحدث الكثير من الأشياء الأخرى في 0.5 ، لكن القليل من AFAICT يحدث في المصفوفات هذه القائمة بالذات. بعضنا ممن ساهموا كثيرًا في الماضي في مصفوفات جوليا مشغولون (جزئيًا ، جني ثمار عملنا السابق: wink :). لتحقيق ذلك ، من المحتمل أن يضطر الآخرون إلى الصعود إلى المستوى (تلميح). لكن ربما يكون الرقم 14474 المنشور للتو هو الشيء الأكثر إثارة على هذه الجبهة الذي سيأتي في وقت طويل - من نواح كثيرة ، هو عنق الزجاجة الحاسم.

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

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

هنا صوت واحد لتأخير 0.5 حتى يتم تنفيذ كل التغييرات الفاصلة حول المصفوفات. ما أفهمه هو أن تقطيع نمط APL (الذي يكسر التوافق مع الإصدارات السابقة) هو بالفعل في المستوى الرئيسي ، لذلك سيتعين على مؤلفي الحزم تحديث كمية كبيرة من التعليمات البرمجية بغض النظر عن 0.5. إذا كان التغيير الرئيسي الآخر (إرجاع المشاهدات بدلاً من النسخ من [] ) سيأتي فقط في بعض الإصدارات بعد 0.5 جوليا ، فسيتعين على الجميع مراجعة / تحديث جميع سطور الكود نفسها مرة أخرى ، والتي ستكون حقًا الكثير من العمل الإضافي الذي يمكن تجنبه تمامًا إذا تم تسليم هذين التعديلين في إصدار واحد.

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

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

على أي حال ، هل يمكن لشخص ما تحديث تاريخ الاستحقاق في 0.5 معلم؟ على الأقل إذا كان تفسيري لتعليق ViralBShah أعلاه صحيحًا ، فلن يكون هناك إصدار جوليا 0.5 في 1/31 ، ما هي المعلومات الحالية المرتبطة بـ 0.5 معلم ، أليس كذلك؟

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

davidanthoff : هل إعادة المشاهدات بدلاً من النسخ sub للحصول على عرض في مصفوفة.

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

كان لدي انطباع بأن الفكرة كانت عبارة عن إصدار 0.5 سريع _بشكل دقيق_ نظرًا لأن تغييرات كسر المصفوفة (يجب أن تكون في إصدار واحد) ستظهر قريبًا. إذا كان هناك قادم خلال الأشهر القليلة المقبلة ، هل يجب تأجيل 0.5؟

ViralBShah ما زال المعلم الرئيسي لهذه المشكلة 0.5 أليس كذلك؟ لا يمكن أن يكون 0.4.x؟

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

➜  arrayalloc git:(master) ✗ make
python lucompletepiv.py
size  100 matrix factorized in  0.010 seconds
size  250 matrix factorized in  0.047 seconds
size  500 matrix factorized in  0.246 seconds
size 1000 matrix factorized in  2.330 seconds

Julia version with copy slices
size  100 matrix factorized in  0.016 seconds
size  250 matrix factorized in  0.093 seconds
size  500 matrix factorized in  0.517 seconds
size 1000 matrix factorized in  4.126 seconds

Julia version with view slices
size  100 matrix factorized in  0.004 seconds
size  250 matrix factorized in  0.078 seconds
size  500 matrix factorized in  0.453 seconds
size 1000 matrix factorized in  3.555 seconds

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

من السهل جدًا تغيير خوارزمية قائمة على النسخ إلى خوارزمية قائمة على العرض ويمكن أن يكون هذا التغيير أسهل إذا أدخلنا صيغة خاصة لطرق العرض. لذلك ، قد لا يكون من المجدي تغيير فهرسة المصفوفة إلى _views افتراضيًا_.

هذه نقطة انطلاق رائعة. تبدو الخطوة الواضحة التالية مثل اكتشاف ما يتعين علينا القيام به لجعل المصفوفات الفرعية أسرع. ربما يعرفtimholy أو @ mbuman بالفعل.

نحن بحاجة إلى أن يكون لدينا مترجم بناء مصفوفة فرعية بالكامل. أعتقد أن كود المصفوفة الفرعية مناسب بالفعل لذلك ، لذلك ربما يكون العمل الشاق "فقط" على codegen هو المطلوب.

andreasnoack ، فإن الاختلاف مع المصفوفات الصغيرة يجعل هذا

موافق ، ولاحظ أننا أسرع من بيثون للمصفوفات الصغيرة.

حسنًا ، أتساءل عما إذا كان هناك شيء آخر يحدث - قد لا يكون هذا معيارًا للمصفوفات الفرعية على الإطلاق. ماذا يحدث إذا استبدلت https://github.com/JuliaLang/julia/blob/6d7a50b880fe2189b1efa34eb47d4dfeb181b674/test/perf/arrayalloc/lucompletepiv.jl#L39 بمكالمة إلى BLAS.syrk2! ؟

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

timholy سيكون أسرع ، لكن الهدف من المعيار هو أنه يخصص syrk2 .

ViralBShah لقد فسرت تعليق timholy على أنه دعوة لمزيد من الموارد (أي القوى العاملة) لهذه المشكلة لأن المطورين الذين يعتزمون القيام بالعمل على هذا قد انتقلوا لكن ربما أساءت الفهم ، أو ربما تطوع أشخاص جدد بالفعل لتولي المسؤولية.

tknopp ليس نقص المشاهدات من [] هو ما يمنع الناس من استخدام جوليا ، بل هو توقع حدوث تغييرات كبيرة قادمة من 1-2 إصدار لاحقًا. على الأقل أنا محاط بأشخاص ستكون جوليا مثالية لهم ، لكنهم ببساطة ليسوا على استعداد لاستخدام لغة قد يضطرون فيها إلى تحديث الكود الخاص بهم حتى يظل يعمل بشكل صحيح في إصدار جوليا التالي.

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

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

ببساطة لا يرغبون في استخدام لغة قد يضطرون فيها إلى تحديث كودهم بحيث يستمر تشغيله بشكل صحيح في إصدار جوليا التالي.

هل هذا لأنهم لن يستخدموا أي لغة قبل الإصدار 1.0 ، أو أنهم سمعوا على وجه التحديد أنه سيتم قريبًا كسر تغييرات في المصفوفة (وبعد ذلك سيستخدمون جوليا)؟

hayd لست متأكدًا بنسبة 100٪ ، لكن عناصر المصفوفة التي أعتقد أنها مخيفة بشكل خاص للأشخاص لأنها تؤثر على الكثير من التعليمات البرمجية (على الرغم من أنني أعتقد أن فهرسة نمط APL الموجودة بالفعل على المستوى الرئيسي أكثر من طريقة العرض / النسخ ).

هل يستخدم NumPy و Julia نفس تقنية BLAS هنا؟ يمكنني الحصول على تسريع كبير (> 1/3) لحالة مصفوفة بحجم 1000 عن طريق استدعاء Base.disable_threaded_libs() .

@ davidanthoff :
إذا كان هذا مصدر قلق ، فربما تكون جوليا صغيرة جدًا بالنسبة لهؤلاء الأشخاص. من وجهة نظري ، لم يكن عدد التغييرات التي طرأت على اللغة الأساسية على مدى السنوات الثلاث الماضية بهذا الحجم.
هناك بالطبع لغات مستقرة جدًا ، لكن إذا فكرت في C ++ 11 أو Python3 ، فهناك تغييرات كبيرة في اللغات الناضجة.

davidanthoff ، نعم ، إنها دعوة لمزيد من الأشخاص للمساهمة في هذا الجهد --- ربما لم يتم "الانتهاء" من المساهمين السابقين (أنا لست كذلك) ، ولكن القائمة طويلة والأفراد لديهم أولويات متعددة.

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

فيما يتعلق بإزالة فحص الحدود على وجه التحديد: العروض الحالية سريعة جدًا ، لكنها غير آمنة نظرًا لعدم وجود تدقيق في الحدود. من أجل جعلها قابلة للاستخدام بشكل عام ، نحتاج إلى _add_ فحص الحدود ، ولكن حتى يتم دمج عمل

andreasnoack ، هل يمكنك فتح مشكلة منفصلة حول معيار lu الخاص بك؟ هناك المزيد للمناقشة ، لكنني أعتقد أنه يصرف الانتباه عن القضايا الأكبر هنا.

ماذا عن السماح للحقول في الأنواع المجردة (https://github.com/JuliaLang/julia/issues/4935) بأي شيء جديد في هذا الاتجاه؟

ماذا عن سرقة بناء الجملة {} من أنواع tuple المخطط لها ولديك A{:, 1} لإنشاء عرض بينما لا يزال A[:, 1] ينشئ نسخة؟

اقترح JeffBezanson A@[:,1] للمشاهدات و A[:,1] للنسخ أيضًا.

سؤال ساذج لماذا لا يكون A [:، 1] طريقة عرض بشكل افتراضي وإذا كنت تريد نسخة تسميها "نسخة" في العرض؟

لجعل هذا مقتضبًا في استخدام ذي صلة ، قمنا بزيادة التحميل على "*" على سبيل المثال * (A [: ، 1]) - إذا كانت أحادية * في المحلل اللغوي ، فسيصبح هذا مقتضبًا * A [: ، 1]. لا أدافع بقوة عن استخدام * لكنه يرسم في ذهني استخدام لغة سي.

ما زلت في صالح. لدى JeffBezanson بعض التحفظات حول ذلك -

هناك نوعان من القضايا الرئيسية مع وجهات النظر بشكل افتراضي IMO

1) إنه تغيير فاصل ، وهو أحد أسوأ أنواع التغيير لأنه يقدم أخطاء التعرّف (بشكل أساسي ، بخلاف إيقاف فهرسة النطاق لإصدار كامل ، سيتعين عليك تدقيق كل جزء من التعليمات البرمجية التي تستخدمه)

2) العناصر الثابتة التي تحتوي على مراجع جوليا غير فعالة تمامًا في الوقت الحالي ، لذا إذا بدأ الأشخاص في استخدام طرق العرض للراحة (أي لتجنب الحوسبة اليدوية للمؤشرات) فمن المحتمل أن يروا تراجعًا في الأداء

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

تحرير: بالتفكير في الأمر ، قد يكون الانتقال الأقل إزعاجًا لـ (1) هو إعادة عروض القراءة فقط للإصدار ، وتجنب بعض أخطاء التعرّف (ولكن ليس تلك التي تكتب فيها في المصفوفة الأصلية) ، وتمكين الكتابة من خلال عرض لاحقًا

بينما أقدّر الجهود المبذولة لتقليل التغييرات المتقطعة و / أو توفير مسارات الإيقاف ... قبل الإصدار 1.0 ، ألا يجب أن نكون على استعداد لكسر بعض الأشياء؟

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

بشكل عام ، أنا أؤيد كسر الأشياء قبل الإصدار 1.0 ، ولكن لا يبدو أن هذه حالة يكون فيها من الواضح أن السلوك الجديد هو فوز مؤكد.

لاتخاذ هذا على الأقل بضع خطوات أخرى إلى الأمام ، ما هي المرشحين المحتملين لبناء الجملة لطرق عرض المصفوفة؟

هناك شيء مثير للاهتمام حول بناء الجملة A@[:,1] ، من حيث أنه يقرأ A at the location of the following indices .

هناك شيء مثير للاهتمام حول بناء الجملة A @ [:، 1] ، من حيث أنه يقرأ A في موقع الفهارس التالية.

متفق عليه ، يبدو بديهيًا بشكل مدهش.

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

رأيي (ba-ding!) في A@[:,1] هو أنه من المحير إدخال رمز الماكرو @ في سياق مختلف تمامًا.

هذا هو رد فعلي الأول ، لكني تجاوزته للأسباب التي كتبتها أعلاه.

ولكن بالمثل ، فإن {} يقدم شيئًا يشبه النوع في سياق مختلف تمامًا.

رأي (أ ،: ، 1)؟

kkmann : تحتاج طرق العرض إلى صيغة خاصة حتى تعمل ميزات مثل end .

A@[:,1] لديه إمكانات. +1 لاختباره.

أنا أزعم أنك في معظم الحالات تريد المشاهدات وفقط في بعض الأحيان تريد نسخًا. سيكون هناك عدد كبير من سلاسل الرسائل حول التعليمات البرمجية التي تعمل ببطء والتي ستكون الإجابة عليها "تخلص من الكود الخاص بك مع Array @ [...]" ألا يمكن أن تكون عروض الصفيف ثابتة بشكل افتراضي؟ ثم سيكون عليك أن تطلب صراحة عرضًا متغيرًا.

وجهات النظر الثابتة بشكل افتراضي فكرة مثيرة للاهتمام. قد يكون بناء الجملة A@[...] هو الحصول على عرض قابل للتغيير و copy(A[...]) سيكون كيفية الحصول على شريحة غير مرئية.

نظرًا لعدم إهمال فهرسة النطاق لإصدار كامل ، سيتعين عليك تدقيق كل جزء من التعليمات البرمجية التي تستخدمها

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

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

@ mauro3 ، ليست كل الأخطاء المحتملة.

من @ كارنافال :

تحرير: بالتفكير في الأمر ، قد يكون الانتقال الأقل إزعاجًا لـ (1) هو إعادة عروض القراءة فقط للإصدار ، وتجنب بعض أخطاء التعرّف ( ولكن ليس تلك التي تكتب فيها في المصفوفة الأصلية ) ، وتمكين الكتابة من خلال عرض لاحقًا

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

لا تزال طرق العرض بشكل افتراضي تبدو وكأنها الخيار الصحيح على المدى الطويل بالنسبة لي. قد تكون الطريقة الأقل خطورة للوصول إلى هناك انتقال عبر طرق العرض للقراءة فقط بشكل افتراضي.

+1 لفترة انتقالية للعرض الثابت متبوعة بالعرض القابل للتغيير

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

ماذا عن وسيطة / تعليمات لجعل جميع المحاولات لتغيير طريقة عرض تثير خطأ لأغراض التصحيح؟ على أي حال ، يحتاج الأشخاص إلى المرور بمرحلة النقل لدعم إصدار Julia الجديد: يمكنهم تشغيل الكود الخاص بهم مرة واحدة باستخدام هذا العلم لتحديد الحالات الإشكالية ، ويكونوا آمنين بعد ذلك.

أنا أصوت فقط لعمل وجهات النظر بشكل افتراضي. من وجهة نظري ، هذا يتوافق تمامًا مع السلوك الحالي لـ setindex!

julia> a= zeros(3,3)
3x3 Array{Float64,2}:
 0.0  0.0  0.0
 0.0  0.0  0.0
 0.0  0.0  0.0

julia> a[:,1] = 1
1

julia> println(a)
[1.0 0.0 0.0
 1.0 0.0 0.0
 1.0 0.0 0.0]

هذا السلوك غير متسق مع الحالة حيث يكون a[:,1] قيمة R ويتم نسخها بصمت. لذلك أنا أيضًا ضد جعل الآراء غير قابلة للتغيير (والتي لن تكون مماثلة لنوع غير قابل للتغيير بالمناسبة).

بالطبع كل هذا قرار تصميم وهناك إيجابيات وسلبيات. لكن دعنا نقرر هذا مبكرًا ولا نؤجله لإصدار آخر.

johnmyleswhite ، أعتقد أن عدم تقديم المشاهدات بشكل افتراضي (ولكن مع الاستمرار في تسهيل الوصول إليها بشيء مثل A@[...] ) لن يكون خيانة للثقة. قد تكون هناك أسباب وجيهة لعدم جعل الفهرسة قابلة للتغيير بشكل افتراضي.

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

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

سيكون من المثير للاهتمام أيضًا مقدار الكود الذي يكسر حقًا. لقد أجرينا مناقشات كبيرة مفادها أن Int8+Int8 -> Int8 سيؤدي إلى كسر الكثير من التعليمات البرمجية ولكن في النهاية حدث التغيير ولم يكن هناك كسر كبير.

kmsquire : تعدد العمليات في رأيي متعامد تمامًا مع هذه الميزة. نعم ، هناك سيناريوهات قد يكون من المنطقي فيها نسخ البيانات في التعليمات البرمجية ذات مؤشرات الترابط بحيث يكون لكل مؤشر ترابط نسخته الخاصة ولكن عادةً ما يتم ذلك عن طريق تقسيم المصفوفة والعمل على أجزاء من هذه المجموعة. وهذا بالضبط سيتطلب وجهات نظر. لا أحد يريد أن يبدأ مجموعة من سلاسل الرسائل لنسخ التعليمات البرمجية (وهو ما يفعله حاليًا [: ،:]) في حلقة "ساخنة".

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

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

ليس لدي وجهة نظر قوية حول الحل النهائي الذي يجب أن يكون عليه ، يمكنني بسهولة التعايش مع أي من الاقتراحات المقدمة هنا.

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

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

ولكن بالإضافة إلى نقاط carnaval أعلاه ، هناك نقطة ثالثة مقابل وجهات النظر بشكل افتراضي وهي أنها لن تكون دائمًا فوزًا في الأداء حتى لو تم تنفيذها بكفاءة. حتى في حالات مثل فهرسة متجه بـ Vector{Int} ، إذا تم اجتياز المصفوفة مرات كافية ، فمن المحتمل أن يكون إنشاء نسخة أسرع. يبدو من الصعب إجراء عرض لمصفوفة متفرقة مع متجه من الأعداد الصحيحة مثل الصفوف في أي مكان قريب من سرعة النسخة لمعظم العمليات. بالنظر إلى أن ما إذا كان العرض مفضلًا على نسخة يعتمد على ما يتم فهرسته وما يتم عمله به ، أعتقد أنه يجب أن تكون هناك طرق سهلة للقيام بأي منهما.

بالنظر إلى أن ما إذا كان العرض مفضلًا على نسخة يعتمد على ما يتم فهرسته وما يتم عمله به ، أعتقد أنه يجب أن تكون هناك طرق سهلة للقيام بأي منهما.

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

أراهن أن لا أحد يريد الفهرسة العددية لإرجاع طريقة عرض ، ولا يبدو أنها قابلة للتنفيذ بكفاءة. ولكن مع بناء جملة منفصل ، يمكن أن نحصل على ذلك ، على سبيل المثال ، يعطي A@[1,1] طريقة عرض 0-d يمكن الكتابة إليها باستخدام v[] = x .

أعتقد أنه قد قيل بالفعل من قبل ، ولكن هناك العديد من الحالات مثل المصفوفات المتفرقة ، والمصفوفات الموزعة ، وهياكل بيانات المصفوفات الأساسية ، حيث تكون طرق عرض المصفوفات افتراضيًا إما ليست فكرة جيدة أو يصعب الأداء الجيد عليها.

تسمح الصيغة المقترحة لطرق عرض المصفوفات باستخدام طرق العرض عندما أريدها ، والاحتفاظ بالتعليمة البرمجية الحالية كما هي بدون كسر - كل ذلك مع إضافة / حذف حرف واحد.

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

هل يستحق الأمر جمع بعض المعايير ، ونحن نواصل هذا التغيير؟ قد يكون هذا أمرًا جيدًا بشكل عام.

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

آسف للتناغم في وقت متأخر هنا.

eschnett ،

سيكون من الجيد أن يكون لديك بناء جملة يمنحك دائمًا عرضًا ، ويعمل بشكل مماثل في كل من 0.4 و 0.5.

لدينا بالفعل هذا: الوظيفتان slice و sub .

johnmyleswhite ،

خيانة جوهرية للثقة

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

أيضًا ، ظهر بعضنا بشكل دوري على القائمة البريدية ليقول "لا داعي لانتظار Arraypocalypse ، لدينا وجهات نظر فعالة الآن. ما هو سبب التوقف عن بناء الجملة ، على أي حال؟" لذلك على الأقل وجهة النظر هذه ، التي تم تبنيها عدة مرات خلال العام الماضي ، متوافقة نسبيًا مع الاتجاه الذي تتحرك فيه هذه المحادثة.

JeffBezanson ،

أعتقد أنه من الصعب للغاية التعهد بأن الفهرسة ستعيد دائمًا إشارة إلى البيانات الأساسية بدلاً من النسخ.

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

لدي بعض التذكر الغامض لبعض أقواس الأحرف التي تم اقتراحها للإضافة إلى القاعدة (تم العثور عليها - # 8892). أشياء مثل [| ... |] ، {| ... |} ، إلخ. ألا يمكننا أخذ أحد هذه الأشياء لإنشاء عرض؟ أعتقد أن الأول يمكن أن يعمل بشكل جيد دون إدخال استخدام @ وهذا لا يعني الماكرو.

اقتراحي هو:

  • @ محجوز لوحدات الماكرو
  • { } محجوز لأنواع tuple
  • x[1,:] يعني الفهرس وإنشاء نسخة
  • x[|1,:|] يعني الفهرس وإنشاء طريقة عرض

بقدر ما أستطيع أن أقول أن بناء الجملة هذا مجاني ( | ليس عامل تشغيل وحيد) ومن غير المرجح أن يفاجئ الناس. الجانب السلبي هو أن كتابة [| و |] من [ و ] يتطلب المزيد من العمل.

A@[1,:] أكثر سهولة في العرض من x[|1,:|] . أنا شخصياً لا أشعر بأي ارتباك مع بناء الجملة الكلي.

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

+1 لـ A@[1,:]

يجب أن يصبح سلوك الفهرسة الحالي (الذي يولد الكثير من المؤقتات) أسرع حيث يمكننا القيام بتحليل أفضل للهروب وإعادة استخدام الذاكرة.

أي تخمين ما هي المكاسب التي يمكن تحقيقها من خلال هذا النوع من الأشياء؟

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

في التعليق الذي يفيد بأن @ محجوز حاليًا لوحدات الماكرو ، أود أن أشير أيضًا إلى أن Julia _ بالفعل _ لديها رمزان محددان (أو مستخدمان بشكل اصطلاحي) لتغيير سلوك المشغلين والوظائف (وما زلت أتحدث عن [] كمعامل ، _a la_ C ++). هذه هي الرموز . و ! ، وأنا قلق من إضافة رمز @ ثالث إلى المزيج الذي يضيف الارتباك (ربما غير ضروري).

هل اعتبر الأشخاص A.[1,:] أو حتى A![1,:] أو A[1,:]! بناء جملة ممكن؟ أي تغيير عامل التشغيل [] إلى .[] أو []! ؟ حدسيًا ، يمكن تفسير الأول على أنه فهرسة من حيث العناصر (والتي يمكن القول إنها يمكن أن تُفسَّر على أنها فرض نسخة ؟؟) والأخير نوع من الفهرسة المتغيرة (التي تبدو مشابهة لروح الآراء ، حيث يؤدي تغيير وجهة النظر الناتجة إلى حدوث طفرات إلى المصفوفة الأصلية).

A![1,:] هو بناء جملة صالح بالفعل للفهرسة في مصفوفة تسمى A! . الصيغ الأخرى متوفرة.

علاوة على ذلك ، لا يزال من الممكن إتاحة @[] لتعريف عمل السحر الشبيه بالماكرو مع المؤشرات (أفكر في شيء على غرار TensorOperations.jl ، هنا ، ربما حتى Devectorize .. . فقط التخمين هنا)

StefanKarpinski نعم ، فكرت في ذلك بعد ، []! هو الأكثر منطقية بالنسبة لي شخصيًا.

راجع https://github.com/JuliaLang/julia/issues/7721#issuecomment -170942938 للحصول على اقتراح مشابه من الناحية التركيبية يجب وضعه في الاعتبار هنا: f(x)! للاتصال بـ f(x) وإنهاء النتيجة تلقائيًا على خروج النطاق.

لا أحب حقًا استخدام ! لأي شيء باستثناء عمليات التحوير. على سبيل المثال ، تم اقتراح reshape! لإعادة تشكيل مشاركة البيانات. أعتقد أن هذا يخلق الكثير من الالتباس حول ما يعنيه ! . أخذ وجهة نظر لا يتغير ؛ في الواقع ، إنه يعمل بشكل جيد في البرامج التي لا تستخدم الطفرات مطلقًا!

( JeffBezanson : هل يتضمن ذلك معارضة بناء الجملة f(x)! المقترح في # 7721؟)

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

لا يزعجني f(x)! من # 7721 كثيرًا ، ربما لأنه يتضمن أيضًا آثارًا جانبية من نوع ما ، في حين أن إعادة عرض مصفوفة هي مجرد وظيفة خالصة.

حسنًا ، ماذا عن العامل الآخر ، .[] ؟ أستطيع أن أرى بديلين:

في عالم يعرض فيه [] طريقة عرض (عند تحديده ، e ، g. Array ، أو نسخة حيث يكون ذلك أكثر منطقية) ، قد يكون .[] مناسبًا لـ _force_ نسخة. بالطبع ، كما تمت مناقشته ، يجعل من الصعب التنبؤ بما ستحصل عليه من [] .

أو ربما يمكن اعتبار .[] بديلاً عن @[] للمشاهدات ، في حال بدا ذلك بديهيًا لأي شخص؟ كيف سيفسر الناس "فهرسة العناصر"؟

كيف سيفسر الناس "فهرسة العناصر"؟

الفهرسة النقطية هي أحد الاحتمالات. سيعيد A.[1:3,1:3] العناصر الثلاثة الأولى على طول القطر. # 2591

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

حسنًا ، أوافق ، # 2591 أكثر منطقية لـ .[]

+1 لـ A@[1,:]

أعتقد أيضًا أن امتلاك القدرة على جعل مصفوفة غير قابلة للتغيير بشكل مؤقت ستكون مفيدة جدًا لتعقب الأخطاء حيث يتم تغيير المصفوفة ولا يمكنك معرفة السبب (أو فقط للتحقق من عدم تغييرها أثناء وجودها داخل دالة). هذا ليس بالضرورة أن يكون جزءًا من slice لكن يمكن أن يكون كذلك. هل هناك طريقة لفعل ذلك الآن؟

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

سيكون من الرائع تمامًا رؤية شخص ما يلتقط الشعلة هنا ويطلق النار للحصول على بعض الأرقام الأولية باستخدام البنية التحتية القياسية CI.

andyferris ألا تحتاج أسماء الماكرو دائمًا إلى معرفات (على الأقل الآن)؟ أعتقد أنه سيتعين القيام بعمل خاص للسماح باستخدام أحرف مثل [ أو ( أو { كأسماء ماكرو ، وللتعامل مع الحرف الختامي المقابل بشكل صحيح .
أعتقد أن بناء الجملة A[ind]! قد يكون غامضًا. على سبيل المثال ، ماذا يعني A[ind]!=5 ؟
أعتقد أن بناء الجملة المقترح f(x)! قد يواجه أيضًا مشاكل الغموض أيضًا. (نعم ، قد تحتاج إلى مسافة بين ! و = ، لكن هذا قد يبدو محيرًا)

ماذا عن <strong i="5">@view</strong> A[1,:] ببساطة؟ (انظر https://github.com/JuliaLang/ArrayViews.jl/pull/14)

أعتقد أن هذا مطول جدًا عندما تريد استخدام جميع طرق العرض في خوارزمية على سبيل المثال.

لا يمكن تحديد نطاق ماكرو @view ليحل محل getindex داخل كتلة begin ... end بالكامل؟

لا ارى لماذا لا

شيء آخر يجب مراعاته إذا قدمنا ​​بنية جديدة لطرق العرض (على سبيل المثال ، @[...] ): ما هو المتغير المقابل setindex!

A@[1,:] = x

فعل؟ نظرًا لأنه يبدو من غير الواضح نوعًا ما ، فقد يكون من الأفضل عدم السماح بذلك ، ولكن بعد ذلك سيتعين عليك تذكر استبعاد @ عند قيامك بالمهمة.

فكرة رائعةtkelman ، تجعلها مشابهة لـ @inbounds .

ليس بالضبط: @inbounds أكثر سحرية قليلاً (انظر https://github.com/JuliaLang/julia/blob/9bfd27bd380124174a5f37c342e5c048874d71a4/test/boundscheck.jl). سيكون هذا تحويلًا بسيطًا في بناء الجملة.

مماثلة في الاستخدام لا التنفيذ إذن. على أي حال ، أنا أحب ذلك: P

لكن مشكلة في حالة الاستخدام هذه: A مصفوفة متفرقة (لذلك لنفترض أن النسخ أسرع من إنشاء عرض) ، B كثيف وله طرق عرض سريعة. ما الذي يجب أن يفعله <strong i="7">@view</strong> c += A[1:10,2:15]*B[:,j] ؟

تعذرت كتابة شيء مثل c += A[1:10,2:15]*(<strong i="5">@view</strong> B[:,j]) حيث يعمل @view فقط على ما يوجد داخل الأقواس. لا أعرف ما يكفي عن الماكرو لمعرفة ما إذا كان ذلك ممكنًا.

لكن ربما يخسر الإسهاب الآن ..

أعتقد أن وجود كلا اللغتين سيكون أفضل. ثم استخدم A2@[] إذا كان التحكم الدقيق ضروريًا. (تحرير: تمت إضافة @ )

KristofferC ، نعم ، هذا

ومع ذلك ، أنا أحب ذلك بشكل عام. لاحظ أن التنفيذ بسيط للغاية: يتعلق الأمر باستبدال Expr(:ref, :A, args...) بـ Expr(:call, :slice, :A, args...) (على الرغم من أنه يتعين عليك أيضًا البحث عن end واستبداله يدويًا).

لا أمانع على الأقل في تجربة @view على الماجستير لبعض الوقت ورؤية كيف يبدو الأمر قبل أن نفعل A@[] .

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

A@[] يسير في اتجاه perl sigil لكونه من الصعب قراءته وفهمه للمستخدمين الجدد. على الأقل يوضح الماكرو أو الوظيفة ما يفعلونه ...

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

إن تقديم صيغتين له مزايا ، لكنه لا يحل جميع حالات الاستخدام. يمكنني بالفعل رؤية ثلاثة منهم:
1) تريد نسخة يمكن تعديلها دون التأثير على المصفوفة الأصلية -> [] .
2) تريد طريقة عرض لتعديل المصفوفة الأصلية -> @[]
3) تريد الطريقة الأسرع / الأرخص لاستخراج مجموعة فرعية من المصفوفة ، لكن لا تحتاج إلى تعديلها. تفضل عرضًا (ربما غير قابل للتغيير) لمجموعات أنواع الفهرس / الصفيف حيث يكون أسرع ، ونسخة في مكان آخر. هذا مشابه لاستخدام eachindex(a) بدلاً من 1:length(a) عند التكرار على مصفوفة. -> لا يوجد بناء جملة مقترح

إن تقديم ثلاث تراكيب هو أمر مبالغ فيه بعض الشيء ... ولكن يبدو لي أن معظم المكاسب التي نتوقعها (محرر) من استخدام طرق العرض بشكل افتراضي تتوافق مع الحالة 3.

لذلك أتفق مع tkelman على أن مسألة ما إذا كان من الممكن جعل وجهات النظر فعالة لجميع أنواع القواعد تستحق التحقيق: فهي ستسمح فعليًا بدمج الحالتين 2 و 3 ، وربما تسرق صياغة الحالة 1 (أي وجهات النظر افتراضيًا). مع بناء جملة المولد المعمم والوظائف المجهولة السريعة ، تبدو المشاهدات كميزة رائعة لتجنب التخصيصات وضمان الأداء العالي.

مشكلة واحدة في استخدام @view لالتفاف التعبيرات / الكتل: ماذا لو كان لدي قالب ملفوف في @view وأحتاج إلى إضافة نسخة فهرسة بالداخل؟ ثم سأضطر إلى كسر الكتلة بأكملها. ماذا لو لم ألاحظ؟ ماذا لو قمت بلصق كود في تلك الكتلة؟ سأشعر بتحسن كبير إذا كان إلقاء نظرة أم لا سيعتمد فقط على العملية ، وليس سياق الكود المحيط.

لما يستحق:

أتعامل كثيرًا مع وجهات النظر في التعلم الآلي. تدور العديد من الخوارزميات حول ملاحظات بعض مجموعات البيانات ، والتي يتم تمثيلها في كثير من الأحيان على أنها مصفوفة. في حالات مثل SVMs ، لا يمكن للمرء صياغة هذا من حيث مضاعفات المصفوفة ، ولكن بدلاً من ذلك يحتاج إلى التظاهر بأن كل ملاحظة عبارة عن ناقل. في هذه الحالات ، سيكون التركيب البسيط القابل للقراءة موضع تقدير ، لأنني أهدف إلى رمز زائف يشبه التطبيقات. لا أعتقد أن A@[1,:] محير على الإطلاق ؛ حتى أنه يقرأ "A at [1 ،:]".

أتفق مع toivoh على أن استخدام @view يبدو أنه يجبر المرء على الاختيار بين استخدام المشاهدات فقط أو المزيد من الخداع المطول. يشعر @inbounds بقطع أكثر وضوحًا في هذا الصدد

هل سيعمل view(arr, dims) و view!(arr, dims) لإرجاع طريقة عرض ثابتة ومتغيرة على التوالي؟
سيسمح ذلك بتحديد المعلمات بناءً على ما إذا كانت arr كثيفة أم متفرقة أم شيء آخر تمامًا ، أليس كذلك؟

tkelman في A@[x,y] ، لماذا يكون @ a sigil؟ قرأت @[] كمعامل ، بدلاً من @ كعنصر سيجيل مرتبط بـ A .

إنه عامل ذو مظهر مضحك ليس لديه الكثير من السوابق. لا يبدو أن الحاجة إلى تتبع بناء الجملة لأنواع مختلفة من الفهرسة أمر مثالي. إنه يشبه إلى حد ما كيف أن الصدأ له أنواع مختلفة من المؤشرات (وكان يحتوي على المزيد) ، فهو ليس بديهيًا ويتعين عليك تتبعه كثيرًا عند محاولة قراءة التعليمات البرمجية لأول مرة. من المحتمل أن أعيش مع A@[] لكن هذا يشعرني بالرضا.

تحرير: إذا كانت العروض افتراضية ومبنية بشكل كسول ، فعندئذٍ يأمل المرء أن يكون copy(A[1,:]) مكافئًا تمامًا لنسخ اليوم A[1,:] لكنني لست متأكدًا من مدى قربنا عمليًا باستخدام مترجم اليوم.

تحرير 2: أعتقد أن @[] جيد أو أفضل من أي من عروض "نوعي الأقواس" الأخرى. البديل من وجهة نظري هو جعل [] دائمًا طريقة عرض (للقراءة فقط من أجل انتقال الإصدار) واستدعاء copy على تعبير فهرسة للحصول على سلوك مكافئ لليوم. سأبحث في فرع

إذا نظرنا إلى السابقة ، يمكن أن يكون A(1,:) دائمًا نسخة ، نظرًا لأن هذا ما هو موجود في matlab AFAIK ، و A[1,:] دائمًا ما يتم عرضه كما هو الحال تقريبًا في NumPy. أعتقد أن () فكرة سيئة ، مجرد طرحها في العصف الذهني. أنا أيضًا لا أحب A@[1,:] .

إذا كان الاعتراض الرئيسي على @view هو كيفية التعامل مع الحالات الاستثنائية (على سبيل المثال ، نسخة داخل كتلة @view أو عرض عادي) ، فهل يمكن للأشخاص استخدام sub / slice في الحالة الأخيرة ، وربما نضيف طرقًا إلى الوظيفة copy التي تتعامل مع السابق؟ في الوقت الحالي ، لا يبدو أن copy لديه أي طرق متعددة الوسائط ، لذلك يمكن أن يكون اسمًا أقصر لما يفعله getindex الآن.

لذا فإن copy(A, idx...) يمنحك دائمًا نسخة ، و sub(A, idx...) دائمًا ما يعطي عرضًا ، و A[idx...] سيُنسخ بشكل افتراضي ولكن يمكن تغليفه بـ @view للتغيير السلوك (أو العرض افتراضيًا باستخدام ماكرو @copy لتغيير السلوك ، IDK أيهما أفضل)

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

timholy التنفيذ ليس بهذه البساطة ، لأنه إذا قمت ببساطة باستبدال :ref Exprs ، فإن <strong i="7">@view</strong> X[:, 1] += 2 سيصبح slice(X, :, 1) += 2 . أعتقد أنه يمكنك استخدام قرص المحلل اللغوي custom_ref من # 8227 للحصول على السلوك المطلوب بما في ذلك end ، رغم ذلك.

ssfrr أعتقد أن @view قد يكون على الأقل غامضًا مثل @[] عند إعادة بناء الكود. سيضع الأشخاص المختلفون بلا شك @view حول كتل بأحجام مختلفة ، وربما يضعها بعض الأشخاص حول ملفات كاملة.

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

لست متأكدًا مما إذا كان هناك اهتمام؟

يوم الجمعة ، 29 يناير 2016 ، Simon Kornblith [email protected]
كتب:

timholy https://github.com/timholy التنفيذ ليس تمامًا
بهذه البساطة ، لأنك إذا استبدلت ببساطة: ref Exprs ثم view X [:، 1]
+ = 2 ستصبح شريحة (X،:، 1) + = 2. أعتقد أنه يمكنك استخدام custom_ref
قرص المحلل اللغوي من # 8227 https://github.com/JuliaLang/julia/pull/8227 إلى
الحصول على السلوك المطلوب بما في ذلك النهاية.

ssfrr https://github.com/ssfrr أعتقد أن view يمكن أن يكون على الأقل كـ
غامضة مثل @ [] عند إعادة بناء التعليمات البرمجية. الناس المختلفين سوف بلا شك
ضع @ view حول كتل بأحجام مختلفة ، وربما بعض الأشخاص
حتى وضعه حول ملفات كاملة.

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/13157#issuecomment -176787527.

cartazio أنا مهتم بإعادة النظر في مناقشات التصميم تلك ورؤية ما يمكن تكييفه في نظام نوع Julia ، ولكن هذه المشكلة تطول جدًا وقد يكون من الأفضل نقل بعض أجزاء هذه المناقشة إلى مشكلاتها المنفصلة أو القائمة البريدية / المباشرة مواضيع البريد الإلكتروني.

إذا كنت تعتبر A[1,:] بمثابة عقرب مختصر لإنشاء "نسخ نوع الشريحة" الذي يتم تطبيقه على طريقة الاستدعاء - A( copy_slice(1, :) )

هل سيكون من غير المعقول أن يكون عرض قابل للتغيير A( view_slice( 1, : ) ) ؟

إن إضافة بناء جملة لإنشاء copy_slice و view_slice مباشرة يجعل هذا أسهل في الاستخدام في السطر. هذا مشابه جدًا لمنشئي النطاق الحاليين

1:3 -> UnitRange{Int64}

يعمل هذا بشكل أساسي اليوم إذا أكدنا أن "view_slice هو اسم مستعار لـ tuple (للأسف هذا هو عكس NumPy / matlab) ولكن لديك خيار أن تكون واضحًا وصريحًا

1,:,1:2 -> (1,Colon(),1:2)

وبالتالي

A( 1,: ) -> A( view_slice( 1,: ))

هل هذا الإسهاب في الكتابة

A( view( 1, : ) )

هذا يسمح أيضًا بالامتداد إلى وجهات النظر الثابتة

A( immutable_view( 1,: ) )

يمكنك تنفيذ هذا اليوم بدون تغييرات المحلل اللغوي (ومن المحتمل بطريقة متوافقة مع الإصدارات السابقة ، إرسال إلى getindex وآخرون) باستثناء دعم end .

إذا تم تعديل المحلل اللغوي ليحل محل end أجل: النهاية بالشكل المختصر العام للنقطتين يمكننا الاعتماد على الإرسال للقيام بالشيء الصحيح.

1:end -> 1 : :end -> colon( ::Int64, ::Symbol )

[تحرير: على الرغم من أنني أفضل النوع {End}]

قبل القلق بشأن بناء الجملة ، أود حقًا رؤية المزيد من الجهود الهندسية في وجهات النظر وإلقاء نظرة فاحصة على مقايضات الأداء. أحد الأشياء التي قد تكون مساعدة كبيرة وميكانيكية إلى حد ما هو تحديث طرق فهرسة SubArray لاستخدام المصطلح الجديد الرائع <strong i="5">@boundscheck</strong> checkbounds(A, I...) . (بشكل عام ، يمكن استبدال جميع استخدامات unsafe_getindex بـ <strong i="8">@inbounds</strong> A[...] ، وإزالة كافة تعريفات الطرق الخاصة به.)

nalimilan كتب:

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

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

ثم هناك مشكلة فئة التعقيد للمصفوفات المتخصصة. ليس من المكلف إنشاء مناظر متفرقة ، على سبيل المثال ، ولكن المشكلة معها هي أن المصفوفات الفرعية التي تم إرجاعها لم تعد تصل إلى الهياكل المتفرقة المتخصصة. لذا فإن sum(slice(S, :, 1) يصل إلى الارتداد المجرد ولم يعد O (nnz).

mdcfrancis - أحد أقوى استخدامات الكلمة الرئيسية end هو استخدامها في الحساب ، على سبيل المثال ، A[(end+1) ÷ 2] أو A[mod1(x, end)] .

-1 لـ A @ []

يبدو الأمر أشبه بتقديم سياقات Perl ، ويشير الرمز @ إلى وجود وحدات ماكرو متضمنة. تعجبني فكرة A [| x ، y |] ، أو أي نوع آخر من الروايات.

أعتقد أن ما يبحث عنه الناس ليس "مشاهدات بشكل افتراضي" ، ولكن تضييق فرق الأداء بين المعايير التي يعرضها https://github.com/JuliaLang/julia/issues/13157#issuecomment -168378436. سيكون من الجيد أن يقوم السلوك الافتراضي بذلك ، لكن التعديل السهل الذي يمكن للمرء أن يجده في قسم نصائح الأداء يكون جيدًا تقريبًا.

mbauman - اجعل نوع الحارس النهائي يعمل كرقم. ثم يتم تمرير شجرة التعبير إلى طريقة الاستدعاء ويمكن تقييمها بطول المصفوفة؟

END + 1 -> EndExpr( length(A))

@ mauro3 قام ببعض العمل على ذلك في حزمة مصفوفة خشنة . انها ليست سهلة.

-1 مقابل A@[] . هل A[[index]] متاح لبناء الجملة؟ من شأنه أن يسمى شيء مثل getindexview(A, index) ؟ أعتقد أن هذا يعبر عن أننا نحصل على مستوى من المراوغة يناسب وجهة النظر.

GlenHertz هذا يعني بالفعل شيئًا:

julia> a = ["pablo","martín","garcía"] ; a[[1,2]]
2-element Array{UTF8String,1}:
 "pablo" 
 "martín"

كتب @ lucasb-eyer:

إذا نظرنا إلى السابقة ، يمكن أن تكون A (1، :) نسخة دائمًا ، نظرًا لأن هذا ما هو موجود في matlab AFAIK ، و A [1 ،:] دائمًا ما يتم عرضها كما هو الحال تقريبًا في NumPy. أعتقد أن () فكرة سيئة ، فقط ألقي بها في العصف الذهني. أنا أيضًا لا أحب A @ [1 ،:].

يبدو لي أن هذا الاقتراح المتعلق بالنسخ () للنسخ و [] للمشاهدات هو الحل الأكثر إيجازًا وقد يكون الأكثر سهولة للمستخدمين الجدد من MATLAB و Python (سيزيد من مقدار التشغيل القابل للتشغيل كود MATLAB). يبدو نوعًا ما "صحيحًا" أن C-like [] يقوم بعمل مؤشر وأن () يؤدي وظيفة لإرجاع كائن جديد (ومن الطبيعي أنه ليس له معنى في اليد اليسرى -side ... لكن علينا إضافة تحذير لتجنب الأخطاء المنطقية هنا). بشكل عام ، أنا أحب ذلك.

للأسف نفقد القدرة على استخدام call لكائنات تشبه المصفوفة ...

يؤدي استخدام () للفهرسة إلى القضاء على الميزة الرئيسية لوجود بناء جملة للفهرسة - أي السماح لأشياء مثل end بالعمل.

إنها طريقة خاطئة لإخبار الجميع أولاً بتبديل جميع الفهرسة الخاصة بهم لاستخدام ( ) ، ثم في المستقبل استخدم [ ] للمشاهدات عندما تريدهم.

سيكون الشيء الحقيقي الذي يشبه C هو استخدام &A[x,y] للمشاهدات ، والذي يعد حاليًا خطأ في بناء الجملة وبالتالي قد يكون ممكنًا بالفعل.

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

كونك لغة أفضل لا يعني بالضرورة أنك بحاجة إلى تغيير هجاء كل عامل.

يؤدي استخدام () للفهرسة إلى إزالة الميزة الرئيسية المتمثلة في وجود بناء جملة للفهرسة - أي السماح لأشياء مثل النهاية بالعمل.

بدافع الفضول ، ألا يمكن تنفيذ end مثل : / Colon والسماح للمترجم بالتعامل معه بدلاً من المحلل اللغوي؟ أي جعلها ميزة مكتوبة بالكامل وقابلة للتحميل الزائد بدلاً من ميزة بناء الجملة والسكر؟ أفهم أنه سيتعين عليه دعم مجموعة من العمليات الحسابية ( end - 1 ، إلخ) ، لكن يجب أن يكون في أرض المجدي ، أليس كذلك؟

تحرير: آسف ، أرى الآن المناقشة حول هذا أعلاه ، على سبيل المثال Ragged.jl.

سيكون الشيء الذي يشبه C حقًا هو استخدام & A [x، y] لطرق العرض ، والذي يعد حاليًا خطأ نحويًا وبالتالي قد يكون ممكنًا بالفعل.

هل يمكننا تخيل استخدام & لإجراء تغييرات على tuples و NTuple s والمصفوفات غير القابلة للتغيير وما إلى ذلك؟ (أي مفيد للمصفوفات الموجودة في المكدس ، مثل # 11902)

&A[x,y] لا يبدو سيئًا أيضًا! يبدو الأمر بديهيًا وأفضله تمامًا على ()

وجود بناء جملة حيث يتغير المعنى مع أو بدون فراغات يجعل الأشياء أكثر صعوبة في الفهم.

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

هذا يعمل على 0.4:

A = rand(Int, 10,10)
3&A[1:2,3:5]
2x3 Array{Int64,2}:
 1  0  3
 3  0  2

andyferris : جعل end يعمل بشكل عام كامل مع هذا النهج يتطلب تقييمًا متأخرًا ؛ بدونها ، يمكنك في أحسن الأحوال تنفيذ إصدار نصف مخبوز بنوع يخزن جميع العمليات عليه.

إليكم فكرة عشوائية لم أفكر فيها بعد. أنا فقط أحضره هنا حتى نتمكن من تبادل الأفكار.

ربما حان الوقت الآن لإعادة التفكير في المعنى الدلالي للمصفوفة (أو الموتر) ، والعلاقة بين المصفوفة والوظيفة.

أود أن أفكر في المصفوفة بهذه الطريقة: ككائنات مجردة ، لا تختلف المصفوفة عن وظيفة. كلاهما يأخذ بعض المدخلات (فهرس للمصفوفة) ويعطيان الإخراج (القيمة). المصفوفة v = A (i) هي دالة ، معلمة الإدخال هي الفهرس. الدالة y = f (x) عبارة عن مصفوفة أبعاد لا نهائية ، حيث يكون الفهرس هو x. هذا أيضًا صحيح رياضيًا ، المتجهات في الفضاء الإقليدي لا تختلف كثيرًا عن الدوال في فضاء هيلبرت.

أود أن أعتقد أن المعنى الدلالي لـ A [1] هو أن ، A هو بعض التخزين ، نستخدم [] للوصول إلى القيمة المحددة للتخزين. هذا هو المستوى المنخفض الدلالي.

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

بالنسبة لي ، يعتبر العرض آلية تقييم كسولة للمصفوفة مثل استمرار وظيفة. لذلك يمكننا إنشاء بعض الوظائف عالية المستوى للمصفوفة لإنتاج العرض. تمامًا مثل الحصول على استمرارية أحادية للدالة f. ليس لدي فكرة واضحة عن كيفية القيام بذلك.

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

+1 لمرات مشاهدة []
+/- 1 لنسخ ()
-1 مقابل &A[x,y] مشاهدة
-1 مقابل A@[x,y] مشاهدة

منطق:
هناك مصطلح شائع مفاده أن الحالة الشائعة يجب أن تكون سريعة وسهلة (الترميز ، في هذه الحالة) ، في حين أن الحالات غير الشائعة يجب أن تكون ممكنة. حاليًا ، يتم التعامل مع النسخ على أنها الحالة الشائعة عبر بناء الجملة [] (وهو أساسًا سكر مقابل getindex / setindex! ) ؛ يتم التعامل مع المشاهدات كحالة غير شائعة عبر sub / slice وبدون سكر. أعتقد أن حقيقة أن الكثيرين قد تطرقوا إلى اتباع نهج أفضل لطرق العرض تشير إلى أنه يجب التعامل مع المشاهدات على أنها حالة شائعة مع بناء جملة محسن سريع / سهل.

إليكم ردي على بعض المخاوف العالقة التي أثارها JeffBezanson :

إنها حقا طريقة خاطئة لإخبار الجميع بتبديل جميع الفهرسة الخاصة بهم لاستخدام () ، ثم في المستقبل استخدام [] لطرق العرض عندما تريدها.

هل جعل الجميع التبديل ضروري حقًا؟ انطباعي هو أن معظم الشفرات ربما لا تعتمد على أي نسخ تلقائي يتم إجراؤه حاليًا بواسطة [] ، وربما تستفيد تلقائيًا من الأداء من استخدام طرق العرض. نظرًا لوجود تغييرات كسر كبيرة بالفعل في مصفوفات v0.5 wrt ، لا أعتقد أن التبديل كبير جدًا.

سيكون الشيء الذي يشبه C حقًا هو استخدام & A [x، y] لطرق العرض ، والذي يعد حاليًا خطأ نحويًا وبالتالي قد يكون ممكنًا بالفعل.

أجد هذا تعليق غريب نوعا ما. لا تمتلك C حقًا فكرة المصفوفة الفرعية في أبعاد N العامة ، ويتم استخدام إما مؤشرات النهاية أو عدد العناصر (أو الحراس!) للمصفوفات أحادية البعد (الفرعية) ، ولا يستخدم أي من هؤلاء المصفوفات & حقًا &A[x,y] .

أخيرًا ، هل نحتاج حقًا إلى صيغة خاصة لنسخ المصفوفات الفرعية؟ لدينا بالفعل deepcopy و convert . إذا كانت النسخ مهمة حقًا ، فأنا بالتأكيد لا أعارض وجود بنية خاصة مثل A(x,y) ، أو بعض التعديلات الطفيفة الأخرى A[x,y] سبيل المثال مع الرمز المفضل لديك. لا أعتقد أن النسخ مهمة مثل المشاهدات

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

هل جعل الجميع التبديل ضروري حقًا؟ انطباعي هو أن معظم الشفرات ربما لا تعتمد على أي نسخ تلقائي يتم إجراؤه حاليًا بواسطة [] ، ومن المحتمل أن تستفيد تلقائيًا من الأداء من خلال استخدام طرق العرض. نظرًا لوجود تغييرات كسر كبيرة بالفعل في مصفوفات v0.5 wrt ، لا أعتقد أن التبديل كبير جدًا.

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

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

أعتقد أن معظم كود مصفوفة جوليا ربما تريد طرق عرض لأسباب تتعلق بالأداء

آها! هذا تمييز مهم للغاية: هل تريد فقط تشغيل البرامج بشكل أسرع ، أم تريد كائنًا A بحيث يؤدي تعديل A إلى تعديل مصفوفة أخرى B؟

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

على النقيض من ذلك ، من خلال عرض الدلالات ، فإننا نعد بأن هاتين الوظيفتين متساويتان:

function f1(A)
    A[1,:] = 2
end

function f2(A)
    row = A[1,:]
    row[:] = 2
end

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

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

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

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

فيما يتعلق بنقطة أوسكار الجيدة جدًا ، نعم سيكون هناك أخطاء خفية في البعض
حالات بالتأكيد. ولكن يجب أن يكون معظم القائمين على صيانة الحزم على دراية جيدة بـ
تغيير التغييرات القادمة في 0.5 ، لذلك يجب أن ينتهي الأمر على أنه بسيط نسبيًا
إصلاحات الشوائب على ما أعتقد. مرة أخرى ، أنا منفتح على الإقناع إذا كان لدى شخص ما ملموس
مثال على قاعدة تعليمات برمجية يصعب تبديلها لعرض الدلالات.
في 5 شباط (فبراير) 2016 2:16 ظهرًا ، كتب "Jeff Bezanson" [email protected] :

أعتقد أن معظم كود مصفوفة جوليا ربما تريد طرق عرض لأسباب تتعلق بالأداء

آها! هذا تمييز مهم للغاية: هل تريد برامج فقط
للتشغيل بشكل أسرع ، أو هل تريد كائنًا A مثل تعديل تعديل A.
مجموعة أخرى ب؟

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

على النقيض من ذلك ، من خلال عرض الدلالات ، سنكون "نعد" بأن هذين الاثنين
الوظائف متكافئة:

الوظيفة f1 (A)
أ [1 ،:] = 2
النهاية

الوظيفة f2 (A)
row = A [1 ،:]
صف [:] = 2
النهاية

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub
https://github.com/JuliaLang/julia/issues/13157#issuecomment -180506892.

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

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

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

هل يمكننا استخدام الأقواس للعرض؟

julia> x = rand(1,5)
1x5 Array{Float64,2}:
 0.877481  0.18628  0.739978  0.306893  0.037569

julia> x{:,2:3}
ERROR: TypeError: Type{...} expression: expected Type{T}, got Array{Float64,2}

يعطي خطأ ، مما يعني أنه قد يكون ممكنًا. (أعتقد أنه تم اقتراحه من قبل ، لكنني لا أتذكر رؤية سبب أنها فكرة سيئة)

في ضوء حقيقة أنه لا يمكننا استخدام A [[2،21]]. وماذا عن الشيء غير المتماثل: أ [[2،21]؟ ستجعل جميع الاقتراحات مع الرموز & و @ الكود يبدو غريبًا حقًا. أعلم أن الاقتراح ليس متماثلًا ولكن من السهل كتابته ويبدو مألوفًا أكثر.

nstiurca نعم ، عرض الدلالات مفيد جدًا ، لكن بالنسبة لي لا يزال هذا غير كافٍ لحل القضية. هل A[1,1] عرض؟ إذا لم يكن الأمر كذلك ، فإن (1) الأقواس المربعة هي بنية غريبة أحيانًا تُرجع مرجعًا وأحيانًا لا تُرجع ، (2) إذا كنت تريد مؤشرًا لعنصر واحد ، فأنت بحاجة إلى التبديل إلى صيغة أخرى. ويزداد الأمر سوءًا بسبب حقيقة أن بعض الأنواع ، مثل المصفوفات المتفرقة ، إما لا تنفذ طرق العرض أو يكون لها طرق عرض بطيئة للغاية. يبدو أن جعل المشاهدات _1 حرفًا أسهل في الحصول عليها لا يستحق إضافة كل هذا الالتباس إلى عامل تشغيل القوس المربع المتواضع. سنحتاج إلى عامل آخر ليكون عامل "الفهرسة العاقلة" ، والذي اقترح البعض من أجله A( ) لكن هذا لن يحدث. ستحصل العملية الجديدة الأكثر تعقيدًا على بناء جملة جديد.

ماذا عن شيء غير متماثل

لأن ذلك قد يدفع الكثير من المبرمجين إلى الجنون: https://xkcd.com/859/

JeffBezanson A[1,1] هو عرض إذا كان على الجانب الأيسر من = ، ونسخة حاليًا ... دائمًا نسخة "لبناء جملة آخر. لكنك اتخذت قرارك بالفعل مهما يكن.

تضمين التغريدة
oh-god-why

في A[1,1] = z ، ربما يكون من الأدق اعتبار [1,1] معدِّلًا لـ = ، وليس A . على سبيل المثال (ولإدراج الأقواس حيث لا يُسمح بها فعليًا) ، فهي A ([1,1]=) z (لكن التمثيل الفعلي هو setindex!(A, z, [1, 1] ) ، على غرار الطريقة A (+=) z للتحليل إلى A = A + z بدلاً من (البناء غير الموجود) (A+) = z .

يمكن بالفعل إدخال نتيجة &x[3] : Ref(x, 3)

هذا صحيح ، ليس من المنطقي أن نقول أن A[1,1] على يسار = هو عرض --- ماذا يعني أن تكون نسخة بدلاً من ذلك؟

أوافق تمامًا على أن الشيء الصحيح هو أن يكون لديك بناء جملة يعني "دائمًا وجهة نظر" وآخر يعني "دائمًا نسخة". الخلاف الوحيد هو حول ما يجب أن يكون بناء الجملة لكل منهما. أعتقد أن تغيير A[ ] جذري للغاية. ماذا عن ، على سبيل المثال ، البحث في القاموس؟ هل هذا يدعم وجهات النظر أيضا؟

في هذه المرحلة ، أعتقد أن A[...] يعني دائمًا النسخ بينما يعني A@[...] دائمًا أن العرض يستحق المحاولة لمعرفة كيف يبدو الأمر. البنية الدقيقة ليست مهمة حقًا مثل تجربتها. ومع ذلك ، لما يستحق الأمر ، لست مقتنعًا تمامًا بما سأسميه "موقف جيف" لعدة أسباب:

  1. لا يبدو أن إنشاء نوع عرض كسول عام يمكن أن يكون نوع النتيجة لتقطيع الحاويات العامة أمرًا صعبًا للغاية. حقيقة أن المصفوفات الكثيفة تتمتع بتطبيق عرض أكثر كفاءة يعد تحسينًا رائعًا ولكنه مجرد تحسين - يمكنك فقط إرجاع عرض كسول وسيكون السلوك هو نفسه. قد يكون إنشاء عرض كسول رخيصًا وإذا أدى copy للعرض إلى انهيار العرض البطيء بحيث لا يصبح عرضًا ، فلديك طريقة متسقة للتعبير عن كل من المشاهدات والنسخ: A[...] هو عرض و copy(A[...]) شريحة غير مرئية. لا حاجة إلى إدخال بناء جملة غريب. هذا أيضًا له ميزة نحوية تتمثل في أن أقصر الأشياء وأكثرها وضوحًا رخيص (وغالبًا ما يكون سريع الاستخدام أيضًا) ، والشيء الباهظ الثمن - أي عمل نسخة - واضح جدًا ؛ أنت تعرف بالتأكيد أنه يتم عمل نسخة.
  2. أنا لا أشتري حجة الفهرسة العددية. هذا لأن الاختلاف الأكبر يبقى في كلتا الحالتين: الشرائح غير العددية - على سبيل المثال A[1,:] و v[1:5] - إرجاع الحاويات ؛ الشرائح العددية - على سبيل المثال A[1,2] و v[1] - تُرجع القيم الفردية. بالمقارنة مع هذا الاختلاف الدلالي الهائل ، فإن الفرق بين أن تكون الشريحة غير العددية عبارة عن طريقة عرض والشريحة العددية كونها غير مرئية تبدو تافهة. نظرًا لأنه يتعين علينا بالفعل فهم هذا الاختلاف ، لا أرى كيف تكون هذه الحجة مقنعة.

أعلم أننا ناقشنا في # 8892 الأقواس الزاوية القائمة على الترميز الموحد ، ولكن ماذا عن الأقواس الزاوية ASCII ( A<:,3> )؟ أدرك أنها الأقل قابلية للقراءة من بين جميع خيارات الأقواس ، لكنها تبدو جانبية "v" لـ "view": smile :.

مشكلة واضحة: حاليا

julia> 2<3>1
true

julia> 1<2>3
false

أعتقد أنه شخصيًا ، سأكون على استعداد للتبديل إلى 1 < 3 && 3 > 2 مقابل الحصول على شريحة أخرى مكونة من حرف واحد. في بعض التناقض مع استحالة إصدار تحذير للدلالات copy-> view ، أتساءل عما إذا كان من الممكن إصدار خطأ محلل إعلامي لهذا التغيير في بناء الجملة.

أو يمكننا استخدام C ++ بالكامل واستخدام A<<:,3>> . أنا بالفعل أرتجف مع أفكار الذهول!

للنسخ عند الكتابة: "COW" (U + 1F404)
للشرائح: "شريحة بيتزا" (U + 1F355)

حسنًا ، أوافق على أن حجة الفهرسة العددية ليست قوية. الجانب الأكثر أهمية هو كيفية تأثير ذلك على منفذي getindex (من بينهم الكثير) بشكل عام. هل التوجيه الذي يجب ألا يقوم بتطبيق getindex ، بدلاً من السماح له بالعودة إلى الوضع الافتراضي الذي ينشئ طريقة عرض ، وتنفيذ copy(::View{MyType}) بدلاً من ذلك؟

لا يبدو أن إنشاء نوع عرض كسول عام يمكن أن يكون نوع النتيجة لتقطيع الحاويات العامة أمرًا صعبًا للغاية.

لقد فعلناها ، وكان من الصعب. timholy أذكر أن أكبر مشكلة كانت الفهرسة الخطية. هل هذا صحيح؟ في حين أنه من الصحيح أن الحالات الخاصة للمصفوفات الكثيفة هي "تحسينات فقط" ، فإننا نعلم بالفعل أنه لا يوجد تنفيذ فعال ، على سبيل المثال للمصفوفات المتفرقة في الأفق. وماذا عن شيء مثل DataFrames؟

يمكنني القول أن DataFrames يصعب استخدامها كوسيلة واضحة لأي من الجانبين: الفهرسة في الباندا DataFrames ينتج بشكل عام عرض ؛ تؤدي الفهرسة في إطار بيانات R دائمًا إلى إنتاج نسخة عند الكتابة.

إن تنفيذ الفهرسة الخطية ليس بالأمر الصعب - إن تنفيذها _ بكفاءة_ صعب. لكن الفهرسة الخطية فعالة فقط في عدد قليل من هياكل البيانات على أي حال (المصفوفات التي يتم تخزينها بشكل متجاور) - ونرغب في الابتعاد عنها بشكل عام. إذا قمت بتنفيذ الفهرسة العددية ، فإن تنفيذ عرض V = A[I,J] هو مجرد مسألة تعليق على A ، I و J وتحديد V[i,j] = A[I[i],J[j]] . إذا كانت هناك طريقة أكثر فاعلية للقيام بذلك ، فيمكنك زيادة التحميل على الفهرسة غير العددية ، ولكن بشكل عام أعتقد أن هذا يجب أن يكون في الواقع _less_ يعمل لمعظم منفذي الحاوية. لاحظ أن تكوين المشاهدات يمكن أن يكون فعالاً بشكل عام: V[I,J][K,L] = V[I[K],J[L]] . نظرًا لأن تقطيع نطاق باستخدام نطاق ينتج عنه نطاق ، فإن هذا يعمل بشكل جيد.

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

johnmyleswhite هل يمكنني الحصول على إجابة أكثر

أحسنت اللعب ياJeffBezanson. :)

من أجل الوضوح على مستوى التحذلق ، يجب أن أشير إلى أنني لا أهتم بشكل خاص بأي من هذين الخيارين ينتهي به الأمر إلى اختيار الكود الخاص بي لأنني استخدم دائمًا sub الآن.

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

فيما يتعلق بإطارات البيانات ، أعتقد أن تقديم أي شكل من أشكال الفهرسة على الإطلاق هو خطأ: فأنت تحتاج حقًا إلى مستوى أعلى من التجريد مثل ذلك الذي يوفره R's dplyr.

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

johnmyleswhite أوافق على أن الآراء مطوري Torch وغيرهم ممن يفضلون المشاهدات ، ولكن ما الضرر في استخدام A@[] لتحقيق ذلك بالضبط؟ إذا كانوا لا يحبون عمل نسخ ، يمكنهم فقط تجنب بناء الجملة A[] .

أنا شخصياً أفضل أن يكون لدى A[] نسخ دلالات ، حيث قد يختار التطبيق استخدام النسخ عند الكتابة في بعض الحالات لأسباب تتعلق بالأداء. ثم يتم ضمان عرض الدلالات باستخدام بناء الجملة A@[] .

timholy ، أوافق ، سيكون من الجيد أن تكون قادرًا على استخدام <> لكن هناك بعض المشكلات ، على سبيل المثال ، الفهرسة المنطقية ستكون صعبة مع <> أيضًا:

A[x.<1]
A<x.<1>

من المحتمل أن يكون هناك عدد كبير جدًا من الحالات / القواعد الإضافية لجعل عمل <> .

A[...] عرض و copy(A[...]) شريحة غير مرئية

يعجبني هذا لأنه عندما يهتم المرء بالحصول على عرض أو نسخة لأسباب دلالية (على عكس الأداء) ، لن يكون عادةً في منتصف التعبير ، لذا فإن الإسهاب الإضافي copy() يبدو كثيرًا أسلم من السحر الإضافي لـ @[] بالنسبة لي.

@ lucasb-eyer أعتقد أن القضية هي أن مفهوم وجهة النظر لا يكون له معنى دائمًا. لذا فإن A[...] سيكون له معنى مفاهيمي مختلف لأنواع مختلفة من A . شخص ما يصحح لي إذا أسأت فهم ذلك.

بالإضافة إلى أن هناك قلقًا مفاده أن التغيير إلى طرق العرض افتراضيًا سيؤدي إلى ظهور الكثير من الأخطاء الدقيقة في النظام البيئي الحالي.

ما زلت أؤيد A@[...] بالمناسبة.

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

شكلت الفهرسة الخطية 2 من التحديات الثلاثة الرئيسية ، ولكن من العدل أيضًا أن نقول إن sub مقابل slice يمثل 2 من التحديات الثلاثة:

  • _inferring_ ما إذا كانت المصفوفة الفرعية تحتوي على فهرسة خطية فعالة هي المشكلة الأصعب. يكون هذا الأمر أكثر صعوبة في حالة إنشاء عرض للعرض ، لأنه باستخدام sub نقوم بتحويل فهارس الأعداد الصحيحة إلى نطاقات. هذا ملائم لأنه يمكن الاستدلال على أن sub(A, 3, :) يحتوي على فهرسة خطية فعالة ولكن sub(A, 3:3, :) لا يمكنه (تغيير ذلك إلى sub(A, 3:4, :) وتقطع الفهرسة الخطية) ، ولكن داخليًا أثناء التخزين نقوم بالتحويل بفعالية 3-> 3: 3. على الرغم من هذا التحويل ، تمكنا من تحقيق ذلك:
julia> A = rand(5,5);

julia> B = sub(A, 3, :);

julia> Base.linearindexing(B)
Base.LinearFast()

julia> C = sub(B, :, 2:4);

julia> Base.linearindexing(C)
Base.LinearFast()

وأيضا هذا:

julia> A = rand(5,5,5);

julia> B = sub(A, :, 2:3, 2:3);

julia> Base.linearindexing(B)
Base.LinearSlow()

julia> C = sub(B, :, :, 1);

julia> Base.linearindexing(C)
Base.LinearFast()

لأننا فقط رائعون. (ترجع الحيلة إلى المعلمة النهائية LD والتفكير حول كيفية حصولك على كل ما كان عليه من أجل المصفوفة الفرعية الأصلية.) لو كنت سأفعل ذلك مرة أخرى ، كنت أتجنب محاولة أن أكون رائعًا ، و الاحتفاظ بأبعاد "غير مقسمة" بنوع جديد من الفهرس ، NoSlice(3) ، مما يجعل الاستدلال مباشرًا.

  • البناء أو الفهرسة بأبعاد أقل:
A = rand(5,5,5)
B = sub(A, :, 3:17)  # constructs a 2d view from a 3d array

أو

A = rand(5,5,5)
B = sub(A, 2:4, 2:4, 2:4)
B[1, 7]

إذا تخلصنا من الأخير ، واستبدلنا الأول بتكوين من نوعين من العروض ، SubArray{ReshapedArray{Array}} ، ستكون الأمور أكثر نظافة (ولكن ربما تكون ذات أداء أقل).

  • إلى أن قمنا بإنشاء وظائف ، لم أجد طريقة خالية من النفقات للتعامل مع هذه المشكلة:
S1 = slice(A, :, 5, 2:6)
S2 = slice(A, 5, :, 2:6)
S1[i,j] -> A[i,5,(2:6)[j]]
S2[i,j] -> A[5,i,(2:6)[j]]

الآن بعد أن أصبحت أكثر اعتيادًا على أنماط الترميز "lisp-y" ، أظن أننا قد نكون قادرين على الاستغناء عن الوظائف التي تم إنشاؤها إذا كان من الممكن حل مشكلات الأداء المختلفة الناتجة عن الرش (# 13359).

@ mauro3 ، نقطة جيدة.

أعتقد أن المشكلة تكمن في أن مفهوم وجهة النظر لا معنى له دائمًا. لذا فإن [...] سيكون لها معنى مفاهيمي مختلف لأنواع مختلفة من A. شخص ما يصحح لي إذا أسأت فهم ذلك.

Evizero هل يمكن أن تشرح ما تعنيه بهذا؟ يوجد [...] بالفعل معاني مفاهيمية مختلفة لأنواع مختلفة من A.

  1. أنا لا أشتري حجة الفهرسة العددية. وذلك لأن الاختلاف الأكبر يبقى في كلتا الحالتين: شرائح غير عددية - على سبيل المثال A [1 ،:] و v [1: 5] - حاويات إرجاع؛ الشرائح العددية - على سبيل المثال A [1،2] و v [1] - تُرجع قيمًا مفردة. بالمقارنة مع هذا الاختلاف الدلالي الهائل ، فإن الفرق بين أن تكون الشريحة غير العددية عبارة عن طريقة عرض والشريحة العددية كونها غير مرئية تبدو تافهة. نظرًا لأنه يتعين علينا بالفعل فهم هذا الاختلاف ، لا أرى كيف تكون هذه الحجة مقنعة.

أتفق مع StefanKarpinski و @ lucasb-eyer هنا. نعم ، copy(A[...]) أكثر تفصيلاً ، لكنه أكثر سهولة في القراءة ، وبديهية ، وصراحة. A@[...] المحتمل أن يكون

الجانب الأكثر أهمية هو كيفية تأثير ذلك على منفذي getindex بشكل عام.

ماذا لو قمنا بتغيير A[…] إلى أقل من slice بدلاً من getindex واحتفظنا بدلالات getindex كما هي حاليًا؟ ثم copy(::SubArray) يمكن تهجئته كما يلي:

copy(S::SubArray) = getindex(S.parent, S.indexes...)

لا يزال القائمون على تطبيق getindex بحاجة فقط للتعامل مع الحالة العددية. لا تزال المكتبة الأساسية توفر (نسخ) احتياطات غير قياسية لـ getindex. إذا كان هناك تحسين متاح لهم ، فيمكنهم getindex (كما يفعلون حاليًا). أو إذا كان بإمكانهم تنفيذ نوع عرض أكثر كفاءة ، فيمكنهم slice . هذا يعني أيضًا أن copy(A[…]) هو نفسه فعليًا مثل getindex(A, …) القديم الجيد. إنه مجرد قلب امتياز بناء الجملة إلى طرق العرض ، دون فقدان الوظائف.

(لا يعمل هذا تمامًا كما هو ، نظرًا لأن slice(A, 1, 1) عبارة عن عرض 0 بُعد في الوقت الحالي ، ولكن يمكن تغيير ذلك أو تغيير اسم getindex المخصص.)

هل يمكن أن توضح ما تعنيه بهذا؟ يوجد [...] بالفعل معاني مفاهيمية مختلفة لأنواع مختلفة من A

أعتقد أن وجهة نظري كانت أنه سيكون من الغريب أن تقوم A [1 ،:] بإرجاع عرض للمصفوفات الكثيفة ونسخة للمصفوفات المتفرقة. بعبارة أخرى ، بالنسبة لبعض الأنواع ، فإن معالجة القيمة المرتجعة من شأنها في الواقع تغيير الكائن الأصلي بينما بالنسبة للأنواع الأخرى لن يؤدي ذلك إلى تغييرها.

ولكن لماذا تم تعريف A[1,:] للمصفوفات المتفرقة على الإطلاق؟ يبدو لي أنه تم تعريف هذا فقط لتحقيق واجهة AbstractArray الكاملة (مهما كانت). من الواضح أن الأنواع التي ليس لديها البيانات الخاصة بالشريحة المتاحة مباشرة يجب أن تحسبها بسرعة وبالتالي إنشاء نسخة بشكل طبيعي.

أنا قلق بشأن ذلك أيضًا ، لكن StefanKarpinski تناول ذلك من خلال اقتراح تطبيق احتياطي getindex والذي يُرجع دائمًا نوع عرض عام. هذا النوع من شأنه ببساطة القيام بالفهرسة غير المباشرة ، أي

getindex(v::View, i) = v.a[v.idx[i]]

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

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

يجب أن أشير إلى أن نسخ الشرائح الإملائية كنسخة (A [...]) لها عيب ، على الأقل من الناحية اللغوية وفي غياب التحسينات الذكية ، يعني أنه يتعين عليك الدفع مقابل إنشاء كائن العرض ثم نسخه .

ربما يمكن حل هذا بشكل مشابه لما لدينا حاليًا sub مع copy(A, ...) ؟

ربما يمكن حل هذا بطريقة مشابهة لما لدينا حاليًا مع نسخة (أ ، ...)؟
: +1:

ربما يمكن حل هذا بشكل مشابه لما لدينا حاليًا sub مع copy(A, ...) ؟

قد يكون لذلك نفس المشكلة التي يواجهها sub الآن ، وهي أنه لا يمكنك استخدام end كتعبير فهرسة.

copy(A[...]) لديه الكثير من الجاذبية لإصدار النسخ: فهو يقرأ بشكل مباشر تمامًا ، ولا يخفي عمليتين داخل واحدة ، ويبدو تمامًا مثل copy(foo(A)) لأي عملية أخرى foo() .

الآن للحصول على اقتراح مجنون إلى حد ما كحل مؤقت في غياب التحسينات الذكية بما فيه الكفاية: ماذا لو كان copy(A[...]) مجرد سكر نحوي لنسخة مجمعة و getindex؟ أعلم أن الناس سيكونون سعداء للتخلص من أشياء مثل Ac_mul_B ، لكن تلك كانت أيضًا بمثابة حل مؤقت مفيد حتى يأتي شيء أفضل.

هل يمثل copy(A[...]) مشكلة بالفعل؟ إذا كان بناء المصفوفة الفرعية رخيصًا ، فلن يكون للعملية المدمجة سوى تكلفة طفيفة.

@ c42f أعتقد أنه بالنسبة للسكر النحوي ، من الممكن تطبيق ماكرو @copy يقوم بذلك. يتطلب صنع سكر نحوي copy(A[...]) تغييرات في المحلل اللغوي.
tknopp لقد كنت أتساءل عن ذلك أيضًا. يجب أن تجعل تكلفة النسخ تكلفة إنشاء المصفوفة الفرعية ضئيلة.

ماذا لو كان A من النوع الذي لا يفسح المجال للمشاهدات (على سبيل المثال ، يجب أن يكون لدى A[...] نسخة مقابل A على أي حال). هل ينفذ copy(A[...]) بعد ذلك نسختين؟ يبدو أنه مصدر خفي لمشاكل الأداء.

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

فيما يتعلق بحجة الخطأ الدقيقة: هناك أشخاص يعتقدون أن ما يلي مفاجئ:

julia> a = [1,2,3];
julia> b = a;
julia> b[1] = 0;
julia> a
3-element Array{Int64,1}:
 0
 2
 3

يبدو أنه مشابه جدًا لمصفوفة تعيد وجهة نظر إلي.

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

tknopp هل تقترح ألا يعمل A[:, 1:2] ببساطة مع SparseMatrices؟ هذا يبدو غريبا جدا

هل تعتقد أن scipy غريب جدًا؟

أنا في الواقع لا أهتم إذا تم تعريف هذه الأساليب لمصفوفات متفرقة. لكن أخذ هذه الأساليب كحجة لعدم القيام بمجموعة وجهات نظر ليس مقنعًا بالنسبة لي. أو هل لديك حالة استخدام حيث يتم استخدام الأساليب؟

بالنسبة إلى scipy ، يعتمد الأمر على تنسيق المصفوفة الخاصة بك. بالنسبة إلى CSC يمكنك إجراء التقطيع ولكن بحجم خطوة 1 فقط.

هل تعتقد أن scipy غريب جدًا؟

IMHO python ليس نموذجًا جيدًا عندما يتعلق الأمر ببناء الجبر الخطي

لكن أخذ هذه الأساليب كحجة لعدم القيام بمجموعة وجهات نظر ليس مقنعًا بالنسبة لي.

لا أعتقد أن _ أي شخص_ يعارض عمل عروض المصفوفة. السؤال هو كيف ينبغي أن تبدو.

النقطة التي أردت توضيحها هي أن A[:, 1:2] طريقة ملائمة للمصفوفات المتفرقة. وأردت أن أعرف ما إذا كان الناس يعتقدون أن هذه حالة استخدام مهمة جدًا يجب أن تقود مناقشة بناء الجملة أم لا. لقد تعلمنا من هذا الموضوع أنه يمكننا أن نكون أكثر عمومية بنسخ [...] لكن هذا وحده لا يكفي IMHO لضمان بناء جملة خاص. من المهم أيضًا أن يكون بناء الجملة هو ما يريده الناس بالفعل في معظم المواقف. أعتقد أنها وجهة نظر ولكن هذا هو تفضيلي الشخصي وبالتالي أعتقد أنه ينبغي مناقشة هذا هنا.

أظن أن SciPy يعمل بهذه الطريقة على وجه التحديد لأن الفهرسة ترجع المشاهدات. لن ترغب أبدًا في استخدام عرض مصفوفة متفرقة غير فعالة بحيث لا يمكنك الحصول عليها. ولكن لا يزال الأمر يبدو لي غريبًا حقًا إذا كان بإمكانك القيام بـ A[1, 2] ولكن ليس A[:, 1:2] . ستظل بحاجة إلى طريقة ما للتعبير عن العملية الأخيرة ، ولا يمكن أن تكون copy(...) إذا لم تتمكن من إنشاء طريقة عرض. يبدو أيضًا أنه كارثة كاملة إذا كنت ترغب في كتابة تعليمات برمجية يمكن أن تعمل على كل من المصفوفات الكثيفة والمتفرقة.

أحد مواضيع هذا الموضوع هو أن هناك عنصرين لـ "ما يريده الناس بالفعل": الدلالات التي يريدونها ، وما هو سريع الآن. أفضل نسخ الدلالات ، وعندما أستخدم sub ، فعادة ما يكون ذلك للأداء وليس لأنني أريد بالفعل عرض الدلالات. أعتقد أن الطريقة المثالية قد تكون طرق عرض النسخ عند الكتابة كما اقترح JeffBezanson في https://github.com/JuliaLang/julia/issues/13157#issuecomment -180506892.

أظن أن SciPy يعمل بهذه الطريقة على وجه التحديد لأن الفهرسة ترجع المشاهدات. لن ترغب أبدًا في استخدام عرض مصفوفة متفرقة غير فعالة بحيث لا يمكنك الحصول عليها. لكن لا يزال الأمر يبدو لي غريبًا حقًا إذا كنت تستطيع القيام بـ A [1، 2] ولكن ليس A [:، 1: 2]. ستظل بحاجة إلى طريقة ما للتعبير عن العملية الأخيرة ، ولا يمكن نسخها (...) إذا لم تتمكن من إنشاء عرض. يبدو أيضًا أنه كارثة كاملة إذا كنت ترغب في كتابة تعليمات برمجية يمكن أن تعمل على كل من المصفوفات الكثيفة والمتفرقة.

  • نعم ، الفهرسة العددية لا تعني الكثير بالنسبة للمصفوفات المتفرقة. لذلك يجب التعامل مع هذا بالمثل
  • إذا كنت تريد كتابة رمز عام يعمل على مصفوفات متفرقة وكثيفة ، فهل ستستخدم فهرسة النطاق؟ بالطبع حصلت على حجتك ولكن سيكون من المثير للاهتمام إذا كان هذا شيء يستخدمه الناس بهذا الشكل أو إذا كانت هذه حالة استخدام افتراضية.

أحد مواضيع هذا الموضوع هو أن هناك عنصرين لـ "ما يريده الناس بالفعل": الدلالات التي يريدونها ، وما هو سريع الآن. أنا أفضل نسخ الدلالات ، وعندما أستخدم sub ، عادةً ما يكون للأداء وليس لأنني أريد بالفعل عرض الدلالات. أعتقد أن الطريقة المثالية قد تكون آراء النسخ عند الكتابة كما اقترح JeffBezanson في # 13157 (تعليق).

لست متأكدًا مما إذا كان من السهل فصل الدلالات عن الأداء. من وجهة نظري ، يجب أن يكون [...] خفيفًا قدر الإمكان ويجب أن يمنع أي تخصيص للكدمات.

فيما يتعلق بالنسخ عند الكتابة: لقد فوجئت بالفعل برؤية هذا الاقتراح من قبل JeffBezanson لأنه سيعقد نظام المصفوفة بأكمله. مع تعدد مؤشرات الترابط الجارية ، ليس من الواضح بالنسبة لي كيف يمكن تنفيذ ذلك بطريقة فعالة.

نسخة WRT عند الكتابة ، يمكنك جعل النواة تفعل ذلك ، ولكن فقط على OS X AFAICT وربما لا يزال لديها العديد من التكاليف المرتبطة بتخصيص الكومة. إذا لم نستخدم النواة ، فيبدو أنك قد تحتاج إلى القيام ببعض الأشياء الرائعة لجعل النسخ على الكتابة فعالاً للحلقات التي تقرأ ثم تكتب إلى مصفوفة ، ولكن إذا كان من الأسهل جعل المترجم أكثر ذكاءً من جعل المستخدمين أكثر ذكاءً ، قد يكون يستحق.

يعد الترابط نوعًا من التعقيد مع دلالات المصفوفات التي لدينا الآن ، لأنه من الممكن تغيير مؤشر الصفيف باستخدام push! وما إلى ذلك ، ومن ثم قد تصل بعض سلاسل العمليات إلى المخزن المؤقت الخطأ. لست متأكدًا مما إذا كان / كيف يتم التعامل مع ذلك حاليًا ولكن يبدو أنه مشكلة مماثلة.

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

يرجى أن تضع في اعتبارك أنه يمكننا عمل عروض لمصفوفات متفرقة بتكلفة قليلة نسبيًا ببساطة عن طريق الفهرسة من خلال كائنات الشرائح: على سبيل المثال ، تتطلب الفهرسة إلى S[1, 3:25] فقط إضافة عدد صحيح إضافي واحد لكل عنصر وصول. إذا كانت الشريحة متجهًا ، فنحن بحاجة إلى التمسك بهذا المتجه ، لكنني لا أرى ذلك باعتباره سدادة عرض - يمكن بناؤها في وقت ثابت وهي بطيئة بعض الشيء في العمل معها.

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

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

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

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

for M in (SparseMatrixCSC, SubArray{,...,SparseMatrixCSC, ...})
    <strong i="6">@eval</strong> begin
        ....
    end
end

من ناحية أخرى ، فإن فكرة تحسين طرق عرض BitArrays مخيفة بشكل إيجابي بالنسبة لي.

آسف للتدخل هنا كمستخدم خالص يشاهد هذا النقاش بقلق:

اقتراح عمل شرائح _نسخ على الكتابة_ هو أفضل خبر سمعته عن جوليا منذ فترة طويلة جدًا. أنا نفسي ، وجميع المتعاونين معي تقريبًا في رموز جوليا الخاصة بنا ، سأكون سعيدًا إذا كان تدوين التقطيع القياسي A[...] يتصرف بشكل دلالي كنسخة.

ملاحظة: أحب أيضًا فكرة وجود تدوين بسيط مثل A@[...] للمشاهدات.

cortner : هل يمكنك دعم هذا الرأي ، لماذا ستكون سعيدًا؟ أعني: حاليا هي دائما نسخة فلماذا أنت سعيد؟

tknopp : آسف إذا لم أكن واضحا. أنا في الواقع لا أهتم بشكل خاص بما إذا كان A[2:5, 6:12] بإرجاع نسخة أو مصفوفة مجردة للنسخ عند الكتابة طالما أنها تتصرف كنسخة. إلى حد ما ، قد يكون مجرد تفضيل شخصي ، ولكن في النهاية ، أليس هذا النقاش أساسًا حول الخيار الأفضل لأكبر عدد من المستخدمين ، أي التفضيلات الشخصية؟ بالنسبة لي شخصيًا ، فإن طريقة العرض التي تتبعها بايثون هي شيء يزعجني في كل مرة أكتب فيها كود بايثون ، لذلك كنت أخشى اليوم الذي تحولت فيه جوليا إلى هذا السلوك في 0.5.

أعتقد اعتقادًا راسخًا أن "السلوك الافتراضي" يجب أن يكون أولويًا وآمنًا قدر الإمكان. في هذا السؤال بالذات ، أعتقد فقط أن سلوك أسلوب النسخ (سواء كان نسخًا أو نسخًا عند الكتابة) يحقق ذلك.

وللتأكد من ذلك: قد يزعجني كثيرًا أن أضطر إلى كتابة copy(A[2:5, 6:12]) تمامًا كما يزعجني أن أضطر إلى كتابة slice(A, 2:5, 6:12) لحظة إذا أردت إسقاط أبعاد مفردة. (هذا فقط لإثبات أنني لست _ عادل_ من الإنجيليين المتلابين).

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

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

المشاهدات في تاريخ NumPy تعود إلى Numeric 1. يمكنك أن ترى بعض المناقشات حول PEP209 المسحوب من 2001 لإعادة التصميم المقترحة ، حيث يستشهدون بالأداء. في القائمة البريدية ، ناقشوا أيضًا إمكانية التركيب وبناء الجملة :

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

يبدوا مألوفا. قد يكون اختيارهم قد تأثر أيضًا بدعم تجريد قائمة القوائم للصفائف متعددة الأبعاد ؛ A[0] هو إشارة إلى الصف الأول من المصفوفة.

من المثير للاهتمام أن ماتلاب يبدو أنه يستخدم فقط مشاركة النسخ عند الكتابة من أجل بناء الجملة وإعادة التشكيل A(:) . جميع صيغ الفهرسة الأخرى عبارة عن نسخ فورية (تم اختبارها في 2014 أ). سأكون مندهشا للغاية إذا كانت هناك أي مناقشات عامة حول هذا ... ولكن الآراء ستكون انحرافا كبيرا عن دلالات النسخ عند الكتابة للتجليد.

بصفتي مستخدمًا لـ Julia ، إليك بعض مخاوفي بشأن جعل عروض المصفوفة افتراضية:

  • يمكن أن يكسر التغيير الحزم الحالية ورمز المستخدم بطريقة خفية ، دون فترة إهمال أو طريقة لتحذير المستخدمين تلقائيًا (طرق العرض للقراءة فقط تخفف هذا إلى حد ما ، ولكن ليس تمامًا). يمكن أن يكون لهذا عواقب وخيمة على مبرمجي جوليا غير المدركين ، أو الأشخاص العاديين الذين تتأثر حياتهم ببرنامج مكتوب بلغة جوليا.
  • يدور دعم التغيير إلى حد كبير حول الأداء ، ومع ذلك يمكن تحقيق تحسينات مماثلة في الأداء دون تغيير [] دلالات (من خلال تحسينات المترجم).
  • إذا كانت طرق العرض هي الإعداد الافتراضي لفهرسة النمط A [:، 1] ، فهل يجب أن تكون أيضًا هي الإعداد الافتراضي لفهرسة النمط A [bool_vec، 2]؟ في NumPy ، تؤدي الفهرسة باستخدام متجه منطقي أو متجه مؤشر إلى نسخة (على الأرجح لأسباب تتعلق بالأداء) ، بينما تؤدي الفهرسة باستخدام النطاق إلى عرض. هذا يربك المستخدمين ، ويجعل [] الدلالات معقدة ، ويقدم مصدرًا للأخطاء الدقيقة.
  • إذا تم اختيار طرق العرض كإعداد افتراضي لفهرسة المتجه المنطقي ومتجه الفهرس ، فما تأثير ذلك على أداء الكود الحالي (والمستقبلي) الذي يستخدم هذه الأنواع من الفهرسة؟ بالإضافة إلى الاضطرار إلى تخزين متجه الفهرس طوال فترة العرض ، من المفترض أن تتطلب مثل هذه العروض التحقق من حدين لكل وصول (أحدهما لمتجه الفهرس ، ثم الآخر للمصفوفة الأساسية).
  • ماذا يحدث لطريقة عرض إذا تغير شكل / حجم المصفوفة الأساسية؟ هل يجب إبطال العرض على الفور ، حيث تؤدي عمليات الوصول المستقبلية إلى خطأ؟ أم يجب أن يؤدي الوصول إلى العرض إلى حدوث خطأ فقط إذا كان الفهرس المترجم خارج المصفوفة الأساسية؟ من المحتمل أن يقدم كلا الأسلوبين زيادة في الأداء وتعقيدًا من شأنه أن يؤثر أيضًا على 99٪ من الحالات حيث لا يتغير حجم الصفيف الأساسي أبدًا.
  • بالنسبة للمصفوفات التي تحتوي على كائنات غير قابلة للتغيير (الحالة الأكثر شيوعًا) ، تُرجع A [1 ، 1] نسخة من العدد القياسي. بالنسبة لي ، قد يبدو الأمر غير متسق إذا أعاد التكوين A [1 ، 1: 2] المتشابه بصريًا عرضًا بدلاً من ذلك.

annalam : شكرا لك على هذه القائمة الرائعة.

يكسر التغيير كميات كبيرة من الحزم الحالية ورمز المستخدم بطريقة خفية ، دون فترة إهمال أو بأي طريقة لتحذير المستخدمين تلقائيًا.

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

ماذا يحدث لطريقة عرض إذا تغير شكل / حجم المصفوفة الأساسية

لا يمكن تغيير حجم المصفوفات التي تحتوي على أكثر من بُعد. قد يتم تغيير حجم Vector ، لذلك قد تتسلل بعض الحدود للتحقق من عدم الكفاءة هناك.

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

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

يسعدني إنشاء الريبو وإدارته ، إذا كان كل من شارك هنا على استعداد لتقديم بعض الرموز وحالات الاختبار القائمة بذاتها ، والتي يمكننا قياسها.

يسعدني إنشاء الريبو وإدارته

الرجاء القيامViralBShah. أعتقد أن بعض التعليمات البرمجية الحقيقية ستساعد في المناقشة بشكل جيد. الأشياء التي أود رؤيتها:

  • كم مرة تتم قراءة المصفوفات مقابل كتابتها؟
  • كم مرة تتطلب النسخ؟
  • ما مدى سهولة اكتشاف الأخطاء عند الكتابة فوق البيانات بصمت بسبب نسيان نسخة؟
  • ما هي الفروق الحقيقية في السرعة بين العرض / النسخ / النسخ عند الكتابة؟

أعتقد أنه مع وجود بعض الأمثلة "الحقيقية" ، قد يصبح بعضًا من هذا أكثر وضوحًا.

هذا اقتراح عظيم فيروسي. يمكنني المساهمة في حالة استخدام يكون فيها سلوك النسخ مضللًا. يجب أن نلخص كل subtle bugs هناك.

بخصوص COW ، هل هناك أي تنفيذ _لا يؤدي_ إلى إبطاء الوصول؟ أفكر في هذا:

type COWArray{T,N,A<:AbstractArray} <: AbstractArray
    iscopy::Bool
    parent::A
end

function setindex!(A::COWArray, val, indexes...)
    if !A.iscopy
        A.parent = copy(A.parent)
        A.iscopy = true
    end
    A.parent[indexes...] = val
end

الآن ، ربما يعني توقع الفرع أن الفحص لا يبطئ الوصول لغير SIMD ، ولكن اختبار هذا سيكون أولوية أولى.

قد لا تكون COW بهذا السوء في Matlab لأن اللغة لم تكن مصممة في البداية لأنماط الوصول لكل عنصر - إذا كانت الطريقة المعقولة الوحيدة لاستخدام المصفوفات هي عبر بناء الجملة المتجه ، فأنت ترفع بشكل فعال فحص COW.

timholy إذا استطعنا أن بالأعباء في الحلقات ، فأعتقد أن الأتباع قد ينجحون. سيحدث النسخ في التكرار الأول غير المسجل ، ويمكن حذف الشيك من الحلقة الرئيسية (مع TBAA المناسب). هذا يساعد فقط في الحلقات ذات الأنماط المتفرعة البسيطة ولكن من المحتمل أن تكون تلك الحلقات الوحيدة التي يكون فيها الحمل مهمًا.

أعتقد أن هذا لا يزال لا يحتوي على نفس دلالات النسخ حيث سترى طفرات في المصفوفة الأصلية

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

@ كارنافال : في تطبيق COW المناسب ، ستحتاج مجموعة "الأم" إلى

أود أن أقدم مثالًا ملموسًا للناس للنظر فيه. افترض أنني أريد تطبيق LU المحورية بالكامل ، وهي خوارزمية ستراها في الكتب المدرسية الموصوفة على هذا النحو (Golub and Van Loan 4 / e ، ص 132 ، الخوارزمية 3.4.3):

screenshot 2016-02-23 11 17 40

هذه الخوارزمية الخاصة غنية جدًا بسلوكيات الفهرسة والتقطيع.

قد يرغب المستخدم الساذج في كتابة شيء مثل هذه الخوارزمية

function lucompletepiv!(A)
  n=size(A, 1)
  rowpiv=zeros(Int, n-1)
  colpiv=zeros(Int, n-1)
  for k=1:n-1
    As = abs(A[k:n, k:n])
    μ, λ = ind2sub(size(As), indmax(As))
    μ += k-1; λ += k-1
    rowpiv[k] = μ
    A[[k,μ], 1:n] = A[[μ,k], 1:n]
    colpiv[k] = λ
    A[1:n, [k,λ]] = A[1:n, [λ,k]]
    if A[k,k] ≠ 0
      ρ = k+1:n
      A[ρ, k] = A[ρ, k]/A[k, k]
      A[ρ, ρ] = A[ρ, ρ] - A[ρ, k] * A[k, ρ]
    end
  end
  return (A, rowpiv, colpiv)
end

ولكن نظرًا لجميع النسخ التي يتم إجراؤها بواسطة تعبيرات الفهرسة ، فإن كود Julia هذا في 0.4 يكون بطيئًا بمقدار ضعف كود Python المكافئ

import numpy as np

def lucompletepiv(A):
    assert np.size(A, 0) == np.size(A, 1)
    n = np.size(A, 1)
    rowpiv = np.zeros(n-1, dtype=int)
    colpiv = np.zeros(n-1, dtype=int)
    for k in range(n-1):
        Asub = abs(A[k:n, k:n])
        mu, lam = np.unravel_index(np.argmax(Asub), np.shape(Asub))
        mu, lam = mu + k, lam + k
        rowpiv[k] = mu
        A[[k, mu], :n] = A[[mu, k], :n]
        colpiv[k] = lam
        A[:n, [k, lam]] = A[:n, [lam, k]]
        if A[k, k] != 0:
            rho = slice(k+1, n)
            A[rho, k] /= A[k, k]
            A[rho, rho] -= np.dot(np.reshape(A[rho, k], (n - (k + 1), 1)),
                                  np.reshape(A[k, rho], (1, n - (k + 1))))
    return (A, rowpiv, colpiv)

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

: +1:

للمقارنة ، هذا ما يجب علينا كتابته في 0.4 لأداء أفضل:

function lucompletepiv3!(A)
    n = size(A, 1)
    lda = stride(A, 2)
    rowpiv = zeros(Int, n - 1)
    colpiv = zeros(Int, n - 1)
    <strong i="7">@inbounds</strong> begin
        for k = 1:n - 1
            offsetk = (k - 1)*lda
            μ, λ = idxmaxabs2(A, k:n, k:n)
            rowpiv[k] = μ
            swaprows!(A, k, μ)
            colpiv[k] = λ
            swapcols!(A, k, λ)
            if A[k,k] ≠ 0
                ρ = k + 1:n
                scale!(1/A[k + offsetk], sub(A, ρ, k))
                for j in ρ
                    offsetj = (j - 1)*lda
                    Akj = A[k + offsetj]
                    <strong i="8">@simd</strong> for i in ρ
                        A[i + offsetj] -= A[i + offsetk] * Akj
                    end
                end
            end
        end
    end
    return (A, rowpiv, colpiv)
end

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

واو - جاءت الأمثلة بسرعة. أعتقد أننا بحاجة إلى العديد من الأكواد الأقرب لأحمال العمل أو التطبيقات الحقيقية. ربما ستكون الحزم مصدرًا جيدًا.

لقد قمت للتو بإنشاء هذا الريبو: https://github.com/JuliaLang/IndexingBenchmarks

إذا كان كل شخص هنا قد أرسل المقتطفات يمكنه إلزامها في الريبو أعلاه أو تقديم العلاقات العامة ، فسوف أتولى مهمة تنظيم وإعداد أداة لتشغيل الأشياء وما إلى ذلك.

مشكلة الأذونات مع الريبو:

remote: Permission to JuliaLang/IndexingBenchmarks.git denied to JaredCrean2.
fatal: unable to access 'https://github.com/JuliaLang/IndexingBenchmarks.git/': The requested URL returned error: 403

@ JaredCrean2 يجب أن تكون قادرًا على الكتابة إلى هذا الريبو الآن. بشكل عام ، بالنسبة للأشخاص الذين ليس لديهم حق الوصول للالتزام ، سيتعين عليهم إرسال تقارير عامة ، ولكن يسعدهم إضافة أي شخص يساهم / يساعد هناك.

لقد قدمت PR بدلاً من ذلك (لم أر تعليقك حتى الآن فقط).

ما هو الحد الأدنى من مجموعة الاختبارات لتكون مفيدة؟ نسخة جوليا (0.4) من خوارزمية تستخدم المشاهدات وواحدة تستخدم النسخ؟

مربعا اختيار في يومين. بهذا المعدل ، سننتهي في وقت قصير: ابتسم:.

تم نشر العديد من الأمثلة في هذه المشكلة لتوضيح أن إرجاع طرق العرض بشكل افتراضي غير كافٍ لحل العديد من مشكلات الأداء - يمكن معالجة العديد من هذه بشكل أفضل عن طريق "التقسيم التلقائي". هذا يقودنا إلى عالم مترجم ذكي بدرجة كافية. ومع ذلك ، في https://github.com/JuliaLang/julia/pull/6837#issuecomment -213617933 ، أدهشني أنه منذ اندماج jb/functions ، أصبح لدينا الآن الآلات لتمثيل هذه العمليات على الأقل في بطريقة فعالة.

بالطبع ، لا يزال هناك قدر هائل من السحر المترجم الذي يجب القيام به.

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

ما العناصر الموجودة هنا لا تزال في نطاق 0.5؟

أعتقد أنني وجدت طريقة لتجنب التباطؤ الكبير في أوقات الاختبار عند تقديم النوع Transpose لذا يجب أن يظل "Ditch الخاص لخفض Ac_mul_Bt" في النطاق. أعمل عليه.

من بين العناصر "الأساسية" ، لدي انطباع أننا قررنا عدم "إرجاع الشرائح كمشاهدات". ما يعمل andreasnoack عليه سيغلق معظم الباقي. يبدو أن احتمال "إنشاء أسهل للمصفوفات الثابتة" قاتمة؟ من المحتمل أن يتم إنهاء "أي نوع فهرس" بسرعة.

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

هل يمكن لشخص ما أن يشير إلى مناقشة "عودة الشرائح كوجهات نظر"؟ أعلم أنه ربما تم تجزئته مرارًا وتكرارًا ، ولكن هل هناك طريقة على الأقل في Base للقيام بشيء مثل view(A, i:j) (مثل ما توفره حزمة ArrayViews)؟

أعتقد أنه كان هنا في الغالب ، لكن جيثب ينهار بالفعل مناقشات طويلة الآن. هناك زر في منتصف عرض التعليقات المخفية.

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

شكرا على الملخص @ StefanKarpinski ؛ هل لدينا على الأقل القدرة على إعادة وجهة نظر؟ أعتقد أن هذا سيكون الحد الأدنى من الميزات ، لذا في الكود الخاص بي ، أعرف أنه يمكنني عمل view(A, i:j) عندما أعلم أن هذا كل ما أحتاجه / أريده للأداء.

لقد كان لدينا ذلك على مر العصور . انظر sub و slice ، والتي صارت سريعة في الوقت المناسب لـ julia-0.4. لدينا الآن بعض أنواع طرق العرض الإضافية أيضًا (على الأقل ReshapedArray و PermutedDimsArray ).

شكرا timholy ، آسف لجهلي هنا. :)

من المحتمل أن يتم إنهاء "أي نوع فهرس" بسرعة.

لم أعد أعتقد أننا يجب أن ندعم أي نوع من أنواع الفهرس نظرًا لصعوبة الحصول على إرسال للقيام بذلك - لقد قمت بتحرير هذه النقطة. أعتقد أنه يجب أن يحدث شيئين لهذا العنصر:

  • يجب تشديد احتياطيات الفهرسة العددية إلى Integer . سيؤدي هذا إلى حدوث خطأ في A[1.0] مع ظهور رسالة مفادها أن الفهرسة باستخدام Float64 غير مدعومة. ويمكن بعد ذلك إزالة الإهمال في to_index .
  • يمكن توسيع طرق الفهرسة غير القياسية والصفيف الفرعي لدعم كل Number s. إنهم يحتاجون حقًا فقط إلى معرفة أن هذه المؤشرات عددية ، ومن ثم تمريرها إلى طرق الفهرسة العددية. إذا أضافت المصفوفة المخصصة دعمًا للفاصلة العائمة أو مؤشرات أخرى أكثر تعقيدًا ، فستعمل فقط * ⁱˢʰ. خلاف ذلك ، سوف يكون الخطأ كما هو موضح أعلاه.

يوجد جزءان صعبان هنا:

  • ماذا تفعل بـ to_index ؟ إنها تفعل الآن شيئين فقط: استدعاء find على المصفوفات المنطقية وتحويل الأعداد الصحيحة إلى Int . سيكون من الغريب أن تقوم المصفوفات الفرعية وطرق الفهرسة غير القياسية بتمرير جميع المقاييس التي لم يتم لمسها باستثناء الأعداد الصحيحة - سيتم تحويلها إلى Int أولاً بواسطة to_index . ربما لا ينبغي أن يتلاعبوا بأي عددات على الإطلاق. يمكننا تقسيم to_index إلى جزأين: to_nonscalar_index (يستدعي find ويسمح بخطاف على سبيل المثال ، NullableArrays لتحسين استخدامها كمؤشرات) و to_scalar_index (فقط يتحول إلى Int )؟ أثناء قيامنا بإعادة البناء هنا ، هل نريد أيضًا السماح للمصفوفة التي يتم فهرستها بإبداء رأيها حول مؤشراتها ، على سبيل المثال https://github.com/JuliaLang/julia/pull/15750/files#diff -a21a7fc275830bf9efb5b7c17c4fb98eR439 ؟
  • الحلم هنا هو الحصول على هذا العمل مع مصفوفات مخصصة فاخرة مثل التداخلات. هذا يقودنا إلى 99٪ من الطريق إلى هناك ، لكن الجزء -ish هو أنه سيواجه مشكلة في إجراء فهرسة غير قياسية مع الأنواع التي تجعلهم يعيدون قيمة غير - eltype (مثل الاستيفاء باستخدام الأرقام المزدوجة). سيظلون يخصصون مصفوفة من eltype s للإخراج ، لكنهم سيصطدمون بخطأ عند محاولة التخصيص فيه. لا بأس في الوقت الحالي ، وفي المستقبل يمكن للفرد المتحمس تنفيذ تخصص promote_eltype_op مقابل getindex .

يجب تشديد احتياطات الفهرسة العددية إلى عدد صحيح. سيؤدي هذا إلى حدوث خطأ في A[1.0] مع ظهور رسالة مفادها أن الفهرسة باستخدام Float64 غير مدعومة.

هل مشكلة السماح باستخدام العوامات للفهرسة تقنية أم فلسفية؟

لقد كان لدينا ذلك على مر العصور. انظر الفرعية والشريحة ، والتي أصبحت سريعة في الوقت المناسب لـ julia-0.4. لدينا الآن بعض أنواع طرق العرض الإضافية أيضًا (على الأقل ReshapedArray و PermutedDimsArray غير المُصدَّر).

هل كان هناك أي اعتبار لإعادة تسمية sub إلى view ؟ لا يشير sub حقًا إلى أنه سيعيد عرضًا ...

view بواسطة حزمة ArrayViews التي تتمتع حاليًا بمزايا أداء كبيرة في حالات معينة (عروض متجاورة صغيرة).

متابعة لـ davidanthoff ، أعتقد أنه يجب علينا إيقاف العمل إما sub أو slice ومن المحتمل أن يكون sub الآن أن سلوك getindex يطابق slice .

هل مشكلة السماح باستخدام العوامات للفهرسة تقنية أم فلسفية؟

إنه مزيج من الاثنين ، ولكن إذا قمنا بفك التشابك القياسي / غير العكسي to_index كما أقترح أعلاه ، فهذا يزيل (آخر؟) الأسباب التقنية. تتطلب الفهرسة الخطية إجراء رياضيات على المؤشرات ، الأمر الذي يتطلب أعدادًا صحيحة. لقد تغير الكثير منذ دمجنا هذا الإهمال (https://github.com/JuliaLang/julia/pull/10458).

آه ، لقد اعتقدت أن القدرة الأساسية هي الآن مجموعة شاملة من العناصر ArrayViews وهي مفضلة دائمًا ... إنه لمن المؤسف بعض الشيء أن يتم استخدام الاسم الأكثر بديهية في الحزمة ويتم ترك القاعدة مع شيء أقل وضوحا ...

يبدو أنه من المؤسف والعكسي إلى حد ما لاسم مستخدم في حزمة لمنع اختيار اسم أكثر وضوحًا لوظيفة في Base. ربما يكون الطريق إلى الأمام هو التخلص من ميزة أداء ArrayViews وإيقاف تلك الحزمة وتغيير اسم الوظيفة إلى Base.view.

افتراضي / أملي هو أن فجوة الأداء ستختفي عندما نكون قادرين على تجميع الحاويات المخصصة للمكدس مع المراجع ... وأنا متشكك في وجود أي شيء يمكننا القيام به حيال ذلك بدون ذلك. الغلاف ArrayView أصغر حجمًا ، لذا فإن القدرة على تضمين إنشاء الغلاف وإلغاء إنشاءه يجب أن تؤدي الغرض.

هذا هو السبب في أن الاختلاف يظهر فقط مع إنشاء مصفوفات صغيرة --- في معظم المعايير الأخرى ، SubArray يساوي أو يتفوق على ArrayViews .

أوه ، وأنا أوافق على إهمال sub .

يمكن أن يستخدم كل من Base و ArrayViews view . بعد كل شيء ، يستخدم ImageView أيضًا view :)

أفترض أن هذا يمكن أن ينجح لأن ArrayViews يعرّف الطرق فقط لـ Array لكن Base يعرّف طرق AbstractArray (أعتقد؟). كيف يعمل هذا عند وجود نطاقات مختلفة:

module A
  function myfunc(a::AbstractMatrix)
     av = view(a, :, 1)
     # do something with av
   end
end

module B 
  using ArrayViews
end

هل يتغير typeof(av) اعتمادًا على ما إذا تم تحميل الوحدة B (بافتراض أن a هو Array

يجب أن يتوقف ArrayViews عن تصدير view ، وفي أي وقت تريد استخدام إصدار ArrayViews' يمكنك أن تقول ArrayViews.view(A, :, 1) .

سيتعين على ImageView أيضًا التوقف عن تصدير view ، لكني لا أوافق على هذه الفكرة.

من بين الإصدارات المتبقية ، بقي فقط # 5332 و # 16846 لـ 0.5 ؛ نقل هذه المسألة إلى 0.6.

أخطط أيضًا للقيام بـ https://github.com/JuliaLang/julia/pull/16260#discussion_r67140179 :

  • انتقاليًا (julia-0.5 فقط) جعل size و length يؤديان إلى ظهور خطأ في المصفوفات ذات الفهرسة غير التقليدية
  • تقديم @arraysafe لإعادة كتابة المكالمات إلى size و length لشيء لا يسبب خطأ
  • دمج allocate_for في similar

ربما لن يتم ذلك إلا بعد JuliaCon ، للأسف. في نفس المناقشة ، قدم eschnett حجة لإدخال نوع منفصل للفهرسة الخطية ، وأشار إلى أن إدخال linearindices هو لحظة مناسبة للقيام بذلك ؛ أنا لا أعارض ، لكنني لا أعتقد أنه سيكون لدي وقت لمعالجة ذلك بنفسي ، بحيث يكون الشخص جاهزًا للاستيلاء عليه.

طالما أنك تستخدمه ، timholy - يجب أن يتم ذلك بحلول الأسبوع المقبل حتى نتمكن من وضع علامة على RC. إذا كنت ترغب في فتح مشكلة ووضعها في المرحلة 0.5.0 حتى نتمكن من تتبعها ، يمكنك ذلك.

ألا ينبغي تعديل العنوان ، إذا تم نقل المعلم الرئيسي؟

أعتقد أن 0.6 جزء من هذا ينعكس في قضايا أكثر تحديدًا و PRs. الانتقال إلى 1.0.

راجع أيضًا # 20164 للاشتراك بسهولة أكبر في طرق العرض لكتلة كبيرة من التعليمات البرمجية.

كل شيء في هذه المشكلة إما أن يكون قد تم أو له مشكلته الخاصة أو أنه لن يحدث (راجعت).

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

القضايا ذات الصلة

yurivish picture yurivish  ·  3تعليقات

tkoolen picture tkoolen  ·  3تعليقات

wilburtownsend picture wilburtownsend  ·  3تعليقات

sbromberger picture sbromberger  ·  3تعليقات

StefanKarpinski picture StefanKarpinski  ·  3تعليقات