2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу Пред.  1 ... 40, 41, 42, 43, 44, 45, 46 ... 52  След.

А вам пакет PARI/GP интересен?
Да 82%  82%  [ 56 ]
Нет 6%  6%  [ 4 ]
Не уверен(а) 12%  12%  [ 8 ]
Всего голосов : 68
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение13.02.2023, 21:39 


05/09/16
11539
gris
Ну так у вас же есть инструментарий. Проверьте сперва как у вас написано а потом просто ispseudoprime(i) и посмотрите на время. Есщи что, то время показывается командой ## (две решетки) или можно включить чтоб показывалось всегда
? default(timer,1)

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение13.02.2023, 21:58 
Заслуженный участник
Аватара пользователя


13/08/08
14457
wrest, время жёлтенькое :-)
да, с предварительной проверкой больше чуть-чуть. А если isprime то больше в 15 раз :-(

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение18.02.2023, 09:42 
Заслуженный участник
Аватара пользователя


13/08/08
14457
wrest, нет примеров программ со своими функциями в теме :-(
Затруднение. Есть некая программа. В ней выполняется несколько функций. Я хочу получить по каждой функции число её выполнений.
{n=0;
for( p=3,100, if(isprime(p),n++) );
print(" n=",n);}
n=24

Чтобы подсчитать количество обращений к функции, я ввожу дополнительную переменную и привязываю её к вызову функции.
{kispp=0; n=0;
for( p=3,100, j=isprime(p);kispp++; if(j,n++) );
print("isprime=",kispp," n=",n);}
isprime=98 n=24

Некрасиво. А вдруг функция вызывается в ифе:
if( isprime(p) && isprime(p+2) && isprime(p+8) )
Подскажите, есть ли встроенное средство? Спасибо.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение18.02.2023, 13:20 


05/09/16
11539
gris в сообщении #1582130 писал(а):
Подскажите, есть ли встроенное средство?

Нет. Но вы можете сделать свою функцию, которая будет вызывать встроенную и плюс считать количество вызовов в какой-то глобальной переменной.
? ipc=0
%1 = 0
? ip(p)=ipc++;return(isprime(p))
%2 = (p)->ipc++;return(isprime(p))
? ipc
%3 = 0
? for(i=1,100,x=ip(i))
? ipc
%5 = 100
?

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

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение18.02.2023, 13:44 
Заслуженный участник
Аватара пользователя


13/08/08
14457
wrest, идея такая была. Но я никак не могу сделать программу с функцией в текстовом файле.
Вот с учётом ваших рекомендаций
{k=0; n=0;
ip(p)=k++; return(isprime(p));
for( i=3,100,n+=ip(i) );
print("k=",k," n=",n);
}

И она ничего не выводит :facepalm:
Что надо сделать?
Но самое удивительное, что если я закомменчиваю вторую строку и запускаю программу без перезапуска PARI/GP, то она печатает
k=98 n=24
Функция сидит уже там?

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение18.02.2023, 14:07 


05/09/16
11539
gris в сообщении #1582156 писал(а):
Что надо сделать?

Надо не ставить фигурные скобки :mrgreen:
? k=0; n=0;
? ip(p)=k++; return(isprime(p));
? for( i=3,100,n+=ip(i) );
? print("k=",k," n=",n);
k=98 n=24
?

Это тонкий лёд, но что ж поделать...

Более универсально:
? ip(~i,p)=i[1]++;return(isprime(p))
%1 = (~i,p)->i[1]++;return(isprime(p))
? k=vector(1,n,0)
%2 = [0]
? for( i=3,100,n+=ip(~k,i) );
? print(k[1])
98
?


Будет работать в версии 2.13 и позднее
Пояснения см тут https://pari.math.u-bordeaux.fr/archive ... 00006.html
Цитата:
- support call by reference in GP functions: f(~L,x) = L[1] = x;
This allows to modify the contents of a vector / list argument and avoids
unnecessary copies of arguments.

То есть указатели передавать можно, но только на контейнерные переменные (массивы).

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение18.02.2023, 14:49 
Заслуженный участник
Аватара пользователя


13/08/08
14457
wrest, спасибо! Вот что я сделал:
запустил PARI запустил таймер запустил
ipp(p)=kipp++; return(ispseudoprime(p));
np(p)=knp++; return(nextprime(p));

А уж потом программу в фигурных скобках, где поменял функции. Всё работает!
У меня теперь есть функции!

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение12.03.2023, 12:23 
Заслуженный участник
Аватара пользователя


13/08/08
14457
Субботний вечер и вот опять я собираюсь в простяшки поиграть. Я набираю PARI и совершаю GP...
Нельзя оставлять полезную тему.
Проверка вектора на простоту и попарные расстояния.
Код:
{pn=[98303873, 98303897, 98303903, 98303927, 98303951, 98303957, 98303981];
lp=#pn;
pt=vector(lp,i,pn[i]-pn[1]);
pind=vector(lp,i,isprime(pn[i]));
pd=vector(lp-1,i,pn[i+1]-pn[i]);
print(pn[1],": ", pt);
print(pind);
print(pd);
}
98303873: [0, 24, 30, 54, 78, 84, 108]
[1, 1, 1, 1, 1, 1, 1]
[24, 6, 24, 24, 6, 24]
time = 329 ms.

Мелочь, а приятно.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение12.03.2023, 15:08 
Заслуженный участник


20/08/14
11179
Россия, Москва
Полезный финт для более компактного вывода векторов:
Код:
? p=[0,24,30,54,78,84,108]; printf("%d: %d\n", 98303873,p);
98303873: [0,24,30,54,78,84,108]
Здесь второй %d применяется к каждому элементу вектора и позволяет убрать пробел после запятой. Если надо.

Ещё финт, для одинакового вывода на консоль и в файл лога/результата:
Код:
p=[0,24,30,54,78,84,108]; w=strprintf("%d: %d", 98303873,p); print(w); write(f,w);
Здесь уже \n в строке не нужно, оно добавляется и print и write. Так можно сначала набрать длинную строку из множества объектов, а потом единым махом её вывести, это намного быстрее вызова кучи print1/write1. Плюс широкие возможности форматирования.

Ещё финт, убрать обрамляющие "[]" из вывода вектора, плюс заменить разделитель на например ";":
Код:
? ? p=[0,24,30,54,78,84,108]; w=strjoin(p,";"); print(98303873,": ",w);
98303873: 0;24;30;54;78;84;108
Корректно работает и с одним элементом в векторе, и с пустым вектором.
Тут конечно надо бы сначала преобразовать вектор чисел в вектор строк (как требует strjoin), но в частном случае просто чисел работает и так.

PS. Сегодня уже воскресенье. ;-)

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение12.03.2023, 20:54 


05/09/16
11539
Вместо
gris в сообщении #1585176 писал(а):
pind=vector(lp,i,isprime(pn[i]));
пишем
pind=isprime(pn);
:wink:

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение12.03.2023, 22:15 
Заслуженный участник
Аватара пользователя


13/08/08
14457
о, уже воскресенье!
как часто жизнь приносит нам сюрпризики,
когда тебе уже шестьнадцать лет :facepalm:
спасибо, советы хорошие, в копилочку :-)
а вот безделушка с сюрпризом. некто начирикал кусочек
{k=0; n=820; m=899;
forprime(p=n,m,
if(p%30==1,k++;
if(k==1,print( "in range ",n," - ",m," p=30k+1:" );
print1("a=[",p) , print1(", ",p))));
if(k>0,print("];"); print("lena=",k,";"))}

