Обновить
2
Жораев Тимур Юлдашевич@TimurZhoraev

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

0,2
Рейтинг
6
Подписчики
Отправить сообщение

скорее всего будут нормальные векторные модели, которые собственно вмещают пару десятков килобайт описания из разряда выдавить, продавить сопряжение, касательность и прочие зависимости. Модель вполне может сделать синтез по граничным условиям. Тот же OpenSCAD текстовый вполне себе годен. Промпт: OpenSCAD сделать зубчатое колесо аналог эвольвенты без библиотек 12 зубьев центральное отверстие шпонка сопряжение другое зубчатое колесо 16 звеньев центральный вал
Результат

Код
// --- Parameters (Change these) ---
m = 2;              // Module (Size of teeth)
z1 = 12;            // Gear 1: 12 teeth
z2 = 16;            // Gear 2: 16 teeth
thick = 10;         // Gear thickness
d_shaft = 8;        // Shaft diameter
k_w = 3;            // Keyway width
k_h = 1.5;          // Keyway depth

// --- Calculations ---
$fn = 60;
pa = 20;            // Pressure angle
pitch_dist = m * (z1 + z2) / 2;

// --- Main Module (No Library Needed) ---
module simple_gear(z) {
    pitch_radius = (m * z) / 2;
    addendum = m;
    dedendum = 1.25 * m;
    
    outer_radius = pitch_radius + addendum;
    inner_radius = pitch_radius - dedendum;

    difference() {
        union() {
            // Base Cylinder
            cylinder(r = inner_radius, h = thick);
            
            // Generate Teeth
            for (i = [1:z]) {
                rotate([0, 0, i * (360/z)])
                translate([pitch_radius, 0, thick/2])
                // Simplified trapezoidal tooth
                cube([m * 2, m * 1.2, thick], center=true);
            }
        }

        // Shaft Hole
        translate([0, 0, -1])
            cylinder(d = d_shaft, h = thick + 2);

        // Keyway (Slot)
        translate([-k_w/2, d_shaft/2 - 0.5, -1])
            cube([k_w, k_h + 1, thick + 2]);
    }
}

// --- Render Assembly ---

// Gear 1
color("Cyan") 
    simple_gear(z1);

// Gear 2 (Positioned to mesh)
translate([pitch_dist, 0, 0])
rotate([0, 0, 180/z2]) // Rotate to fit teeth
color("SpringGreen") 
    simple_gear(z2);

Центральный вал конечно пропустил но про шпонку уже представление имеет

Проблема в том, что много кода созданного человеком для человека. И все эти технологии которые сейчас имеются фактически дожатие того что было сделано до появления ИИ. Как только будет код "do not edit machine generated" дело уже пойдёт лучше, да и язык это будет не те которые сейчас лучше всех а те которые специально адаптированы для ИИ с наименьшими глюками и ошибками

Вообще говоря главная пропасть - между просто данными для обучения и подготовленными человеком датасетами. Это отдельное искусство сформировать нужные шаблоны обучения.

Попробуем проиллюстрировать с использованием "высокоэнтропийного" вайбкодинга что же произошло с Землей на начальном этапе лунной программы.
Модель:
Язык змей горыныч модель окружность 1 окружность 2 навстречу друг другу диаметры отношение один к четырём окружность есть 64 точки отрезков аппроксимация каждый отрезок масса отрезки связаны в точках использовать сохранение импульса закон Ньютона столкновение без рассеяния отрезки между собой закон Гука пружинят конечные разности расчёт шаг счёта по времени примерно одна окружность в секунду использовать матплотлиб визуализация

Реализация
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# Параметры системы
N = 64              # Точек в окружности
dt = 0.002          # Шаг по времени
k_spring = 8000.0   # Жесткость пружин
m_point = 0.1       # Масса точки
damping = 0.05      # Вязкое трение (стабилизация)

def create_ring(R, offset_x, velocity_x):
    angles = np.linspace(0, 2 * np.pi, N, endpoint=False)
    pos = np.zeros((N, 2))
    pos[:, 0] = offset_x + R * np.cos(angles)
    pos[:, 1] = R * np.sin(angles)
    vel = np.full((N, 2), [velocity_x, 0.0])
    return pos, vel, R

