2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1 ... 58, 59, 60, 61, 62  След.

А вам пакет PARI/GP интересен?
Да 83%  83%  [ 60 ]
Нет 6%  6%  [ 4 ]
Не уверен(а) 11%  11%  [ 8 ]
Всего голосов : 72
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 19:32 
gris в сообщении #1712863 писал(а):
конечно понятно, но как-то некрасиво

? sup_str=["¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹"];
? a=3;a_exp=2;b=5;b_exp=3;print(a,sup_str[a_exp],"+",b,sup_str[b_exp]);
3²+5³
?

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 19:40 
gris
Типа такого 3²+4²?
В консоли PARI такого нельзя - в кодировке 866 просто нет символа ². И сменить кодировку консоли похоже нельзя.
В файл вывести можно - любым способом вставить символ с кодом 0xB2 (для кодировки файла 1251 или win, тогда он откроется любым блокнотом винды).

wrest
Вы точно про винду говорите, а? В ней (и вин7 и вин10) кодировка консоли вовсе не Unicode:
Код:
Microsoft Windows [Version 6.1.7601]
(c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены.

C:\>mode con cp

Состояние устройства CON:
--------------------------
    Кодовая страница:      866


C:\>gp64.exe
Reading GPRC: C:/gprc.txt
GPRC Done.

                                                                        GP/PARI CALCULATOR Version 2.17.3 (released)
                                                                amd64 running mingw (x86-64/GMP-6.1.2 kernel) 64-bit version
                                                                      compiled: Nov 11 2025, gcc version 12-posix (GCC)
                                                                                  threading engine: single
                                                                      (readline not compiled in, extended help enabled)

                                                                           Copyright (C) 2000-2024 The PARI Group

PARI/GP is free software, covered by the GNU General Public License, and comes WITHOUT ANY WARRANTY WHATSOEVER.

Type ? for help, \q to quit.
Type ?18 for how to get moral (and possibly technical) support.

parisize = 8000000, primelimit = 51000000, factorlimit = 1048576
? sup_str=["?","?","?","?","?","?","?","?","?"]
%1 = ["?", "?", "?", "?", "?", "?", "?", "?", "?"]
? a=3;a_exp=2;b=5;b_exp=3;print(a,sup_str[a_exp],"+",b,sup_str[b_exp]);
3?+5?
?


-- 19.12.2025, 20:03 --

Изображение

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 20:08 
Dmitriy40 в сообщении #1712869 писал(а):
Вы точно про винду говорите, а?

Точно НЕ про венду :D У меня нет pari/gp "напрямую" в венде.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 20:11 
wrest
Тогда стоит держать в уме и делать поправку на ОС автора вопроса.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 20:11 
Dmitriy40 в сообщении #1712869 писал(а):
В ней (и вин7 и вин10) кодировка консоли вовсе не Unicode:

Ну что же поделать. Может, в Windows Terminal норм будет? Для 10-й венды он вроде есть.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 20:21 
wrest в сообщении #1712872 писал(а):
Может, в Windows Terminal норм будет? Для 10-й венды он вроде есть.
Может и будет, не знаю. Хотя вряд ли - так как PARI не наследует кодировку системной консоли, а своих средств её поменять кажется нету.
Вот только, уверены что ради замены
3^2+4^2
на
3²+4²
в окне PARI кто-то будет заморачиваться с установкой Windows Terminal и тем более сменой винды на 10-ю? :mrgreen:

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 20:32 
Dmitriy40 в сообщении #1712874 писал(а):
Вот только, уверены что ради замены

Понятия не имею :D Охота хуже неволи. А я же вас (но не gris) давно агитирую, капля камень точит.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение19.12.2025, 20:39 
Меня и 3^2+4^2 вполне устраивает, тем более что такую строку можно скопировать в PARI (и в TeX, и не только) и он её корректно посчитает.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 02:00 
Аватара пользователя
Коллеги, два вопроса по оптимизации работы с массивами, буду благодарен за помощь.

1) Есть небольшой (сотни элементов) вектор B, хочу выставить некоторые из его элементов равными одному и тому же числу g, а остальные не менять. Самое быстрое, что у меня получается, выглядит так:

