All streams
Search
Write a publication
Pull to refresh
6
0.2
Жораев Тимур Юлдашевич @TimurZhoraev

Доцент института МПСУ им. Л. Н. Преснухина

Send message

Вы совершенно правы, что нужно использовать линейную частоту вместо синонимов круговая-циклическая. Однако, небольшой экскурс даёт повод для сомнений, зачем множить сущности, если достаточно круговой. И тут можно выяснить, что циклическая определяется как заданное количество циклов за определённое время, в частности, по умолчанию, за 2π секунд, если не оговорено особо, но никто не запрещает, по всей видимости, это время задать самостоятельно. На это подтолкнул прямой перевод и ключевая фраза "Cyclic frequency", что даёт "Cyclic frequency refers to the frequency at which a signal's statistical properties repeat themselves, also known as a cyclostationary signal" и даже обозначается как α, однако, имеет отношение скорее к статистике см. "Cyclic Frequency in Signal Processing". Вообщем это не баг а фича для размышлений.

Спасибо, Евгений! Совершенно верно. Пусть ошибка останется в публикации, как тренировка по составлению уравнений. Действительно, для второго узла необходимо было записать уравнение

Ошибка в системе - найдено
Ошибка в системе - найдено

Ну и конечно же всё получается как надо.

Тем не менее, метод подходит даже для "ошибочных схем". Для исправленного варианта получается предложенным методом амплитуда в точке 2 кГц 1.1484, фаза (результирующая!) -162°. SPICE модель даёт -121°, так как используется отношение выхода ко входу, при этом теряется фаза исходного сигнала, разница как раз составляет 40°. То есть при наличии параметра фазы во входном сигнале симулятор при анализе ФЧХ даст характеристику, как если бы начальная фаза входного сигнала была нулевой. Поправьте если это не так. Хотя лучше было бы если Probe в конкретной точке показывал полную фазу с учётом фазы входной ЭДС.

Схема нужна была для того чтобы сформировать некоторую передаточную функцию и сравнить это с моделью.
По символическому анализу также можно найти SNAP, SymPyCAP, Sapwin, ELABorate, и другие скрипты для вытаскивания схемы из нетлистов.

Угловая - это скорость изменения угла в рад/с, циклическая - частота соответствующая одному циклу (периоду), поэтому в Гц. Ранее в книгах писали "Megacycles per second" MCps или тоже самое что МГц. Может быть circle и cycle в этом случае их сделали синонимами. Поэтому, чтобы не путаться, в данном случае явно было принято разделить круговую как рад/с и циклическую в Гц в пределах области видимости публикации. Кстати в SPICE-моделях m и M - это милли, meg, MEG - это мега, очень часто на этом возникают ошибки.

Вот кстати здесь Вы правы, что код, или текст, который был сгенерирован человеком или инструментом на основе ИИ, надо (а надо ли?) будет уметь различать. Но с точки зрения практической реализации, вполне себе можно использовать, если сформированный код компилируется и выполняет возложенные функции в заданных границах с автоматическим тестированием или имеет ключевые слова для решения задачи. Значимый результат - дообучение как обратная связь. И тут как раз сложные языки, с избыточными с точки зрения диалога с ЭВМ сущностями IMHO начинают проигрывать. Классы-наследование, функциональный подход, HDL-подобные языки, описывающие системы с событиями - это изобретения для человека, удобства проектирования и представления в голове целостной структуры проекта на языке... предметной области. Для машины не важно какие биты она перемалывает, важно то, чтобы она это делала оптимально по выбранному критерию, например, по соотношению время-память. И скорее эволюция сделает очередной виток с Basic-ом, Python-ом, обычным С, Verilog, LISP-Fortran, и даже визуальными языками такими как UML/LabView/Simulink, так как всё остальное будет отдано на растерзание оптимизатору с ИИ, благодаря гораздо более простой внутренней структуре результатов парсера в виде AST и его токенизации и к этому надо основательно готовиться.