# Инициализация (диаметры 1 к 4)
pos1, vel1, r1 = create_ring(1.0, -3.5, 5.0)
pos2, vel2, r2 = create_ring(4.0, 3.5, -5.0)

def get_forces(pos, r_orig):
    forces = np.zeros_like(pos)
    rest_len = 2 * r_orig * np.sin(np.pi / N)
    for i in range(N):
        p_curr = pos[i]
        p_next = pos[(i + 1) % N]
        diff = p_next - p_curr
        dist = np.linalg.norm(diff)
        f_mag = k_spring * (dist - rest_len)
        f_vec = f_mag * (diff / dist)
        forces[i] += f_vec
        forces[(i + 1) % N] -= f_vec
    return forces

# Подготовка анимации
fig, ax = plt.subplots(figsize=(10, 6))
ax.set_xlim(-12, 12); ax.set_ylim(-6, 6)
line1, = ax.plot([], [], 'r-o', lw=1, ms=2)
line2, = ax.plot([], [], 'b-o', lw=1, ms=2)

def update(frame):
    global pos1, vel1, pos2, vel2
    
    # Расчет сил и столкновений за несколько микрошагов для стабильности
    for _ in range(5):
        f1 = get_forces(pos1, r1) - damping * vel1
        f2 = get_forces(pos2, r2) - damping * vel2
        
        # Столкновение (упрощенно: проверка расстояния между узлами)
        for i in range(N):
            for j in range(N):
                dist_v = pos1[i] - pos2[j]
                if np.linalg.norm(dist_v) < 0.25:
                    # Закон сохранения импульса (m1=m2): усреднение скоростей
                    v_avg = (vel1[i] + vel2[j]) / 2
                    vel1[i] = vel2[j] = v_avg
        
        # Интегрирование
        vel1 += (f1 / m_point) * dt
        pos1 += vel1 * dt
        vel2 += (f2 / m_point) * dt
        pos2 += vel2 * dt

    line1.set_data(np.append(pos1[:, 0], pos1[0, 0]), np.append(pos1[:, 1], pos1[0, 1]))
    line2.set_data(np.append(pos2[:, 0], pos2[0, 0]), np.append(pos2[:, 1], pos2[0, 1]))
    return line1, line2

ani = FuncAnimation(fig, update, frames=200, interval=30, blit=True)
plt.title("Модель Змея Горыныча: столкновение упругих колец (1:4)")
plt.show()

Почти в точку. Сейчас все бизнес-проекты будут не то как попасть в индексацию поисковика а как угодить в RAG и прочие MCP по ключевым тегам не говоря уже о попадании в претренинг когда о компании знает уже сама модель на захардкоженном уровне. Влезть в эту тему на этапе становления - это почище битка.

и правильно делают, они учатся языку промптов, и глючить вместе с ИИ, чтобы не делать плохих запросов. Плюс это отличная обратная связь для развития датасетов претренинга

В своё время читал Гради Буч - Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 1999 год, спустя 27 лет актуально и сейчас. Так вот там объект - это нечто, обладающее состоянием, поведением и идентичностью (искал в тексте эти ключевые слова). А для ООП обязательно имеют иерархию наследования и динамическое поведение, грубо говоря таблицу виртуальных функций, представляющую неявное поле типа данных (индекс). С++ скорее просто обогатился синтаксисом из интерпретируемых языков нежели вобрал уж прям нечто совсем концептуальное, ad-hoc полиморфизм уже был тогда, просто сейчас это выглядит как некий макрос с удобной формой записи, как декоратор на Питоне, вобравший assertion. Как только на С++ видится что-то вроде std::memcpy или sizeof(*this) или dynamic/reinterpret_cast или operator x (float16,int8) - это повод взять вновь K&R С, шлифанув пары malloc-free или mutex ИИ-шкой, попросив дописать разрядность к имени функции.

Лучше составить таблицу в которой будет представлено количество работы с кодом, файловой системой и уровни ошибок - системное проектирование, синтаксис, доступ (не найдено) в ответ на количество действий разработчика.

Кто будет читать это через 10 лет вопрос: что спереди, телега или лошадь?

Можно также с генератором.

x, y = 250, 250
gen = (x + i is y + i for i in range(11))
for result in gen:
    print(result)

Интересно также что это работает со строками

v = '100' 
x = int(v)+1
y = int(v)+1
print(x is y)

оказывается true