B=vectorsmall(#B,x,if((x>bR||x<bL) && (B[x]==0) && (x%d==(bL-1)%d||x%d==(bL-1-lr*2*i)%d),g,B[x]))

Сразу скажу, с виду более естественная конструкция работает медленнее:

xt=select(x->(x>bR||x<bL) && (x%d==(bL-1)%d||x%d==(bL-1-lr*2*i)%d),[1..#B]);
foreach(xt,x,if(B[x]==0,B[x]=g));


2) Я знаю, что в этом векторе B все элементы с индексами bL..bR отличны от нуля, а соседние элементы слева и справа уже нули. Теперь я как-то поманипулировал с B и знаю, что диапазон индексов, соответствующих идущим подряд ненулевым значениям, должен расшириться. И хочу найти новые bL, bR; самое быстрое, что умею, такое:

for(x=bR+1,#B,if(B[x]==0,bR=x-1;break));
forstep(x=bL-1,1,-1,if(B[x]==0,bL=x+1;break));


Опять же более красивая конструкция работает медленнее:

xz=select(x->(x>bR)&&(B[x]==0),[1..#B])[1]; bR=xz-1;
xz=select(x->(x<bL)&&(B[x]==0),[1..#B]); bL=xz[#xz]+1;


Как бы еще извернуться?

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 03:36 
waxtep
1)
Условие (x>bR||x<bL) лишнее, оно перекрывается условием B[x]==0.
В условиях x%d==(bL-1)%d||x%d==(bL-1-lr*2*i)%d обе правые части константы, стоит их вычислить заранее.
Тут два одинаковых деления x%d, стоит сохранить значение первого и использовать во втором. Не уверен как быстрее.
Думаю цикл типа for(x=1,#B, if(..., B[x]=g) должен работать побыстрее - он не создаёт новых объектов кроме переменной цикла.
Стоит посмотреть какое условие не срабатывает чаще - его и поставить первым в if.

Вообще весь цикл похож на заполнение нулевых элементов вектора двумя цепочками с постоянным шагом d - может так и сделать, два forstep(x=if(x0==0,d,x0),#B,d, if(B[x]==0, B[x]=g)) с разными x0 ((bL-1)%d и (bL-1-lr*2*i)%d)? Правда их приходится проверять на 0, но это ведь тоже однократно, как и вычисление этих выражений для x0, а не для каждого нулевого элемента как у Вас.


2)
Ваш код работает неправильно если любой край непрерывного куска упёрся в свой край вектора - в этом случае соответствующий указатель не изменится.
Кроме как перебором индексов и проверкой элемента на 0 что-то придумать сложно. Каким именно циклом перебирать указатель думаю разницы мало (я обычно while и вечно парюсь с проверкой на концы вектора).

-- 05.02.2026, 03:57 --

waxtep в сообщении #1717256 писал(а):
Опять же более красивая конструкция работает медленнее:

xz=select(x->(x>bR)&&(B[x]==0),[1..#B])[1]; bR=xz-1;
xz=select(x->(x<bL)&&(B[x]==0),[1..#B]); bL=xz[#xz]+1;
Тут можно сразу поставить пределы [bR+1..#B] и [1..bL-1] соответственно и убрать проверки x>bR и x<bL, будет быстрее.
Однако если нулей не осталось - всё равно будет работать неправильно, в конце нужна дополнительная проверка на пустой вектор: bR=if(#xz>0, xz[1]-1, #B) и bL=if(#xz>0, xz[-1..-1][1]+1, 1).
Но мне сложно представить в каком случае такая конструкция будет быстрее цикла с выходом. Разве что при сильном удлинении непрерывного куска - но такое не может быть часто, а при столь малом векторе выигрыш несколько раз из тысяч (или миллионов или сколько у Вас там итераций) роли не играет.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 09:28 
Dmitriy40 в сообщении #1717259 писал(а):
Вообще весь цикл похож на заполнение нулевых элементов вектора двумя цепочками с постоянным шагом d - может так и сделать,

Да, и это ускорит выполнение минимум в d раз.
Как-то так:
Код:
  my(mod1 = (bL - 1) % d, mod2 = (bL - 1 - lr*2*i) % d);
 
  \\ Обработка первого остатка
  my(x0 = if(mod1, mod1, d));
  forstep(x = x0, bL-1, d, if(B[x] == 0, B[x] = g));
  forstep(x = max(x0, bR+1), #B, d, if(!B[x], B[x] = g));
 
  \\ Обработка второго остатка (если отличается)
  if(mod2 != mod1,
    x0 = if(mod2, mod2, d);
    forstep(x = x0, bL-1, d, if(B[x] == 0, B[x] = g));
    forstep(x = max(x0, bR+1), #B, d, if(!B[x], B[x] = g))
  );

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 10:32 
waxtep
Кстати, как я понял, это у вас происходит в цикле, по i, но первый остаток равный (bL - 1) % d от i не зависит, так что его можно вычислять один раз для цикла. Поскольку второй остаток (bL - 1 - lr*2*i) % d по тому же модулю d что и первый, то его можно вычислять в теле цикла уже без деления.

Ну то есть идея такая:
Код:
mod1=(bL - 1) % d; mod2=mod1; mod2_inc=(-2*lr) % d;
for(i=1,n,
  \\ mod1=(bL -1) % d; mod2= (bL - 1 - 2*lr*i) % d;
  mod2+=mod2_inc; if(mod2+1>d,mod2-=d);
  );


Первой строчкой делаем предвычисления перед циклом, а в цикле вместо того что закомментировано делаем то что незакомментировано. Два деления заменяем одним или двумя сложениями.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 13:46 
wrest в сообщении #1717264 писал(а):
Да, и это ускорит выполнение минимум в d раз.
Меньше чем в d - вектор слишком маленький чтобы пренебречь накладными расходами перед ним.
А на самом деле даже больше - условия вычисляются один раз, а не #B раз и не #B/d раз.
Ну и плюс проверка ненужности цикла по второму остатку, да.
wrest в сообщении #1717273 писал(а):
Код:
if(mod2+1>d,mod2-=d);
mod2>=d проще чем mod2+1>d.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 18:21 
Dmitriy40 в сообщении #1717301 писал(а):
mod2>=d проще чем mod2+1>d.

А я чета даже и не подумал что >= "легитимный" оператор, даже проверять не стал :facepalm:

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение05.02.2026, 18:55 
wrest в сообщении #1717264 писал(а):
Код:
forstep(x = max(x0, bR+1), #B, d, if(!B[x], B[x] = g));
Здесь max() неправильно - если x0<bR+1, то начальное значение x будет bR+1, но ведь не факт что (bR+1)%d==mod2. Тут надо не просто max(), а округлить bR+1 до mod2 по модулю d, например влево (что проще): forstep(x=max(x0,bR-bR%d+x0),#B,d, if(B[x]==0, B[x]=g)). Тут может оказаться что первый x<=bR, но это не проблема так как дальше всё равно стоит проверка B[x]==0, а одной лишней итерацией можно и пожертвовать.

-- 05.02.2026, 19:18 --

И кстати не факт что деление одного цикла на два (до bL и после bR) выгодно, если bR-bL мало (причём по сравнению с d), то возможно один цикл будет быстрее, даже с чуть бОльшим количеством итераций.
И обратно, если bR-bL приближается к #B, то два коротких цикла выгоднее одного длинного.

 
 
 [ Сообщений: 921 ]  На страницу Пред.  1 ... 58, 59, 60, 61, 62  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group