Этот пример был приведён для того, что сложность языка дополняется сложностью задач для которых его применяют, включая аппаратуру. То есть курс "С++ за N дней для начинающих" и "С++ Embedded за M часов для юнатов" должны отличаться опытом длиной в X лет. Больше возможностей - относительно расплывчатая формулировка, например, уменьшается время внедрения новых сущностей в проект, удобство документации, командной разработки, меньшие требования к кандидатам на проект, вылавливание ошибок на этапе компиляции, простота отладки, наборы инструментов для профайлинга, визуализация данных. "Пишите программы, которые пишут программы" - (точно не помню где слоган был Керниган-Ричи или Пайк) скорее это и есть тот искомый сбалансированный инструмент для аппаратуры, наподобие GUI-генераторов инициализации контроллеров. Равно как первые плюсовые компиляторы, которые транслировали код на С. А что касается классического примера со статическим UI это скорее MFC/Borland образца 90-х с соответствующей рисовалкой ресурсов. То есть плюсы и этот подход в наибольшей мере сочетаются и не требуют особое обилие скиллов для достижения заданного результата, который даётся даже проще и быстрее чем Win32. Вообщем С++ без полного следования ООП (включая процесс проектирования на "бумаге" а-ля CRC-карточки и прочий UML) это С с классами. А также, С++ - это ещё и практически неотъемлемая инфраструктура в виде стандартной библиотеки. И именно в этом русле раскрывающий все свои преимущества, особенно, если проект дополняется сторонними средствами, без которых действительно потом страшновато разбирать и поддерживать код/данные, и не прибегать постоянно к приложениям из разряда "Understand for C++" и прочим Code Analysis.

Абсолютно верно. Особенно если приправить всё это register, volatile, и другими вроде как не выходящими за границы стандарта сущностями, включая карты линковки или директивы "размести элементы стандартной библиотеки в RAM, так как она быстрее флеша", контроль стека при рекурсии, при работе с оборудованием, периферией, DMA, это превращается в тот ещё квест, особенно когда появились соседние ядра. И вот тут дилемма С или С++. Вообщем С++ лучшим образом подходит скорее для статических UI, заранее заданных жёстких и строгих иерархий, обработки классов функциями требующих хорошее почти фортрановское быстродействие в одном потоке, для обработки пакетов с фиксированной иерархией данных. То есть баланс между временем на поддержание ООП, чтобы можно было что-то вклинить не сильно переписывающее весь код, файловую структуру, систему сборки, и быстродействием. Плюсовые thread-safe очереди-семафоры, мутексы, шедулеры скорее не цель а нечто, что генерируется из более высокого уровня как заведомо проверенное решение.

Вот тут может быть UB с точки зрения реализации. Если bool выполнен как один бит из ячейки в 32 бита, а компилятор вдруг решил что ему достаточно 2 команды по 16 бит, то на прерываниях между этими командами возможна редкая ситуация Read-Modify-Write, при чтениях и записях флажка из асинхронных событий. Тем более этот вектор вряд ли компилятор упаковывает эти булы в битовое поле, но с другой стороны исключается возможность модификации соседнего флажка из-за этой проблемы.

Именно так за небольшим нюансом. Г. Буч (ООП с использованием С++) подвёл некий базис под это и не отделяет наследование от поведения объектов (т. е. виртуальные функции обязательны, хотя бы одна), которые обладают состоянием, поведением и идентичностью. Иначе это просто структура в структуре и в полной мере им не является, хотя и допустимо, но это весьма условно. То есть при отсутствии наследования функций технически компилятор может не вводить неявное поле типа (идентификатор) в класс (ad-hoc полиморфизм и перегрузка также не задействует этот механизм). Кстати в нулевые были ещё пара ключевых книг, которые основательно определяли то что указано автором темы и кристаллизовали те проблемы, которые актуальны до сих пор вот уже на протяжении третьего десятка лет: С. Мейерс "Наиболее эффективное использование C++. 35 новых рекомендаций по улучшению ваших программ и проектов". И ещё одно издание этого же автора "Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ". Вот там как раз взаимосвязь языка с файловой системой, проблемы с компиляцией, то есть то что выходит за рамки языка и отнимает кучу времени в плане организации процесса проектирования.