Что-то никак нет ухода от крайностей - текстовый редактор уровня "консоль" и чистый WYSIWYG, нужно что-то среднее между LaTeX и окончательной вёрсткой. То есть должна быть полная взаимосвязь между элементами того что в графике и сам текст хотя-бы имел минимальный скетч из атрибутов - положение, размер шрифта даже если это моноспейс, верхний-нижний индекс. Тогда в окончательную вёрстку попадает полный стиль набор а в промежуточную только прибитое к некоторому условному форматированию. Тоже самое про программирование разделов, нумерации, глав итд. В ворде это сделано как линейный список, годный только для книг. Для более сложной документации содержащей перекрёстные ссылки этот подход не годен, в этом случае там нумерация будет почти как вручную текстом просто сгенерированная автоматически.

Так инструмент в данном случае совершенно искусственный и вообще говоря не ясно какова его актуальность в текущих реалиях. Это как есть куча оснастки для ремонта паровозов но насколько это востребовано сейчас если это конечно не ниша. Но есть другой нюанс на этот счёт. Можно взять идеальный современный ручной инструмент с вырезами под любые пальцы, мягкими накладками, приятно держать, а можно паровозошморгалку, обычную отбойную отвёртку из прошлого века, которая делает тоже самое и вручить её роботу. Она совершенно устарела и неудобна для человека, но зачем спрашивается ему делать задание лично когда есть такой вот помощник, который в принципе неплохо справляется и руки точно не порежет, на крайний заменить можно хоть целиком.

Именно! Так зачем теперь нужно дополнять ценные гигаватт-часы на дополнительные новомодные триллионы токенов, когда банальный С вытягивает 100% проблем. Да, человеку неудобно, а кто сказал что там что-то нужно читать и знать когда есть 100500 различных парсеров, тестов, санитайзеров, которые генерируются или обвязка для которых налету llm-кой. Вплоть до питона, который анализирует С, делает заголовки и код С, заготавливает метрику, отправляет в LLM, делает автоматом рефакторинг, с файлами -конфигами больше уже нет необходимости возиться, да и версия кода не есть версия текста программы по большому счёту. Это про комментарии и их хранилище с нагенерённой документацией и summary от LLM.

Позвонить в сервис, попросить чтобы дали задание написать мануал для LLM с годной векторной базой данных. Старые мануалы скорее переживают суровый закат, всевозможные языки разметок чтобы быть покрасивее, все эти md, man, hlp, да ещё и не векторные и не структурированные рисунки. Машинно-ориентированный мануал это фактически генератор знаний по запросу. Линейные книги и html-ки это уже прошлый век.

Проблема скорее в формализации качества. Новая фишка должна либо быть более понятной, более безопасной, уменьшить время на её обучение, на разработку, величину кода, его эффективность. Все языки как раз состязались именно чтобы быть приятными человеку, машине всё равно что там написано. Когда же пришла LLM это соревнование потеряло смысл и проще взять совершенно базовые вещи языков высокого уровня которые становятся просто ассемблером для LLM. И чем лаконичнее язык в плане грамматики и синтаксиса тем лучше. В конечном итоге это С (с диалектами CUDA, шейдеры, OpenCL, OpenMP...), Питон, Бэйсик, Фортран, ЛИСП, Verilog ну и ещё что-то из разряда Maxima, Maple, Mathematica. Оркестрируя этим делом можно составить приложение любой сложности.

Чем больше синтаксического сахара - тем больше можно получить случайной соли.

Поэтому и хорош С, что его можно попарсить всем чем угодно и вытащить сам алгоритм - отследить все вызовы malloc-free и где они вызываются и в каком порядке, промптом можно даже попросить сделать смартпойнтер или глобальный стек для отладки, вывод которого скормить той же модели для анализа если там вдруг двойной фри на указатель или указатель без фри. Если этот довесок невозможен ввиду того что это одноплатный процессор на логике 555й серии - можно попросить создать на питоне виртуальную машину с вызовами и моделью поведения, как на верилоге.

