2014 dxdy logo

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

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




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

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


20/08/14
11872
Россия, Москва
gris в сообщении #1594605 писал(а):
Как укорачивать вектор?
Код:
? v=[1,2,3,4,5]; print(v[2..4])
[2, 3, 4]
В качестве последнего элемента можно указывать например его размер #v.
Можно конечно и переменные использовать вместо конкретных чисел.

gris в сообщении #1594605 писал(а):
Отбросить или начало или хвост.
Код:
? v=[1,2,3,4,5]; print(v[3..#v])
[3, 4, 5]
? v=[1,2,3,4,5]; print(v[1..3])
[1, 2, 3]

gris в сообщении #1594605 писал(а):
Как напечатать число 23454567654 в виде
23 454 567 654 с помощью printf?
Если речь про разделители групп разрядов, то никак.
Обходной манёвр: перевести число в массив цифр по модулю 1000, потом объединить массив в строку с разделителями пробелом (или любым другим):
Код:
? x=1234567890123456; d=digits(x,1000); print(d); s=strjoin(d," "); print(s)
[1, 234, 567, 890, 123, 456]
1 234 567 890 123 456

Вообще связка strsplit/strjoin весьма мощная, хоть и медленная, можно делать много красивых вещей.

Теперь по сортировке.
Преобразование вектора чисел в одно число с последующей сортировкой и преобразованием обратно -- вполне нормальный подход. Тем более что можно выбрать в каком порядке преобразовывать числа для их правильной сортировки.
Преобразовать строку в длинное число можно так:
Код:
? s="34332 3 5 433 445 678"; v=eval(strsplit(s," ")); x=fromdigits(v,10^6)
34332000003000005000433000445000678
Преобразовать обратно уже показывал, но ещё раз:
Код:
? x=34332000003000005000433000445000678; d=digits(x,10^6); print(d); s=strjoin(d," "); print(s)
[34332, 3, 5, 433, 445, 678]
34332 3 5 433 445 678
Чтобы последующая сортировка была в порядке 2,3,4,5,6,1 столбцов, надо перед объединением вектора в одно число переставить его элементы желаемым образом, например так:
Код:
? s="34332 3 5 433 445 678"; v=eval(strsplit(s," ")); v=concat(v[2..6],v[1])
[3, 5, 433, 445, 678, 34332]

На самом деле для сортировки массива векторов вовсе не обязательно их преобразовывать в числа, можно и сразу vecsort натравить:
Код:
? v=[[3,5,433,445,678,34332],[3,5,46,33,366,5639],[3,5,46,55,78,456]]; print(v); print(vecsort(v))
[[3, 5, 433, 445, 678, 34332], [3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456]]
[[3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456], [3, 5, 433, 445, 678, 34332]]

Если бы у Вас был не вектор/массив векторов, а матрица, то подматрицы (в том числе отдельные строки или столбцы) из неё можно вытаскивать так:
Код:
? m=matrix(4,3,x,y,y*5+x)
[6 11 16]
[7 12 17]
[8 13 18]
[9 14 19]
? m[,2]
[11, 12, 13, 14]~
? m[,2..3]
[11 16]
[12 17]
[13 18]
[14 19]
? m[2..4,1]
[7, 8, 9]~
? m[2..4,1..2]
[7 12]
[8 13]
[9 14]
? m[2..4,]
[7 12 17]
[8 13 18]
[9 14 19]

А чтобы vecsort не хапала слишком много памяти под результат (если он большого размера, не просто вектор чисел), то можно вместо готовой перестановки получать лишь порядок индексов и потом идти в указанном им порядке по исходному вектору и сохранять данные куда и как надо:
Код:
? v=[[3,5,433,445,678,34332],[3,5,46,33,366,5639],[3,5,46,55,78,456]]; print(v); ind=Vec(vecsort(v,,1)); print(ind); foreach(ind,i, print(v[i]););
[[3, 5, 433, 445, 678, 34332], [3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456]]
[2, 3, 1]
[3, 5, 46, 33, 366, 5639]
[3, 5, 46, 55, 78, 456]
[3, 5, 433, 445, 678, 34332]


-- 21.05.2023, 18:09 --

Dmitriy40 в сообщении #1594640 писал(а):
Обходной манёвр: перевести число в массив цифр по модулю 1000, потом объединить массив в строку с разделителями пробелом (или любым другим):
К сожалению это часто работает некорректно:
Код:
? x=1234567890023456; d=digits(x,1000); print(d); s=strjoin(d," "); print(s)
[1, 234, 567, 890, 23, 456]
1 234 567 890 23 456
Ну тогда можно преобразовать каждую "цифру" в строку отдельно через strprintf, а потом уж объединить в единую строку:
Код:
? x=1234567890023456; d=digits(x,1000); for(i=2,#d, d[i]=strprintf("%03d",d[i]);); d[1]=Str(d[1]); print(strjoin(d," "));
1 234 567 890 023 456
Это правильно работает и для чисел до 1000 (и до 10 тоже).

-- 21.05.2023, 18:48 --

Вашу задачу -- сортировку массива векторов чисел из текстовых строк по 2, 5, 1 элементу (ну для примера) -- можно решить в одну строчку:
Код:
? s=["34332 3 5 433 445 678", "5639 3 5 46 33 366", "456 3 5 46 55 78"] \\Реально заменимо на s=readstr(file); вообще без всяких циклов
["34332 3 5 433 445 678", "5639 3 5 46 33 366", "456 3 5 46 55 78"]
? vecextract(s,vecsort(eval(apply(t->vecextract(strsplit(t," "),[2,5,1]),s)),,1))
["5639 3 5 46 33 366", "456 3 5 46 55 78", "34332 3 5 433 445 678"]
Тут сначала делим строки на кусочки, выбираем только нужные столбцы (и в нужном для сортировки порядке), преобразуем строки в числа, получаем вектор перестановок для отсортированного результата, ну и переставляем исходный массив строк в желаемом порядке.

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


13/08/08
14495
Dmitriy40
Спасибо. Возьмусь за внимательное изучение. Насчёт сокращения вектора вот что понималось. Скажем, поступает вектор с длинным нулевым хвостом неизвестной длины. Я делал так: в цикле находил первый от конца ненулевой элемент. А далее переносил вектор в другой соответствующей длины. А мне казалось, что встречал где-то функцию усекновения нулевого начала или хвоста.
Вот понял, что можно вырезать три элемента:
a=concat( a[1..5], a[9..2000] ) :-)

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


05/09/16
12130
gris в сообщении #1594620 писал(а):
В PARI многие вещи делаются одной функцией, но надо до неё добраться.
Ну вот, например,
[ 111, 22, 33 ]
[ 11, 543, 77 ]
[ 111, 22, 32 ]
после сортировки
[ 11, 543, 77 ]
[ 111, 22, 32 ]
[ 111, 22, 33 ]

Вот так попробуйте:
? v=[[111,22,33],[11,543,77],[111,22,32]];
? print(vecsort(v,[2,3]))
[[111, 22, 32], [111, 22, 33], [11, 543, 77]]

В доках есть объяснение по функции vecsort(x, {cmpf}, {flag = 0}) . Если параметр cmpf присутвует, то
Цитата:
* a vector: sort lexicographically according to the components listed in the vector. For example, if cmpf = [2,1,3], sort with respect to the second component, and when these are equal, with respect to the first, and when these are equal, with respect to the third.

gris в сообщении #1594605 писал(а):
Надо их отсортировать по возрастанию сначала по второму элементу, потом вложенно по остальным (как это правильно называется?).

То, что вы хотите, уже есть в vecsort() - для вектора векторов можно "штатно" указать порядок компонентов по которым сортировать.

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


13/08/08
14495
wrest
спасибо.
я, правда, потыкал и понял, что мне нужно
vecsort(v,[1..3]), но по вашему намёку осознал, что нужно и RTFMить иногда :oops: .
Мне надо потеребить эту штуку практически.
vecsort(v,[3,2,1]) понравились.
А если сортировать тысячу векторов? А попробую

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


05/09/16
12130
gris в сообщении #1594650 писал(а):
А если сортировать тысячу векторов?

Дык какая разница сколько сортировать... Если конечно сортировать гигабайты, тогда наверное будет заметно, а так-то мгновенно всё.

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


13/08/08
14495
да я не о времени, а о подготовке.
Хотя, наверное, по мотивам сегодняшнего урока можно собрать игрушку:
Код:
v=[];
for( i=1,20,
   v=concat(v,[[random(10),random(10),random(10)]]); 
);
print(v);
print(vecsort(v,[1,2,3]))

Получилось интересненько.

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


20/08/14
11872
Россия, Москва
А concat-то зачем? Он же страшно медленный! Можно же проще:
v=vector(20,i,[random(10),random(10),random(10)]);

wrest
Кстати спасибо, тоже не знал про vecsort(,[]).

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


13/08/08
14495
а я хотел из файла считывать
Код:
{
  tin= fileopen("C:/GRIS/list_of_12.txt");
  a=[];

  while (str = filereadstr(tin),
    a=concat( a,[eval(strsplit(str, " "))] );
  );

  a=vecsort(a,[2..12]);
  for( i=1,k, print(a[i]) ); 
}

И работает! Спасибо Dmitriy40 и wrest :-) :-) :-)