Было бы неплохо сделать обзор может даже по условным git-проектам где есть примеры решения задач где используются концептуальные преимущества языка или по содержанию "диска прилагаемого к книге". В основном сейчас лучше изучить концепции из разряда "наследование - это неявное дополнительное поле типа, соответствующее номеру класса по желанию компилятора плюс массив указателей на процедуры или switch-case, реализующие виртуальные функции согласно этому полю", "рекурсия - это неявный стек, который располагается не совсем вручную", ну и разумеется механизмы лямбда, различных темплейтов что это не просто синтаксический сахар и форма макросов, и, конечно же, dynamic_cast и как правильно его готовить чтобы не было сегфолтов.

А кто помнит знаменитую надпись "Cracked by Bill Gilbert"

Просто воспоминания, что не менее увлекательный был процесс перебора от 0 до N ради поиска чего-то необычного кроме рэзета и сессии ТР-ДОСа, особенно если был музыкальный сопроцессор, те самые AY в довесок. А с PEEK/POKE можно было составить свою первую прогу на асме в машинных кодах, записать её на ленту. Плюс различные фишки связанные с бордером. Не только стандартные цвета загрузчика M/C/B/Y но и кастомные. Плюс различные утилиты для быстрой загрузки когда высокий битрейт превращал звук в шипение. Не говоря уже про эксперименты с circle/draw, когда круги рисовались заливкой треугольниками в динамике, как целая игра.

Да, это отдельная история из разряда ++ *, особенно если имеются флажки насыщения в процессорах ЦОС (причём переключаемые динамически в любой момент) вместо переполнения и прочие UB. Это скорее компромисс между комитетом ISO/ANSI, имеющимся исторически сложившимся железом и пожеланиями пользователей. В этом случае используются только математические конструкции или алгоритмическое ветвление без UB, в остальном - только intrinsics и прочие штуки вне стандарта. Хотя бывает и так что char = 16 бит на C[5,2]000 DSP-шках. Плюс арифметический-двоичный сдвиг влево-вправо с учётом и без учёта знака и системы (дополнительный, прямой) особенно там где совсем простое железо. Вообщем лучшие гарантии даёт именно стандарт где математика явно прописана и все ограничения с ней связанные 127+1=-128
PS. Кстати стандарт языка это очень сильная позиция, которая, скорее всего превалирует перед включением Rust в ядро Linux например и другими не стандартизированными вроде Python/Perl/Java/JS и др.

Скорее всего речь уже идёт не строгих языках а фактически тех которые имеют характер описания и разметки. Вообщем эра текстовых редакторов уровня перевод строки и возврат каретки 0D0A ◙♪ с виртуальной машиной, определяемой первой двадцаткой управляющих символов ASCII уходит в прошлое, и то, что мы видим на экране есть результат отображения уже обработанного абстрактного синтаксического дерева. В этом случае ИИ тренируется уже не на слова/мнемоники а на представление алгоритма, данных в виде соответствующего дерева. Любой компилятор неявно содержит в себе модель вычислителя как на HDL-языке с разметкой количества тактов, целостности кэша, работы с аппаратурой.

Не мене увлекательная игра была с randomize usr 0 или randomize usr 15616. Кстати тот самый редактор Бэйсика FOR a=1 to � с мигающим вопросиком это фактически то что так не хватает современным IDE.

Да, также можно дополнить обработкой факторизацией и схемой Горнера общей формулы самого фильтра как суммы взвешенных отсчётов, в этом случае оптимизация может проводится уже в пространстве состояний по отсчётам (z⁻¹), например, сохраняя промежуточные значения в регистрах/памяти и далее уже применяя арифметические сдвиги в нужных местах. Ещё вдобавок решив проблему динамического диапазона и нормировки по ходу вычислений, что-то вроде (x₋₁+x₋₂)/2 = (2x₋₁+x₋₂)/2-x₋₁/2, чтобы не потерять разряды, особенно для полосовых фильтров и прочих высокодобротных штуковин.