так нужно генерировать неправильный код на очень хорошей платформе, который будет генерировать правильный код на плохой. Иными словами кто мешает сгенерировать питон который будет следить за дефайнами, стимулусами, тестбенчами и прочими do-файлами со времён tcl tk, и иже с ними имеющие кодовую базу в тератокены. То есть он будет делать C-вставки в проект, включая парсинг самих C-файлов проекта тем же cparcer. В этом и заключается сила простых языков с точки зрения промптинга и анализа что для них есть превосходные инструменты для обратных связей - вытаскивать структуры, определения, функции итд и встраивать то что необходимо, включая тесты. Изолированная единица с параметром - и настраивай как угодно, остальные имеют те же питон модели поведения, не обязательно всё возлагать на один язык. Достаточно промоделировать и использовать сгенерированный код. В ту же копилку и DMA с режимами работы, потокобезопасные очереди, всевозможные контроллеры прерываний с приоритетами итд

Для решения проблемы с динамической памятью можно использовать штатный санитайзер gcc или просить модель сделать smart pointer даже на простом С. Вообще говоря этот язык переживёт с LLM второе рождение, так как все новомодные фишки которые появились за последнее десятилетие в языках и призванные синтаксисом улучшить читабельность для человека уйдут на второй план, так как контроль за надёжностью и управлением памяти как раз может взять на себя модель, мало того, сугубо компилируемые языки разрослись до уровня интерпретаторов, для нововведений нет кодовой базы для глубокого обучения. Более того, стиль написания скриптов будет примерно такой, как новый язык. Известно, что в моделях есть "температура", а значит, и "энтропия" (cross-entropy). Поэтому промпт-ТЗ должно предельно иметь её высокое значение относительно алгоритма без лишней составляющей. Пример для простого С, используемого как ассемблер для промпта. Сделаем цифровой фильтр с динамической памятью.


Практикум вайб-курса цифровой обработки сигналов в одном Хабр-комментарии. Промптим код без демонов Максвелла с хорошей энтропией:

Язык С мэйн иметь флоат два массива cx и x длина nx два массива cy и y длина ny объединить одна структура глобальная поля структура сделать маллок область видимости выход фри. Инициализация x и y ноль. Мэйн внутри цикл отсчёты внутри аккумулятор ноль первый элемент x равно константа цикл по элемент массив cx и x умножение с накоплением цикл по элемент массив cy и y аккумулятор минус умножение с накоплением. Сохранить аккумулятор первый элемент массив y. Сдвинуть элемент массив x и массив y один позиция вправо, инкремент индекса только использовать временная переменная тэ1 тэ2 обмен.

Код-скелет
#include <stdio.h>
#include <stdlib.h>

// Константы для примера
#define NX 3
#define NY 3
#define STEPS 10
#define CONST_VAL 1.0f

// --- Глобальная структура ---
typedef struct {
    float *cx;
    float *x;
    int nx;
    
    float *cy;
    float *y;
    int ny;
} FilterData;

FilterData g_data; // Глобальный экземпляр

int main() {
    // --- Выделение памяти (malloc) ---
    g_data.nx = NX;
    g_data.ny = NY;
    
    g_data.cx = (float*)malloc(g_data.nx * sizeof(float));
    g_data.x  = (float*)malloc(g_data.nx * sizeof(float));
    
    g_data.cy = (float*)malloc(g_data.ny * sizeof(float));
    g_data.y  = (float*)malloc(g_data.ny * sizeof(float));

    // --- Инициализация ---
    // Коэффициенты (для примера)
    for(int i = 0; i < g_data.nx; i++) { g_data.cx[i] = 0.5f; g_data.x[i] = 0.0f; }
    for(int i = 0; i < g_data.ny; i++) { g_data.cy[i] = 0.2f; g_data.y[i] = 0.0f; }

    printf("Starting processing loop...\n");

    // --- Основной цикл (Отсчеты) ---
    for (int t = 0; t < STEPS; t++) {
        float acc = 0.0f;
        
        // Первый элемент x равен константе
        g_data.x[0] = CONST_VAL;

        // Цикл по cx и x: умножение с накоплением
        for (int i = 0; i < g_data.nx; i++) {
            acc += g_data.cx[i] * g_data.x[i];
        }

        // Цикл по cy и y: аккумулятор минус умножение с накоплением
        // (Обычно пропускают y[0] в обратной связи, но делаем строго по описанию)
        for (int i = 0; i < g_data.ny; i++) {
            acc -= g_data.cy[i] * g_data.y[i];
        }

        // Сохранить аккумулятор в первый элемент y
        g_data.y[0] = acc;

        printf("Step %d: Result Y[0] = %.4f\n", t, g_data.y[0]);

        // --- Сдвиг элементов вправо с использованием временных переменных ---
        // Сдвиг x
        float te1 = g_data.x[0];
        for (int i = 1; i < g_data.nx; i++) {
            float te2 = g_data.x[i];
            g_data.x[i] = te1;
            te1 = te2;
        }

        // Сдвиг y
        te1 = g_data.y[0];
        for (int i = 1; i < g_data.ny; i++) {
            float te2 = g_data.y[i];
            g_data.y[i] = te1;
            te1 = te2;
        }
    }

    // --- Освобождение памяти (free) ---
    free(g_data.cx);
    free(g_data.x);
    free(g_data.cy);
    free(g_data.y);

    return 0;
}

