• کامپیوترهایی که یاد می‌گیرند

    به نام خدا

    امروز یک ویدیو بسیار جالب از TEDxBrussels میدیدم در مورد کامپیوترهایی که می‌توانند یاد بگیرند. جای تعجب نداره که صحبت در مورد پیشرفت‌هایی بود که از طریق به کارگیری چارچون یادگیری موسوم به یادگیری عمیق (Deep Learning) به دست آمده. باز صحبت در مورد این بود که کامپیوترها قراره بسیاری از شغل‌های انسانی رو در اختیار بگیرن. ولی در این صحبت روی دو جنبه‌ی دیگه هم بحث کوتاهی شد که کمتر قبلاً دیده بودم.

    اول اینکه انسان به همراه کامپیوتر در بسیاری از کارها می‌تونن بسیار کارآمدتر و هوشمندتر عمل کنن. این دید متفاوتیه از این دید غالب و تاریخی که کامپیوترها رو در مقابل انسان‌ها قرار میده. البته بحث در مورد اینکه آیا واقعاً روزی کامپیوترهای هوشمند در مقابل انسان قرار خواهند گرفت یک بحث طولانی هست که نیاز به چند پست دیگه و مطالعات بیشتری از جانب من داره. ولی این دید حداقل در چشم‌انداز آینده‌ای نزدیک دیدی هست که می‌تونه بسیار مفید باشه و چیزی هست که واقعاً باهاش مواجه خواهیم شد. در این مورد یک demo خیلی جالب هم نشون میده.

    موضوع دیگه، هر چند مرتبط به موضوع قبلی، در مورد اثر کامپیوترها بر کشورهای کمتر توسعه ‌یافته یا بهتره بگم کشورهای غیر جهان اول هست. اگر به توزیع شغل‌ها در این کشورها نگاهی بیاندازیم، بیشتر ای شغل‌ها به سرعت و راحتی می‌تونن با سیستم‌های کامپیوتری جایگزین بشن و این کار می‌تونه اثر بسیار بزرگی بر اقتصاد این کشورها که بیشتر جمعیت دنیا رو هم تشکیل میدن داشته باشه.

    به هر حال مسئله‌ی هوشمند شدن سیستم‌های کامپیوتری مسئله‌ای هست که بشر برای اولین بار داره در طول تاریخ باهاش مواجه میشه و باید برای عواقب این تغییر آماده باشیم و در موردش فکر کرده باشیم. الان میشه گفت کامپیوترها در بیشتر کارها به حد بالایی از هوشمندی رسیدن و با نرخ بالایی هوشمندی اونها داره بالاتر هم میره. پس در وحله‌ی اول باید در مورد رفتارمون در مقابل این هوشمندی و اثراتش فکر کنیم و چاره بیاندیشیم. و به این موضوع هم توجه کنیم که هوشمندی مقوله‌ای جدا از خودآگاهیه.

    این هم ویدیویی که در موردش گفتم، با سخنرانی آقای Jeremy Howard


  • سال 2014 با پاکت

    17 Dec 2014

    به نام خدا

    امروز ایمیلی از طرف پاکت بهم رسید که در اون نوشته شده بود من جزو Top 5% readers پاکت شدم.

    Year in Pocket total stats

    به همین مناسبت صفحه‌ای نیز درست کردن که توی این صفحه به طور خلاصه گزارشی از کاربری از این سرویس در سال گذشته نشون داده میشه.

    My 2014 Year in Pocket

    Year in Pocket weekly stats

    امیدوارم در سال بعد، یعنی سال 2015، بیشتر مطالعه داشته باشم، هم با استفاده از این سرویس، هم به طرق دیگه.


  • 1024 vs. 1000

    07 Dec 2014

    به نام خدا

    راستش رو بخوایید من هم هنوز دقیق نمی‌دونم وقتی به مدل‌های مختلفی می‌نویسن منظور کدومه.

    1024 vs. 1000


  • دومین سالگرد وبلاگ :)

    17 Oct 2014

    به نام خدا

    امروز دومین سالگرد اون یکی وبلاگمه. دو سال پیش در همین روز بود که اولین پستم رو توی اون بلاگ منتشر کردم.امروز به مناسبت دومین سالگرد چون حوصله‌ی پست نوشتن اونجا رو نداشتم، یعنی در واقع حوصله‌ی پست‌نویسی به سبک اونجا رو نداشتم، تصمیم گرفتم اینجا در مورد اون بلاگ بنویسم.

    البته نوشتن که چه عرض کنم، بیشتر با چند تا عدد بازی کنم و یه چندتایی نمودار بکشم. هدف بیشتر کار با matplotlib بود تا کار مهم دیگه‌ای.

    تو این مدت دو ساله، 77 پست رو ارسال کردم تو اون یکی بلاگم

    Timeline post distribution

    Timeline post distribution

    خیلی واضحه از روی پست که در یکسال اول، خیلی بیشتر از یکسال دوم پست نوشتم. شاید نشون میده که یکسال دوم، یعنی از یکسال پیش، آرامیش بیشتری به زندگیم حاکم بوده. از طرف دیگه شاید بشه گفت که هیجان زندگیم کمتر شده، چیز کمتری بوده تو زندگیم که در موردش بنویسم. البته اگر به آخرهای این مدت زمان نگاهی بندازیم، میبینیم که باز شروع کرده بودم به مرتب نوشتن، ولی باز از حوصله افتادم و الان خیلی وقته که ننوشتم. درسته که فقط دوبار اتفاق افتاده، ولی شاید این تحلیل رو هم بشه کرد که در نزدیکی‌های سالگردها، خیلی کمتر نوشتم.

    از نظر زمانی فکر می‌کردم بیشتر پست‌هام رو در روزهای آخر هفته می‌نوشتم. ولی این نمودار چیز دیگه‌ای رو نشون میده

    Weekly post distribution

    اینطوری که مشخصه بیشترین پست‌هام رو در روز دوشنبه منتشر کردم. هر چند آخرهفته‌ها هم فعال بودم.

    یه موضوع دیگه‌ای که مطرحه اینه که بیشتر در چه زمان‌هایی از شبانه‌روز اقدام به ارسال پست می‌کردم؟ حدس خودم اینه که شب‌ها بیشتر می‌نوشتم. داده‌ها هم این حدس رو تایید می‌کنن.

    Daily post distribution

    البته خیلی هم مطابقت نداره با حدسم. بیشترین پست‌ها رو ساعت 20 شب منتشر کردم. در حالی که من حدس می‌زدم زمان ارسال‌هام چند ساعتی دیرتر باشن. این نکته هم جالبه که ساعت 2 و 3 بامداد و همچنین نیمه‌ی روز هیچوقت ارسال پست نداشتم.

    موضوع بعدی که دوست داشتم در مورد پستم بدونم این بود که چقدر می‌نویسم؟ خودم که همیشه دوست دارم پست‌هایی که می‌نویسم یا می‌خونم طولانی باشن، بخاطر همین حدس می‌زنم بیشتر پست‌هام طولانی باشن. ولی چقدر طولانی؟ از روی بررسی پست‌ها مشخص میشه که طولانی‌ترین پستم از 4170 کلمه‌ تشکیل شده. فکر می‌کنم خیلی کم نباشه :دی

    نمودار پایین هم توزیع پست‌ها بر اساس طولشون رو نشون میده. هر دسته بازه‌ای به طول 400 کلمه است.

    Daily post distribution

    نکته‌ی دیگه‌ای که بهش پرداختم، بررسی رابطه‌ی بین طول پست و زمان ارسال پست بود. یعنی بعضی شبا که میشینم، با خودم هی فکر می‌کنم، آیا نتیجه‌اش این میشه که پست‌های طولانی می‌نویسم؟ محور عمودی طول پست، و محور افقی زمان ارسال پست هست. شکل پایین این موضوع رو بررسی کرده.

    Post length vs. Publishing time scatter plot

    یا اگر جور دیگه‌ای بهش نگاه کنیم، اینطوری:

    Post length vs. Publishing time hex plot

    این نمودار آخر به خوبی این ارتباط رو نشون میده. این که بیشتر شب‌ها پست‌های طولانی‌تری می‌نویسم.البته چون داده‌های زمانی ه صورت ترتیبی نیستن، بلکه دوری هستن، نمیشه یک رابطه‌ی خطی بینشون پیدا کرد. اگر بتونم راه‌حلی برای این مورد پیدا کنم، سعی می‌کنم فرمولی برای این رابطه به دست بیارم.

    بجز این موارد چیز دیگه‌ای به ذهنم نرسید. یعنی بیشتر به تحلیل متن احتیاج داشتم، ولی همچین چیزی فعلاً بلد نیستم. تنها کاری که تونستم انجام بدم این بود که ماتریس شباهت پست‌هام رو به هم پیدا کردم. در شکل پایین ماتریس شباهت پست‌ها رو می‌بینید.

    Post Similarity Matrix

    انتظار دیدن همچین چیزی رو نداشتم. به طرز عجیبی بین سه تا از پست‌ها شباهت زیادی وجود داره، یعنی پست‌های "یه دوست خاص"، "متاسفم"، و "عصبانی". برام این موضوع خیلی عجیب بود. چون نباید این اتفاق میوفتاد. اینقدر شباهت در متن پست‌ها خیلی عجیبه. در نتیجه تصمیم گرفتم متن این پست‌ها رو به دقت و از نزدیک بررسی کنم. وقتی که این کار رو کردم به این نوشته در همه‌شون رسیدم:

    برای نمایش مطلب باید رمز عبور را وارد کنید

    و اینطوری بود که از راز شباهت این سه پست هم پرده برداشته شد :دی

    اگر بهتر به این ماتریس نگاه کنیم، تعدادی پست‌ها هستن که خیلی با پست‌های دیگه تفاوت دارن. اینا پست‌هایی هستن که توشون کلمات انگلیسی زیادی به کار برده شده. ولی بین بعضی دیگر از پست‌ها شباهت‌های خوبی هست. نیاز هست که دقیق‌تر این پست‌ها رو باز بررسی کنم.

    نکته‌ی جالبی که رخ داد اینه که بیان دسترسیم رو بلاگم قطع کرده بخاطر اینکه درخواست زیاد فرستادم.


  • حل مشکل درایورها پس از ایجاد مشکل توسط Windows Update

    به نام خدا

    چند روز پیش سری به قسمت آپدیت‌های ویندوز آپدیت زدم. من خودم نصب آپدیت‌های ویندوز را در حالت خودکار گذاشتم ولی هر از چند گاهی به قسمت آپدیت‌های ویندوز سر می‌زنم تا ببینم آپدیت‌های اختیاری جدیدی وجود دارند یا نه. این با که به این قسمت سر زدم، با آپدیت جدیدی برای درایور Intel HD Graphics مواجه شدم. اینتل از چند نسل قبل در پردازنده‌های خود یک پردازنده‌ی گرافیکی نیز تعبیه کرده است. این پردازنده‌ی گرافیکی با اینکه در ابتدا توان بسیاری نداشت، ولی در نسل‌های اخیر پردازنده‌های اینتل به پردازنده‌ی بسیار قدرتمندی تبدیل شده است. همچنین به دلیل یکپارچه بودن با پردازنده، ویندوز بسیاری از پردازش‌های گرافیکی را توسط این پردازنده‌ی گرافیکی انجام می‌دهد. در این صورت بار محاسباتی بر روی پردازنده‌ی اصلی کمتر شده و همچنین مصرف برق نیز کاهش میابد. به همین خاطر است که بروزرسانی درایور این پردازنده‌ی گرافیکی در بهتر کردن تجربه‌ی کاربری ویندوز مفید است. البته این بار بعد از به روزرسانی درایور پردازنده‌ی گرافیکی اینتل از طریق Windows Update مشکلی رخ داد. اولین مشکل عمده این بود که امکان تغییر روشنایی نمایشگر از بین رفت و نمایشگر در روشن‌ترین حالت خود قرار گرفت و این آزاردهنده بود. مشکل دوم این بود که کیفیت تصویر به میزان بسیار قابل توجهی کاهش یافت و این مشکل، حتی بیشتر آزاردهنده بود. پس از نصب چندین و چند باره‌ی انواع درایور دیگر که اتفاقاً جدیدترین درایورها از طرف اینتل و همچنین Lenovo بودند، باز این مشکل برطرف نشد.

    در نهایت به راه‌حل جالب دیگری دست یافتم. البته این راه‌حل، دست‌مایه‌ی جستجوهای فراوان در اینترنت است.

    اگر بعد از به روزرسانی درایوری مشاهده کردید که عملکرد سخت‌افزار مورد نظر با مشکل همراه است، یک روش ساده برای بازگرداندن درایور قبلی وجود دارد.

    (اگر آپدیتی از طرف Windows Update مشکلی ایجاد کرد، راه‌حل کلی این است که آپدیت مورد نظر را پاک کنید، ولی کاهی امکان پاک‌کردن بعضی آپدیت‌ها وجود ندارد؛ مورد اخیر نیز از این دسته آپدیت‌ها بود)

    راه حل

    1. به Device Manager بروید. در ویندوز 8 می‌توان با جستجوی این عبارت به مکان مورد نظر رفت. در ویندوزهای قبلی نیز می‌توان با راست‌کلیک بر روی آیکون My Computer و انتخاب Manage، به Device Manager رفت.
    2. از لیست سخت‌افزارها، سخت‌افزار مورد نظر که درایور آن مشکل پیدا کرده است را پیدا کنید.
    3. بر روی نام درایور راست‌کلیک کنید و گزینه‌ی

      Update Driver Software...

      را انتخاب کنید.

    4. در صفحه‌ای که باز می‌شود گزینه‌ی

      Browse my computer for driver software

      را انتخاب نمایید.

    5. در صفحه‌ی بعدی که باز می‌شود، گزینه‌ی

      Let me pick from a list of device drivers on my computer

      را انتخاب کنید.

    6. در نهایت، در صفحه‌ای که باز می‌شود، از لیست موجود، درایوری از تاریخی گذشته را که سخت‌افزار بدون مشکل عمل می‌کرد انتخاب نمایید. توجه کنید که تیک قسمت Show Compatible Hardware زده شده باشد.

    Device Manager - Revert to old driver software

    با انجام این دستورات، می‌توانید درایور سخت‌افزاری مورد نظر را به تاریخی گذشته برگردانید و مشکل را حل نمایید.


  • Ray Kurzweil on Singularity 1 on 1

    22 Aug 2014

    به نام خدا

    امروز این گفتگو رو پیدا کردم. گفتگوی جالبی هست. پیشنهاد می‌کنم ببینید حتماً.


  • OpenCV Python Starter Code

    به نام خدا

    معمولاً رسم هست که اولین کد در هر زبان برنامه‌نویسی رو با چاپ کردن عبارت Hello World در خروجی شروع می‌کنند.

    ولی جدای از زبان‌های برنامه‌نویسی گاهی نیاز هست به سرعت بفهمیم آیا تنظیم و نصب یک کتابخانه‌ی مشخص در یک زبان برنامه‌نویسی به درستی انجام گرفته یا نه. برای اینکار لازمه تکه‌کد کوچکی رو با استفاده از این کتابخانه اجرا کنیم تا به مشکلات در صورت وجود پی ببریم. معمولاً پیدا کردن همچین تکه‌کدهای کوتاه کار راحتی نیست و بیشتر از اون که باید، گاهی زمان می‌بره. به همین دلیل تصمیم گرفتم از این به بعد کدهای کوچکی با عنوان Starter Code برای کتابخانه‌هایی که استفاده می‌کنم بر روی این وبلاگ قرار بدهم تا به عنوان یک راهنمای کوتاه برای انجام این امر باشه.

    به عنوان اولین پست از این مجموعه، تکه کدی رو قرار می‌دهم تا بشه باهاش به سرعت کتابخانه‌ی OpenCV رو در پایتون امتحان کرد.

    نمونه کد

    import numpy as np
    import cv2
    
    # Open the webcam to grab frames and display them
    cap = cv2.VideoCapture(0)
    
    while(True):
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('frame',gray)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # When everything done, release the capture
    cap.release()
    cv2.destroyAllWindows()
    

    Sample code source: [OpenCV-Python-Tutorials]

    این کد، ابتدا کتابخانه‌های لازم را بارگزاری می‌کنه. سپس اولین فریم از تصویر از وب‌کم گرفته میشه. بعد در یک لوپ تکرار شونده، در ابتدا یک فریم جدید از وب‌کم گرفته میشه، سپس با تبدیل نمایش فریم گرفته شده از حالت رنگی به سیاه‌سفید، تصویر نهایی در خروجی نمایش داده میشه. در نهایت هرگاه کلید q توسط کاربر وارد بشه، برنامه از لوپ خارج شده و نمایش تصاویر از وب‌کم متوقف میشه.


  • بررسی پیاده‌سازی‌های مختلف حلقه در سی‌پلاس‌پلاس

    به نام خدا

    معرفی

    این پست، بیشتر یک پست معرفی است. امروز یک وبلاگ جدید پیدا کردم که نویسنده‌ی آن تصمیم دارد به مباحثی در برنامه‌نویسی با تمرکز بر روی زبان C++ بپردازد. وبلاگی که معرفی شد Random Programming نام دارد.

    پیشنهاد پست

    فعلاً تعداد پست‌های این وبلاگ به خاطر اینکه تازه تاسیس شده است زیاد نیست. ولی در میان پست‌های وبلاگ، یک سری از پست در مورد انواع پیاده‌سازی حلقه در حالات مختلف در C++ می‌باشد. خواندن این پست‌ها را بسیار توصیه می‌کنم. بخصوص قسمت‌هایی از پست‌ها به پیاده‌سازی با استفاده از امکانات STL در C++11 پرداخته است.

    1. در پست اول این سری، صورت مسئله این است. یک محموعه از اشیا داریم، چگونه می‌توانیم بر روی همه‌ی اشیاء این محموعه تابعی را اجرا نماییم؟ راه‌کارهایی که معرفی شده‌اند در ادامه توسط نویسنده کاملاً بررسی شده و مزایا و معایب هر کدام گفته شده است. این پست را می‌توانید در این آدرس مشاهده کنید.

    2. در این پست، مسئله مشابه پست قبلی است. فرق در این است که در اینجا علاوه بر اشیا مجموعه به تابع آرگومان دیگری نیز پاس داده می‌شود. این پست را نیز می‌توانید در این آدرس مشاهده کنید.

    3. در پست سوم این مسئله بررسی شده است که چگونه می‌توان تابع عضو (member function) را بر روی اعضای یک کلاس درون یک مجموعه صدا زد؟ این پست نیز در این آدرس قرار دارد.

    4. مسئله چهارم به این شکل است. فرض کنید مجموعه‌ای از اشیا از یک کلاس داریم. می‌خواهیم از روی هر یک از اشیاءِ این محموعه، اشیائی از یک کلاس دیگر بسازیم و در مجموعه‌ای دیگر قرار دهیم. این کار را چگونه می‌توان انجام داد؟ راه‌حل‌های پیشنهادی برای این مسئله نیز در این پست آمده است.


  • کامپایلر مایکروسافت برای پایتون

    30 Apr 2014

    به نام خدا

    مقدمه

    اخیراً شروع به کار با زبان پایتون کردم. خیلی سبک زبان رو نپسندیدم، بخصوص با dynamic بودن هنوز کامل کنار نیامده‌ام. ولی زبان پایتون جامعه‌ی بسیار بزرگی دارد و نتیجه‌ی این جامعه‌ی بزرگ پروژه‌های باکیفیت و پرتعداد و پرکاربردی است که برای این زبان و با این زبان ایجاد شده‌اند. همین کتابخانه‌ها برنامه‌نویسی را برای انجام بسیاری از کارها آسان می‌کند.

    برای نصب کتابخانه‌های مختلف برای این زبان، راه‌های مختلفی وجود دارد. مشهورترین این راه‌ها pip و easy_install است. همچنین با استفاده از conda نیز می‌توان این کار را برای بعضی از کتابخانه‌ها انجام داد.

    ولی راه اصلی نصب بسیاری از کتابخانه‌ها، استفاده از دستور زیر است:

    >> python setup.py install
    

    فایل setup.py در همه‌ی پروژه‌ها وجود دارد، و در واقع این فایل توسط توسعه‌دهندگان هر کدام از این کتابخانه‌ها نوشته می‌شود. با استفاده از این دستور می‌توان کتابخانه‌ی مورد نظر را به لیست پایتون اضافه کرد.

    پایتون به زبان C نوشته شده است و برای سرعت‌گرفتن، قسمت‌هایی از کد را می‌توان به زبان C نوشت و در کد پایتون استفاده کرد. همچنین پروژه‌ای همانند Cython می‌تواند کد پایتون را به کد C تبدیل کند.

    مشکل

    در هنگام نصب بعضی از پروژه‌ها، لازم است قسمتی از کد توسط یک کامپایلر C کامپایل شود. برای این کار باید پایتون بتواند کامپایلر درست نصب شده و تنظیمات مناسب را تشخیص دهد. اگر این مشکلی در این کار پیش بیاید، خطایی مانند زیر در هنگام نصب کتابخانه نمایش داده خواهد شد:

    Error:unable to find vcvarsall.bat
    

    این خطا بخصوص در ویندوز احتمال ظهور بیشتری دارد! برای اینکار راه‌حلی پیشنهاد می‌شود که در ادامه توضیح آن را خواهم داد.

    راه‌حل

    در مسیر زیر فایلی به نام distutils.cfg وجود دارد

    %PYTHONDIR%\Lib\distutils\
    

    اگر هم این فایل موجود نباشد، آن را ایجاد کنید. محتویات آن را به صورت زیر تغییر دهید:

    [build]
    compiler=msvc
    

    %PYTHONDIR% مسیر نصب پایتون می‌باشد. مسیر پیش‌فرض مسیر زیر می‌باشد:

    C:\Python27
    

    تنظیمات بالا با فرض این است که کامپایلر مایکروسافت بر روی سیستم نصب باشد. اگر ویژوال استودیو داشته باشید کامپایلر نصب می‌باشد. اگر کامپایلر ویژوال استودیو ندارید می‌توانید نسخه‌ی Express ویژوال استودیو را دریافت و نصب کنید.

    حال به مسیر زیر بروید:

    %PYTHONDIR%\PCbuild\
    

    در این پوشه فایل زیر را ایجاد کنید

    msvcr<num>.def
    

    که منظور از <num> یک شماره است که بر اساس نسخه‌ی ویژوال استودیو تعیین می‌شود

    • Visual Studio 2008 -> 90
    • Visual Studio 2010 -> 100
    • Visual Studio 2012 -> 110
    • Visual Studio 2013 -> 120

    حال در فایل ایجاد شده دو خط زیر را بنویسید:

    LIBRARY MSVCR<num>.dll
    EXPORTS
    

    با انجام این کارها به احتمال زیادی مشکل کامپایل‌شدن کدهای C برای پایتون حل خواهد شد.


  • Spectrogram

    به نام خدا

    Exponential Chirp Spectrogram Exponential Chirp Spectrogram

    (Creative Commons Attribution-Share Alike 3.0 Unported license (CC BY-SA 3.0), from Wikimedia Commons)

    معرفی

    برای بررسی ساختار فرکانسی سیگنال‌های متغییر در زمان، از روشی به نام تبدیل فوریه‌ی کوتاه-زمان (STFT) استفاده می‌شود. با استفاده از این نوع تبدیل فوریه می‌توان به اطلاعات فرکانسی و فازی ناحیه‌ای کوتاه از سیگنال پی برد. در حالت پیوسته، این تبدیل از رابطه‌ی زیر به دست می‌آید:

    $$ \text{STFT} ‎\lbrace x(t) ‎\rbrace (\tau ,\omega ) \equiv X ( \tau ,\omega ) = \int _{-\infty }^{\infty} x(t)w(t-\tau )e^{-j \omega t}dt $$

    که تابع \( w(t)\) تابع پنجره می‌باشد.

    رابطه‌ی تبدیل فوریه‌ی کوتاه-زمان برای حالت گسسته نیز مشابه می‌باشد.

    $$ \text{STFT} \lbrace x[n] \rbrace (m,\omega )\equiv X(m,\omega )=\sum _{n=-\infty }^{\infty } x[n]w[n-m]e^{-j \omega n} $$

    برای تهیه‌ی اسپکتروگرام، سیگنال به بازه‌هایی با طول کمتر از طول سیگنال تقسیم می‌شود (لزومی ندارد این بازه‌ها مجزا باشند)، برای هر کدام از این بازه‌ها تبدیل فوریه محاسبه می‌شود، و سپس اندازه‌ی این تبدیل فوریه برای بازه‌های مختلف در کنار یکدیگر قرار می‌گیرد تا تصویری دو یا سه بعدی از اسپکتروگرام سیگنال اصلی ایجاد شود.

    پیاده‌سازی

    (نمونه کدها، به زبان متلب می‌باشند)

    برای ایجاد نمودار اسپکتروگرام برای یک سیگنال، ابتدا لازم است سیگنال را به تعدادی بازه تقسیم کرده و سپس برای هر بازه، ضرایب فوریه را محاسبه نماییم. در نهایت با جمع‌آوری همه‌ی این ضرایب به دست‌آمده، می‌توانیم نمودار آبشاری اسپکتروگرام را رسم کنیم.

    کد زیر یک پیاده‌سازی ابتدایی برای این کار است:

    function specPlot(x, windlen)
    % x: input signal
    % windlen: length of the time window inside which fourier coefficients will be calculated, note that since our signal is real, only half of the coefficients are needed
    
    % preallocating magnitude matrix for speedup
    numofwinds = floor(length(x)/windlen);
    magnitude = zeros(numofwinds, floor(windlen/2));
    for i = 0:(numofwinds - 1)
           startIdx = i*windlen;
           partfft = abs(fft(x((1+startIdx):(startIdx+windlen))))/windlen;
           magnitude((i+1),:) = partfft(1:length(partfft)/2);
    end
    waterfall(1:windlen/2, 0:(length(x)/windlen -1), magnitude);
    xlabel('frequency');
    ylabel('time');
    zlabel('magnitude');
    end
    

    حال این توابع را بر روی یک سیگنال نمونه امتحان می‌کنیم.

    سیگنال زیر را که یک سیگنال جیر با رابطه‌ی \( y=sin(1600\pi t^2) \) می‌باشد در نظر بگیرید. نمودار این سیگنال به صورت زیر است:

    Chirp Plot, limited

    Chirp Plot

    >> t = [0:1/8000:1-1/8000];
    >> y = sin(2*pi*800*(t.*t));
    >> specPlot(y,800);
    

    با اجرای دستور آخر نمودار زیر ایجاد خواهد شد

    Spectrogram waterfall plot