Да действительно там есть инструкция MUL которая позволяет делать 16*16=16 за 9 тактов плюс ret и 16*16=32 за 17 тактов. Тут же говорится о том чтобы вообще не использовать данную инструкцию, например на каком-нибудь Attiny где умножение занимает сотни библиотечных тактов ну или знаменитый Z80. Интерес в том числе представляет в принципе подобного рода оптимизация на основе фиксированных значений коэффициентов, включая, например, возможную реализацию "гладкой" функции активации для нейрона с оптимальной для градиентного метода (производная есть сама функция) формой что-то вроде 1/(1+2^-x) - логистическая, с 2 вместо экспоненты, тогда алгоритм будет заключаться в сдвиге на заданное количество разрядов согласно старшей единице в операнде.

В данном случае речь идёт о расчёте коэффициентов фильтра, равным степени двойки, при которых он заведомо будет упрощён по количеству операций. Конечно же если компилятор достаточно "умный", то в коде выше можно вместо >>1 написать /2 или возможно даже int(a*0.5) и он оптимизирует, но лучше не рисковать и указать явную операцию << или >>, она практически выглядит как intrinsic-инструкция в коде, в этом случае язык С выглядит как "аппаратно-независимый ассемблер". Плюс в указанном методе без изменения структуры фильтра можно дискретным образом изменять полосу пропускания. Хотя, это если имеется инструкция ASR/ASL на заданное количество бит (Barrel shifter), в архитектуре AVR, например, сдвиг происходит только на один бит без параметра. CIC фильтр также требует большой динамический диапазон для вычислений вида ∞-∞ из-за наличия каскада интеграторов, в предлагаемом варианте этот диапазон ограничен лишь старшим разрядом.

Вообще говоря выглядит как хороший полуфабрикат для генерации чего бы то ни было с использованием некоего PerlScript-а, который штампует заголовочники с #embed. Потенциально настроечно-конфигурационные макросы и CMAKE будут хорошенько пересмотрены. На очереди встроенный Bison-Flex и Regexp как вишенка.

Ну тогда получается 2 вида квантования - по времени (что скорее образно и не вполне корректно) и по уровню, когда сигнал принимает значение соответствующее разрядной сетки (не обязательно линейной с шагом 2^-N, например для float с мантиссой и экспонентой она нелинейная, зато большой динамический диапазон).

Примерно тоже самое, но только с фиксированной частотной характеристикой без параметра + использование временных переменных состояния. Скорее всего это тоже самое, для 2-го порядка. В этом случае используется 3 точки, например на 0й частоте, Найквиста и какая-либо выделенная частота, при которой коэффициенты кратны степени двойки. Например, мнимая часть в этой точке равна нулю (полосовой) или обе одновременно (режекторный). Как раз там возникают те самые "рысканья", для первого порядка - статическая ошибка как сказано в статье. Однако, можно последовательно соединить ФНЧ и ФВЧ чтобы получить полосовой в некоторой мере, и тут уже возможны варианты. Ну а далее схема Горнера и прочие алгебраические преобразования чтобы вынести необходимые степени двойки за скобки и использовать переменные состояния.
Есть ещё более "хитрые" способы, заключающиеся в применении метода Ньютона-Рафсона, у того же Техаса, который для C2000 с фиксированной запятой реализует деление с уточнением по таблице, вычисление синусов-косинусов по таблице с интерполяцией рядом Тейлора в окрестности заданной табличной точки (описание вроде в sprc993), ну и конечно же CORDIC. Логарифмический масштаб скорее для количественного описания, здесь же отображение качественных характеристик, не имеющих промежуточных значений, да и на частоте Найквиста значение точно равняется нулю, там логарифм убегает в -∞.

Information

Rating
2,491-st
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Hardware Engineer, Research Scientist
Senior
From 300,000 ₽
Applied math
Software development
Code Optimization
C
Assembler
Python
Algorithms and data structures
Object-oriented design
Multiple thread
Verilog HDL