Хотеть коэффициент cx массив как единица делить количество. Нужно первый коэффициент cy равно ноль. Ещё два коэффициент cy посчитать полюс устойчивость единичная окружность комплексная плоскость хорошо остальные ноль.

Догадайся что это IIR
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define NX 5
#define NY 5
#define STEPS 15
#define CONST_VAL 1.0f

typedef struct {
    float *cx;
    float *x;
    int nx;
    
    float *cy;
    float *y;
    int ny;
} FilterData;

FilterData g_data;

int main() {
    // --- Выделение памяти ---
    g_data.nx = NX;
    g_data.ny = NY;
    g_data.cx = (float*)malloc(g_data.nx * sizeof(float));
    g_data.x  = (float*)malloc(g_data.nx * sizeof(float));
    g_data.cy = (float*)malloc(g_data.ny * sizeof(float));
    g_data.y  = (float*)malloc(g_data.ny * sizeof(float));

    // --- Инициализация массивов ---
    for(int i = 0; i < g_data.nx; i++) {
        g_data.cx[i] = 1.0f / (float)g_data.nx; // Коэффициент 1/N
        g_data.x[i] = 0.0f;
    }

    // Инициализация cy нулями
    for(int i = 0; i < g_data.ny; i++) {
        g_data.cy[i] = 0.0f;
        g_data.y[i] = 0.0f;
    }

    // Расчет коэффициентов cy для устойчивых полюсов
    float r = 0.9f;         // Радиус (внутри единичной окружности)
    float theta = 0.5f;     // Угол (фаза)
    
    g_data.cy[0] = 0.0f;    // Первый коэффициент ноль по условию
    if (g_data.ny > 2) {
        g_data.cy[1] = -2.0f * r * cosf(theta); 
        g_data.cy[2] = r * r;
    }

    printf("cx[0] = %.4f, cy[1] = %.4f, cy[2] = %.4f\n", g_data.cx[0], g_data.cy[1], g_data.cy[2]);
    printf("--------------------------------------\n");

    // --- Основной цикл ---
    for (int t = 0; t < STEPS; t++) {
        float acc = 0.0f;
        
        g_data.x[0] = CONST_VAL;

        // Умножение с накоплением для x
        for (int i = 0; i < g_data.nx; i++) {
            acc += g_data.cx[i] * g_data.x[i];
        }

        // Вычитание умножения с накоплением для y
        for (int i = 0; i < g_data.ny; i++) {
            acc -= g_data.cy[i] * g_data.y[i];
        }

        g_data.y[0] = acc;

        printf("Step %d: y[0] = %.4f\n", t, g_data.y[0]);

        // --- Сдвиг x ---
        float te1 = g_data.x[0];
        for (int i = 1; i < g_data.nx; i++) {
            float te2 = g_data.x[i];
            g_data.x[i] = te1;
            te1 = te2;
        }

        // --- Сдвиг y ---
        te1 = g_data.y[0];
        for (int i = 1; i < g_data.ny; i++) {
            float te2 = g_data.y[i];
            g_data.y[i] = te1;
            te1 = te2;
        }
    }

    // --- Очистка ---
    free(g_data.cx);
    free(g_data.x);
    free(g_data.cy);
    free(g_data.y);

    return 0;
}

Принтф "импульсная характеристика" принтф формат CSV в файл "эксперимент" тэикстэ на дисплей тоже красиво табуляция массив цикл отсчёты.

ввод-вывод
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define NX 5
#define NY 5
#define STEPS 20

typedef struct {
    float *cx, *x, *cy, *y;
    int nx, ny;
} FilterData;

