2014 dxdy logo

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

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




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

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


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

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


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

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


13/08/08
14495
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
12058
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
14495
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
12058
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
14495
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
14495
Субботний вечер и вот опять я собираюсь в простяшки поиграть. Я набираю 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
11766
Россия, Москва
Полезный финт для более компактного вывода векторов:
Код:
? 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
12058
Вместо
gris в сообщении #1585176 писал(а):
pind=vector(lp,i,isprime(pn[i]));
пишем
pind=isprime(pn);
:wink:

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


13/08/08
14495
о, уже воскресенье!
как часто жизнь приносит нам сюрпризики,
когда тебе уже шестьнадцать лет :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
11766
Россия, Москва
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
14495
Вот мимолётная задача: Есть не слишком много векторов одинаковой длины, состоящих из натуральных чисел меньших тысячи. Первый элемент типа заголовка не больше миллиона
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
02/04/25
549
gris в сообщении #1594605 писал(а):
как отсортировать массив векторов одинаковой длины по первому и в глубину по остальным элементам?

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

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


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

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

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

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



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

Сейчас этот форум просматривают: DariaRychenkova


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

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