ничего не печатает. значит нечего. а так:
{k=0; n=455; m=899; .... }
in range 455 - 899 p=30k+1:
a=[541, 571, 601, 631, 661, 691, 751, 811];
lena=8;

отлично. но джипити решил исправить синтактическую ошибку и вышло так:
in range 455 - 899 p=30k+1:
a=[541, 541];
lena=8;

это была не ошибка — завопил некто.
а тогда вот это точно ошибка — сказал ии.
in range 455 - 899 p=30k+1:
a=[541in range 455 - 899 p=30k+1:
a=[571in range 455 - 899 p=30k+1:
a=[601in range 455 - 899 p=30k+1:
......

ии, покажи, что ты делал!
ищочиво. сам догадайся.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение13.03.2023, 14:22 
Заслуженный участник


20/08/14
11179
Россия, Москва
gris
Научитесь уже оформлять код нормально! Особенно когда он более чем из одной строки или имеет больше одного уровня вложенности. Вот как примерно оно должно выглядеть:
Код:
{k=0; n=820; m=899;
forprime(p=n,m,
   if(p%30==1,
      k++;
      if(k==1,
         print( "in range ", n, " - ", m, " p=30k+1:" );
         print1("a=[", p)
      ,
         print1(", ", p)
      )
   )
);
if(k>0, print("];"); print("lena=", k, ";") )
}
Отдельно обращу внимание что не надо писать k++ в той же строке что и if, слишком легко его там не заметить.

Отдельный совет: чтобы плодить меньше уровней вложенности if можно пользоваться next, т.е. условие if(p%30==1, ...) заменить на условие if(p%30!=1, next) и тело условия окажется на уровень выше, на том же уровне что и сам этот if, а не в глубине его. Не всегда это получается, но часто.

PS. Сам Ваш вопрос так и не понял, извините.

 Профиль  
                  
 
 PARI/GP хорошая штука, но вызывает привыкание
Сообщение21.05.2023, 14:08 
Заслуженный участник
Аватара пользователя


13/08/08
14457
Вот мимолётная задача: Есть не слишком много векторов одинаковой длины, состоящих из натуральных чисел меньших тысячи. Первый элемент типа заголовка не больше миллиона
34332 3 5 433 445 678
5639 3 5 46 33 366
456 3 5 46 55 78

Они сидят в текстовом файле по одному вектору в строке.
Надо их отсортировать по возрастанию сначала по второму элементу, потом вложенно по остальным (как это правильно называется?).
Я не думая упаковал каждый вектор в число
34332 3 5 433 445 678 в 3005433678034332
5639 3 5 46 63 366 в 3005046063366005639
456 3 5 46 55 78 в 3005046055078000456

отсортировал и распаковал обратно
Код:
{ k=0;
  tin= fileopen("C:/GRIS/test.txt");

  a=[];
  p=vector(6);

  while (str = filereadstr(tin), k++;
    b=strsplit(str, " "); print(str);
    p=eval(b);
    pv=0;
    for( i=1,5, pv=pv+p[7-i]*10^(3*i-3);  );
    a=concat(a,pv*10^6+p[1]);
  );
print("number of vectors:",k);

a=vecsort(a);

for( i=1,k,
  p[1]=a[i]%10^6 ;
  b=a[i]\10^6;
  for( j=2,6,
    p[j]=b\10^(3*(6-j));
    b=b-p[j]*10^(3*(6-j));
  ); 
  print(p);
);
}


Оно работает, вроде бы
number of vectors:3
[5639, 3, 5, 46, 33, 366]
[456, 3, 5, 46, 55, 78]
[34332, 3, 5, 433, 445, 678]


но как-то неуклюже. Как всегда после скоропалителного решения хочется получить изящное.
Как укорачивать вектор? Отбросить или начало или хвост.
Как напечатать число 23454567654 в виде
23 454 567 654 с помощью printf? Где-то же было, но разве найдёшь :oops:
как отсортировать массив векторов одинаковой длины по первому и в глубину по остальным элементам?
Ну и вообще...

 Профиль  
                  
 
 Re: PARI/GP хорошая штука, но вызывает привыкание
Сообщение21.05.2023, 14:42 
Аватара пользователя


22/11/13
502
gris в сообщении #1594605 писал(а):
как отсортировать массив векторов одинаковой длины по первому и в глубину по остальным элементам?

Транспонировать и сортировать получившиеся массивы по возрастанию, а потом транспонировать обратно? Или вам нужно что-то другое? Можете привести пример?

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 14:54 
Заслуженный участник
Аватара пользователя


13/08/08
14457
kthxbye
Так пример выше и есть. Там даже маленькое осложнение в виде первого элемента, который надо тащить с собой, но не сортировать по нему.
Ну это, наверное, что-то векторно-лексикографическое, но я не нашёл.
В PARI многие вещи делаются одной функцией, но надо до неё добраться.
Ну вот, например,
[ 111, 22, 33 ]
[ 11, 543, 77 ]
[ 111, 22, 32 ]

после сортировки
[ 11, 543, 77 ]
[ 111, 22, 32 ]
[ 111, 22, 33 ]

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 780 ]  На страницу Пред.  1 ... 40, 41, 42, 43, 44, 45, 46 ... 52  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group