FilterData g_data;

int main() {
    g_data.nx = NX; g_data.ny = NY;
    g_data.cx = (float*)malloc(NX * sizeof(float));
    g_data.x  = (float*)calloc(NX, sizeof(float)); // Инициализация 0
    g_data.cy = (float*)malloc(NY * sizeof(float));
    g_data.y  = (float*)calloc(NY, sizeof(float)); // Инициализация 0

    // Настройка коэффициентов
    for(int i = 0; i < NX; i++) g_data.cx[i] = 1.0f / NX;
    for(int i = 0; i < NY; i++) g_data.cy[i] = 0.0f;
    
    float r = 0.95f;      // Полюс внутри окружности
    float theta = 0.4f;   // Угол
    g_data.cy[1] = -2.0f * r * cosf(theta); 
    g_data.cy[2] = r * r;

    FILE *f = fopen("experiment.txt", "w");
    if (!f) return 1;

    printf("Импульсная характеристика:\n");
    printf("T\tInput\tOutput\n");
    printf("--------------------------\n");
    fprintf(f, "Step,Input,Output\n"); // Заголовок CSV

    for (int t = 0; t < STEPS; t++) {
        // Импульс: 1.0 только в t=0, иначе 0.0
        float current_input = (t == 0) ? 1.0f : 0.0f;
        g_data.x[0] = current_input;

        float acc = 0.0f;
        for (int i = 0; i < NX; i++) acc += g_data.cx[i] * g_data.x[i];
        for (int i = 0; i < NY; i++) acc -= g_data.cy[i] * g_data.y[i];

        g_data.y[0] = acc;

        // Вывод: дисплей (табуляция) и файл (CSV)
        printf("%d\t%.2f\t%.4f\n", t, current_input, acc);
        fprintf(f, "%d,%.2f,%.4f\n", t, current_input, acc);

        // Сдвиг x
        float te1 = g_data.x[0];
        for (int i = 1; i < NX; i++) {
            float te2 = g_data.x[i];
            g_data.x[i] = te1;
            te1 = te2;
        }
        // Сдвиг y
        te1 = g_data.y[0];
        for (int i = 1; i < NY; i++) {
            float te2 = g_data.y[i];
            g_data.y[i] = te1;
            te1 = te2;
        }
    }

    fclose(f);
    free(g_data.cx); free(g_data.x); 
    free(g_data.cy); free(g_data.y);
    return 0;
}

Ой плохо проверка после маллок массив что индекс цикл не высоко его размер сделать до 20. Но вводи сканф размер массив x,y и cx,cy клавиатура если энтер и энтер то по умолчанию.

Тест границы массива
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#define MAX_SIZE 20
#define DEFAULT_NX 5
#define DEFAULT_NY 5
#define STEPS 20

typedef struct {
    float *cx, *x, *cy, *y;
    int nx, ny;
} FilterData;

FilterData g_data;

// Функция для безопасного ввода размера
int get_size(const char *name, int def_val) {
    char buffer[100];
    printf("Введите размер %s (по умолчанию %d, макс %d): ", name, def_val, MAX_SIZE);
    if (fgets(buffer, sizeof(buffer), stdin) == NULL || buffer[0] == '\n') {
        return def_val;
    }
    int val = atoi(buffer);
    if (val <= 0) return def_val;
    if (val > MAX_SIZE) return MAX_SIZE;
    return val;
}