Чем мне нравится ПАРИ. Можно не долго думая накидать программку и она порадует. Потом, обратившись за советом к докам (во всех смыслах :-) ) и старательно впитав новые знания, можно улучшить эту программку и забыть её, но в следующий раз всё будет лучше. ВотЪ.

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


05/09/16
12130
gris в сообщении #1594653 писал(а):
да я не о времени, а о подготовке.

Так вы писали что уже всё готово:
gris в сообщении #1594605 писал(а):
Они сидят в текстовом файле по одному вектору в строке.

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


20/08/14
11872
Россия, Москва
gris
Из файла прекрасно читаются прямо в вектор строк: a=readstr("C:/GRIS/list_of_12.txt");
После чего вектор строк сортируется по числам в столбцах 2,5,1: aa=vecextract(a,vecsort(eval(apply(t->strsplit(t," "),a)),[2,5,1],1));

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


05/09/16
12130
gris в сообщении #1594658 писал(а):
а я хотел из файла считывать

Если, кстати, у вас текстовый файл вот такого вида, например vector.txt буквально такой, т.е. со скобками и запятыми (можете добавить или убрать пробелы по вкусу):
Код:
[111,22,33]
[11,543,77]
[111,22,32]

То считать его и сразу сортировать по-вашему можно прямо так, как вы любите, в одну строку, без создания (явного) промежуточного вектора строк и парсинга каждой строки :mrgreen: :
? v=vecsort(readvec("vector.txt"),[2,3]);
? print(v)
[[111, 22, 32], [111, 22, 33], [11, 543, 77]]

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


