কীভাবে এই জটিল অভিব্যক্তিটি নামী স্লাইস ব্যবহার করে প্রকাশ করবেন


14

আমি পাইথনে নিম্নলিখিত বর্ণনাকে বাস্তবায়িত করতে চাই: যেখানে x এবং y হ'ল n এর আকারযুক্ত , এবং k একটি অদ্ভুত অ্যারে আকারের n × n । আকার n প্রায় 10000 পর্যন্ত হতে পারে এবং ফাংশনটি একটি অভ্যন্তরীণ লুপের অংশ যা বহুবার মূল্যায়ন করা হবে, সুতরাং গতি গুরুত্বপূর্ণ।

xi=j=1i1kij,jaijaj,
এক্সYএনএন×এনএন

আদর্শভাবে আমি সম্পূর্ণরূপে একটি লুপ এড়াতে চাই, যদিও আমি অনুমান করি যদি এটি হয় তবে এটি বিশ্বের শেষ নয়। সমস্যাটি হ'ল কয়েকটা নেস্টেড লুপ না করে কীভাবে এটি করতে হয় তা দেখতে আমার সমস্যা হচ্ছে এবং এটি সম্ভবত এটি ধীর করে দেবে।

কেউ কীভাবে নীচের মতো সমীকরণটি দক্ষ এবং এমনভাবে অগ্রাধিকারযোগ্য পঠনযোগ্য উপায়ে ব্যবহার করতে পারে তা দেখতে পারেন? আরও সাধারণভাবে, এই ধরণের জিনিসটির কাছে যাওয়ার সর্বোত্তম উপায় কী?


কয়েকদিন আগেও আমার একই রকম প্রশ্ন ছিল। স্ট্যাকওভারফ্লোতে আমি এটি জিজ্ঞাসা করেছি। এই পোস্টটি দেখুন । আমি সাইথনের পরিবর্তে স্কিপি.ইউইভ ব্যবহার করি। এর ফলে (বিবেচ্য) পারফরম্যান্সের পার্থক্য হয় কিনা কেউ কি জানেন?
SEB

উত্তর:


17

এখানে নুম্বার সমাধান দেওয়া হল। আমার মেশিনে নূম্বা সংস্করণ অলঙ্করণ ছাড়াই পাইথন সংস্করণের চেয়ে 1000x দ্রুত (200x200 ম্যাট্রিক্স, 'কে' এবং 200-দৈর্ঘ্যের ভেক্টর 'এ') faster আপনি @ অটোজিৎ ডেকরেটারও ব্যবহার করতে পারেন যা কল প্রতি 10 মাইক্রোসেকেন্ড যুক্ত করে যাতে একই কোডটি একাধিক ধরণের সাথে কাজ করে।

from numba import jit, autojit

@jit('f8[:](f8[:,:],f8[:])')
#@autojit
def looped_ver(k, a):
    x = np.empty_like(a)
    for i in range(x.size):
        sm = 0.0
        for j in range(0, i+1):
            sm += k[i-j,j] * a[i-j] * a[j]
        x[i] = sm
    return x

প্রকাশ: আমি নুম্বা বিকাশকারীদের মধ্যে একজন।


ধন্যবাদ, এটি বেশ সোজা দেখাচ্ছে। নাম্বার কথাও জানতাম না! সাইথন, পাইপাই, নুমবা ... এটি একটি বিভ্রান্তিকর বিশ্ব।
নাথানিয়েল

3
ট্র্যাভিস, খুব শীতল, আপনি নিজের উত্তরটির নীচে একটি প্রকাশ যুক্ত করতে আপত্তি করছেন যে আপনি নাম্বার বিকাশকারীদের একজন?
অরন আহমদিয়া

1
এন=200

@ নাট উইলসন - আপনি যদি স্কিকম্পের বিষয়ে প্রশ্ন হিসাবে এটি জিজ্ঞাসা করেন তবে আমি আপনার জন্য এটি চেষ্টা করে সামলাতে খুশি হব :)
অ্যারন আহমাদিয়া

4

এখানে একটি শুরু। প্রথমত, কোনও ভুলের জন্য আমার ক্ষমা চাই।

আমিআমি-1

সম্পাদনা: না, প্রশ্নের উপরের হিসাবে উপরের সীমাটি সঠিক ছিল। আমি এটি এখানে যেমন রেখেছি কারণ অন্য উত্তর এখন একই কোড ব্যবহার করে তবে ফিক্সটি সহজ।

প্রথমে একটি লুপ করা সংস্করণ:

def looped_ver(k, a):
    x = np.empty_like(a)
    for i in range(x.size):
        sm = 0
        for j in range(0, i+1):
            sm += k[i-j,j] * a[i-j] * a[j]
        x[i] = sm
    return x

আমি এটিকে নালীর টুকরো দিয়ে একটি একক লুপ তৈরি করেছি:

def vectorized_ver(k, a):
    ktr = zeros_like(k)
    ar = zeros_like(k)
    sz = len(a)
    for i in range(sz):
        ktr[i,:i+1] = k[::-1].diagonal(-sz+i+1)
        a_ = a[:i+1]
        ar[i,:i+1] = a_[::-1] * a_
    return np.sum(ktr * ar, 1)

এন=5000

তারপরে আমি (আরও পাঠযোগ্য) লুপ করা কোডটির একটি সিথন সংস্করণ লিখেছিলাম।

import numpy as np
import cython
cimport numpy as np

@cython.boundscheck(False)
@cython.wraparound(False)
def cyth_ver(double [:, ::1] k not None,
              double [:] a not None):
    cdef double[:] x = np.empty_like(a)
    cdef double sm
    cdef int i, j

    for i in range(len(a)):
        sm = 0.0
        for j in range(i+1):
            sm = sm + k[i-j,j] * a[i-j] * a[j]
        x[i] = sm
    return x

আমার ল্যাপটপে, এটি লুপযুক্ত সংস্করণের চেয়ে প্রায় 200x দ্রুত (এবং 1-লুপ ভেক্টরাইজড সংস্করণের চেয়ে 8x দ্রুত)। আমি নিশ্চিত অন্যরা আরও ভাল করতে পারে।

আমি জুলিয়া সংস্করণ দিয়ে খেলেছি, এবং মনে হয়েছিল (আমি যদি এটি সঠিকভাবে টাইম করি) সিথন কোডের সাথে তুলনীয়।


এক্স0আমি-1

আহ আমি দেখি. আমি এটি মূল সংমিশ্রণ থেকে সংগ্রহ করেছি, তবে নিশ্চিত ছিল না যে সেটাই উদ্দেশ্য।
নাট উইলসন

1

আপনি যা চান তা একটি সমঝোতা বলে মনে হচ্ছে; আমি মনে করি এটি অর্জনের দ্রুততম উপায়টি হবে numpy.convolveফাংশন।

আপনার সঠিক প্রয়োজন অনুসারে আপনার সূচকগুলি ঠিক করতে হতে পারে তবে আমি মনে করি আপনি কিছু চেষ্টা করতে চাইবেন:

import numpy as np
a = [1, 2, 3, 4, 5]
k = [2, 4, 6, 8, 10]

result = np.convolve(a, k*a[::-1])
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.