int main() {
    // Ввод размеров с клавиатуры
    g_data.nx = get_size("X/CX", DEFAULT_NX);
    g_data.ny = get_size("Y/CY", DEFAULT_NY);

    // --- Выделение памяти с проверкой ---
    g_data.cx = (float*)malloc(g_data.nx * sizeof(float));
    g_data.x  = (float*)calloc(g_data.nx, sizeof(float));
    g_data.cy = (float*)malloc(g_data.ny * sizeof(float));
    g_data.y  = (float*)calloc(g_data.ny, sizeof(float));

    if (!g_data.cx || !g_data.x || !g_data.cy || !g_data.y) {
        printf("Ошибка: не удалось выделить память!\n");
        return 1;
    }

    // --- Инициализация коэффициентов ---
    for(int i = 0; i < g_data.nx; i++) g_data.cx[i] = 1.0f / (float)g_data.nx;
    for(int i = 0; i < g_data.ny; i++) g_data.cy[i] = 0.0f;
    
    // Полюса для устойчивости
    float r = 0.95f; 
    float theta = 0.4f;
    if (g_data.ny > 2) {
        g_data.cy[1] = -2.0f * r * cosf(theta); 
        g_data.cy[2] = r * r;
    }

    // --- Работа с файлом и вывод ---
    FILE *f = fopen("experiment.txt", "w");
    if (!f) {
        printf("Ошибка открытия файла!\n");
        return 1;
    }

    printf("\nИмпульсная характеристика (NX=%d, NY=%d):\n", g_data.nx, g_data.ny);
    printf("T\tInput\tOutput\n");
    printf("--------------------------\n");
    fprintf(f, "Step,Input,Output\n");

    for (int t = 0; t < STEPS; t++) {
        float current_input = (t == 0) ? 1.0f : 0.0f;
        g_data.x[0] = current_input;

        float acc = 0.0f;
        // Циклы теперь ограничены введенными размерами
        for (int i = 0; i < g_data.nx; i++) acc += g_data.cx[i] * g_data.x[i];
        for (int i = 1; i < g_data.ny; i++) acc -= g_data.cy[i] * g_data.y[i];

        g_data.y[0] = acc;

        printf("%d\t%.2f\t%.4f\n", t, current_input, acc);
        fprintf(f, "%d,%.2f,%.4f\n", t, current_input, acc);

        // Сдвиг x через временные переменные
        float te1 = g_data.x[0];
        for (int i = 1; i < g_data.nx; i++) {
            float te2 = g_data.x[i];
            g_data.x[i] = te1;
            te1 = te2;
        }
        // Сдвиг y через временные переменные
        te1 = g_data.y[0];
        for (int i = 1; i < g_data.ny; i++) {
            float te2 = g_data.y[i];
            g_data.y[i] = te1;
            te1 = te2;
        }
    }

    // --- Завершение ---
    fclose(f);
    free(g_data.cx); free(g_data.x);
    free(g_data.cy); free(g_data.y);
    printf("\nДанные сохранены в experiment.txt. Память очищена.\n");

    return 0;
}

Хотеть ГНУ мэйкфайл компиляция что мой С стандарт проверка не хуже C11 мой архитектура есть 64 бита и процессор x86 а не АРМ иначе ошибка. Называю mymain си мой файл я

Антилопа мэйкфайл
# Имя исходного файла и исполняемого файла
TARGET = mymain
SRC = mymain.c

# Настройки компилятора
CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic -lm

# Определение архитектуры и разрядности
ARCH = $(shell uname -m)
BITS = $(shell getconf LONG_BIT)

# Проверка условий: x86_64 и 64 бита
all: check_arch $(TARGET)

check_arch:
	@echo "Проверка системных требований..."
	@if [ "$(ARCH)" != "x86_64" ]; then \
		echo "Ошибка: Архитектура $(ARCH) не поддерживается. Нужен x86_64 (не ARM)."; \
		exit 1; \
	fi
	@if [ "$(BITS)" != "64" ]; then \
		echo "Ошибка: Требуется 64-битная система."; \
		exit 1; \
	fi
	@echo "Система подходит: $(ARCH) $(BITS)-bit. Стандарт C11."

$(TARGET): $(SRC)
	$(CC) $(CFLAGS) $(SRC) -o $(TARGET)

clean:
	rm -f $(TARGET) experiment.txt

run: all
	./$(TARGET)

Хотеть бэш скрипт питон автомат загрузка матплотлиб вэнв виртуальное окружение зависимости хорошо а ежели вэнв есть то продолжить активировать вэнв и запустить скрипт питон называю я graph а если скрипт нет выйти сообщить создайте скрипт.

Бэш питон вэнв автомат
#!/bin/bash

# 1. Проверка наличия Python-скрипта
if [ ! -f "graph.py" ]; then
    echo "Ошибка: Файл graph.py не найден! Пожалуйста, создайте скрипт."
    exit 1
fi

# 2. Проверка и создание venv
VENV_DIR="venv"

if [ ! -d "$VENV_DIR" ]; then
    echo "Виртуальное окружение не найдено. Создаю..."
    python3 -m venv $VENV_DIR
    source $VENV_DIR/bin/activate
    echo "Установка зависимостей (matplotlib)..."
    pip install --upgrade pip
    pip install matplotlib