13/08/08
14495
красивое.
wrest, попробовал и это. исходные данные подредактировал и вот оно:
Код:
v=vecsort( readvec("C:/GRIS/list_of_12.txt"),[3..12] );
for( i=1,#v, print(v[i]) ); 

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


05/09/16
12130
gris в сообщении #1594668 писал(а):
исходные данные подредактировал

Если, кстати, вы будете часто манипулировать текстом

(Оффтоп)

(ну типа заменить пробелы на запятые, добавить скобки и т.п.) то в линуксе (ну и в виндовсе наверное, есть аналоги) есть чрезвычайно могучие штуки которые это умеют.
Например ваша задача с прежним исходным файлом vector.txt с содержанием
Код:
[111,22,33]
[11,543,77]
[111,22,32]

легко сортируется командой sort так как вы хотели:
Код:
~ $ sort -t ',' -nk2 -nk3 vector.txt
[111,22,32]
[111,22,33]
[11,543,77]
~ $

Это конечно немного офтоп, но просто pari/gp не слишком заточен на манипуляцию строками, хотя и может.
Ну и awk с sed-ом конечно... Могут всё :roll:
С другой стороны, чтобы вам не манипулировать при вводе, делайте промежуточные файлы подходящими при выводе, ведь вы выводите тоже из pari/gp так что можете сделать нужный для ввода формат сразу при выводе.

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


13/08/08
14495
Под впечатлением от вчерашнего решил побаловаться с векторами. Типа трёхмерных

a=[
[[111,112,113],[121,122,123],[131,132,133]],
[[211,212,213],[221,222,223],[231,232,233]],
[[311,312,313],[321,322,323],[331,332,333]]];
print( a[1][2] );
print( a[2][3][1] );
print( sum( i=1,3, a[i][i][i]) );

[121, 122, 123]
231
666

Есть ли в этом какой-то смысл? К чему можно применять? Какие есть средства обработки?

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


20/08/14
11872
Россия, Москва
Смысл есть всегда. Или его можно придумать. Или он сам появится из решаемой задачи.
Например уже в известной Вам задаче быстрого (на самом деле быстрого, а не на PARI) поиска симметричных цепочек возникают четырёхмерные структуры данных.
Учитывая отсутствие стандартных типов данных для матриц размерности выше второй, только на векторах их и строить.
Любое пространственное скалярное поле уже требует трёхмерной матрицы, а если поле не скалярное или не одно (нужно несколько величин в каждой точке), то и четырёхмерной (точнее чаще трёхмерной матрицы векторов с разнородными элементами). И кстати нередко вектор векторов удобнее матрицы - если матрица нужна не строго прямоугольная, хороший и известный Вам пример - список допустимых остатков по модулю простого для конкретного паттерна, для каждого простого он своей длины, а если паттернов больше одного, то вот уже и трёхмерная структура.
Средства обработки или отсутствуют (как и сами такие типы данных), или базируются на том что это всё же вектора.
Но можно считать что если вы не знаете зачем это нужно -- то оно вам и не нужно. ;-) Т.е. потребность может идти от задачи, а не от теоретических измышлений.

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

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



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

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


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

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