else
    echo "Активация существующего окружения..."
    source $VENV_DIR/bin/activate
fi

# 3. Запуск Python-скрипта
echo "Запуск визуализации..."
python3 graph.py

# Деактивация после выхода
deactivate

Питон язык загружает CSV файл импульсная характеристика формат время, номер отсчёт, значение, строить матплотлиб красиво цвет график точки и линии подпись ось сетка включено, пакет только матплотлиб импорт другие нельзя.

Питон язык строить CSV
import matplotlib.pyplot as plt
import csv
import os

def draw_graph():
    filename = "experiment.txt"
    
    # Проверка файла
    if not os.path.exists(filename):
        print(f"Ошибка: Создайте сначала {filename} (запустите C программу)")
        return

    steps = []
    values = []

    # Чтение данных без использования сторонних пакетов (только стандартный csv)
    try:
        with open(filename, "r", encoding="utf-8") as f:
            reader = csv.reader(f)
            next(reader)  # Пропускаем заголовок (Step, Input, Output)
            for row in reader:
                if len(row) >= 3:
                    steps.append(int(row[0]))   # Время / Номер отсчета
                    values.append(float(row[2])) # Значение (Output)
    except Exception as e:
        print(f"Ошибка чтения CSV: {e}")
        return

    # --- Настройка визуализации (Красиво) ---
    plt.figure(figsize=(11, 6))
    
    # Рисуем линии и точки одновременно
    # 'o-' означает точки и сплошную линию
    # color='#2c3e50' - темно-синий/графитовый цвет
    plt.plot(steps, values, 'o-', color='#e74c3c', linewidth=1.5, 
             markersize=5, markerfacecolor='#2980b9', markeredgecolor='white',
             label='Импульсный отклик')

    # Оформление осей и заголовка
    plt.title("Импульсная характеристика системы", fontsize=14, pad=15)
    plt.xlabel("Номер отсчета (n)", fontsize=11)
    plt.ylabel("Амплитуда сигнала (y)", fontsize=11)

    # Сетка
    plt.grid(True, linestyle='--', alpha=0.7)
    
    # Линии осей для наглядности (проходят через 0)
    plt.axhline(0, color='black', linewidth=0.8, alpha=0.5)
    plt.axvline(0, color='black', linewidth=0.8, alpha=0.5)

    plt.legend()
    
    # Сохранение и отображение
    print("Сохранение графика в impulse_response.png...")
    plt.savefig("impulse_response.png", dpi=200)
    plt.show()

if __name__ == "__main__":
    draw_graph()
Результат

Это импульсная характеристика или переходная на функцию Хевисайда - уже вопрос для билета

Один из главных моментов - не существует релятивистской динамики абсолютно твёрдого тела, так как возмущение в нём передаётся мгновенно а не со скоростью света, являющейся предельной. Поэтому рассматриваются только материальные точки или их облака (см. тензор Риччи) Если точка неподвижна - тензор Эйнштейна равен нулю, тензор Риччи обращается в ноль (рядом нет энергии), остаётся скаляр Риччи и метрический тензор, для точки - это решение в виде метрики Шварцшильда, представляющей собой расстояние в пространстве-времени (скалярный интервал), квадрат вектора - скаляр, он то и показывает величину того самого искривления, более верно - величина близости к точеченой массе. Ещё более весомый постулат - это дивергенция тензора Эйнштейна равна нулю, это означает, что нет источников и приёмников энергии и момента, то есть можно приравнять энергию к геометрии с коэффициентом. То есть дивергенция геометрии должна быть нулевой, что означает, что гравитация локально не способна порождать или поглощать энергию (!), закон сохранения энергии-момента. Грубо говоря четырёхмерная плёнка, охватывающая точку в пространстве-времени имеет нулевую общую входящую и выходящую энергию (геометрию) - это про ковариантную дивергенцию (там же инвариантность к диффеоморфизму) .

Информация

В рейтинге
3 420-й
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Инженер электронных устройств, Научный специалист, исследователь
Старший
От 300 000 ₽
Прикладная математика
Разработка программного обеспечения
Оптимизация кода
C
Assembler
Python
Алгоритмы и структуры данных
Объектно-ориентированное проектирование
Многопоточность
Verilog HDL