2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу Пред.  1 ... 7, 8, 9, 10, 11, 12, 13 ... 54  След.

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


13/02/17

317
Varanasi
Dmitriy40, VAL, спасибо за помощь. Я разобрался с функциями valuation и ispower, a также с печатью в файл, но так и не осилил данный код.

Код:
ismn(n) = n++; n == 2^valuation(n, 2);
isok(n) = ismn(n) || (ispower(n, , &m) && ismn(m));


непонятно, зачем берется инкремент
Код:
ismn(n) = n++;
, далее происходит сравнение по которому определяется является ли n степенью двойки:
Код:
n == 2^valuation(n, 2);
, если n является степенью двойки, то куда пишется результат сравнения =1? Если нет, то куда 0?
где здесь условные операторы? Далее:
Код:
isok(n) = ismn(n) || (ispower(n, , &m) && ismn(m))
, также непонятно, это просто присваивание, или сравнение, или здесь также есть какие-то скрытые условные операторы.

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

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


27/04/09
28128
Aether в сообщении #1194704 писал(а):
непонятно, зачем берется инкремент
Чтобы сделать из потенциального числа Мерсенна потенциальную степень двойки. Дальше как раз проверяется, степерь ли двойки получилась, как вы заметили.

Aether в сообщении #1194704 писал(а):
куда пишется результат сравнения =1? Если нет, то куда 0?
Возвращается. Эта функция логического типа.

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


13/02/17

317
Varanasi
arseniiv в сообщении #1194706 писал(а):
Чтобы сделать из потенциального числа Мерсенна потенциальную степень двойки. Дальше как раз проверяется, степерь ли двойки получилась, как вы заметили.


Спасибо за ответ. Простите, но я запутался ещё более.

Начинаем исполнять алгоритм: определяем функцию ismn(n) = n++; Далее проверяем, равно ли n степени 2; допустим неравно, куда помещается(возвращается) значение логической переменной ложь=0? И что программа делает далее?

Теперь допустим результат сравнения равен истине, т.е. 1, что далее делает программа и куда эта 1 возвращается?

Во второй строке кода я вижу условия, но не вижу в коде ни одного условного оператора. Как он работает и работает ли вообще?

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


27/04/09
28128
А, ну тут дело в том, что expr1; expr2 — это цельное выражение, и оно целиком является определением функции, притом так, что при вычислении функции её аргумент подставляется в это выражение, оно вычисляется, и его результат становится результатом функции. Логическое значение будет использоваться так, как используется результат функции в каком-то коде, куда она входит. Сам по себе он никуда не запишется. Например, если вы в интерактивной строке напишете ismn(3), то результат должен вывестись рядом же в консоль как и результат вычисления любого выражения, которое вы так введёте.

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


20/08/14
11867
Россия, Москва
Aether в сообщении #1194708 писал(а):
определяем функцию ismn(n) = n++; Далее проверяем,

Не так, это вот "далее" - это всё ещё продолжение функции. До конца строки. Вот так вот! Сам поразился. Т.е. функция ismn(n) возвращает результат проверки равенства n == 2^..., причём n берётся уже увеличенное на 1.
Функция isok(n) определена как ИЛИ двух условий: или число Мерсенна, или выражение в скобках. Если истинно любое из этих условий - функция вернёт истину.
Пользоваться же этим примерно так: вызываете функцию isok с аргументом, который желаете проверить является ли он степенью числа Мерсенна и функция вернёт вам или "да"/истину или "нет"/ложь. Пара примеров:
isok(7)
isok(100500)
for(i=1,100, if(isok(i^3), print(i^3," found!"))) :-)

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


13/02/17

317
Varanasi
Dmitriy40 в сообщении #1194711 писал(а):
Код:
for(i=1,100, if(isok(i^3), print(i^3," found!")))


arseniiv, Dmitriy40,

Спасибо, разобрался, но использовать функцию isok лучше наверное так:
Код:
for(i=1,1000000, if(isok(i) ==1, print1(i,", ")))


Последовательность вроде бы правильную строит.

-- 23.02.2017, 04:27 --

Теперь вопрос на засыпку, как бы эту самую isok(n) модифицировать так, чтобы она выдавала истину не когда n- число Мерсенна или степень числа Мерсенна, а когда n - произведение степеней чисел Мерсенна. Т.е. сначала необходимо найти для числа n все возможные разложения на множители, учитывая множитель 1, затем каждое разложение проверить, являются ли все его члены степенями чисел Mерсенна.

Подскажите пожалуйста, что-то не могу найти, есть ли функция, дающая разложения числа на множители? Или нужно все эти разложения искать с помощью факторизации числа самому?

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


20/08/14
11867
Россия, Москва
Aether в сообщении #1194728 писал(а):
функция, дающая разложения числа на множители?

divisors - выдаст вектор всех делителей, включая 1 и само число.
factor - выдаст факторизацию (разложение на степени простых чисел).
С factor начинаются ещё несколько функций, например factorint, возможно они Вам лучше подойдут.

Функции, возвращающие логические типы (и ismn() и isok()), лучше использовать именно без сравнения с 0 или 1: if(isok(i), ...) или if(isok(i) && ismn(i), ...).

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


27/04/09
28128
Да, если даже (какой-то) язык считает логические значения целыми числами, в нём обычно все условные конструкции будут принимать эти целые числа без нужды в лишних сравнениях. А если представить, что для получения логического значения из логического же значения b надо сравнить последнее с нулём, то останавливаться на единственном сравнении рано, надо записать бесконечную в обе стороны строку сравнений …(…((b == 0) == 0)… == 0)… и даже после этого разочарованно помотать головой.

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


13/02/17

317
Varanasi
Да, работает и без сравнения логической переменной с её значением. Сравнение было лишним, хотя с ним программа и работала.

Теперь вопрос вот в чем, с помощью функции divisors(n) получаю делители числа n в виде вектора длиной k. Для различных чисел длина вектора будет различной. Необходимо как-то определить длину вектора k, а затем каждое его значение проверить не является ли оно степенью числа Мерсенна. Если является, то записать в другой вектор.

Как же определить длину вектора v=divisors(n), чтобы работать с его значениями в цикле? И как их вписывать в другой вектор, если наверное сначала его необходимо создать, но необходимая его длина неизвестна, поскольку заранее неизвестно количество чисел, являющихся степенями чисел Мерсенна?

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


11/01/06
5710
Aether в сообщении #1194820 писал(а):
Как же определить длину вектора v=divisors(n), чтобы работать с его значениями в цикле?

Не обязательно явно строить вектор делителей. Перебрать их в цикле проще командой
Код:
fordiv(n,d, ...)
Здесь $d$ пробегает все делители числа $n$. А количество всех делителей числа $n$ можно получить командой
Код:
numdiv(n)

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


13/02/17

317
Varanasi
arseniiv в сообщении #1194805 писал(а):
А если представить, что для получения логического значения из логического же значения b надо сравнить последнее с нулём, то останавливаться на единственном сравнении рано, надо записать бесконечную в обе стороны строку сравнений …(…((b == 0) == 0)… == 0)… и даже после этого разочарованно помотать головой.



Не понимаю, зачем бесконечная строка сравнений, а не одно сравнение, ведь функция сравнения не рекурсивна? Сравниваем ведь не само с собой, а с 0.

-- 23.02.2017, 19:54 --

maxal в сообщении #1194823 писал(а):
Не обязательно явно строить вектор делителей. Перебрать их в цикле проще командой Код:

fordiv(n,d, ...)
Здесь $d$ пробегает все делители числа $n$. А количество всех делителей числа $n$ можно получить командой Код:

numdiv(n)


Спасибо.

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


27/04/09
28128

(Оффтоп)

Aether в сообщении #1194824 писал(а):
Не понимаю, зачем бесконечная строка сравнений, а не одно сравнение, ведь функция сравнения не рекурсивна? Сравниваем ведь не само с собой, а с 0.
Ну, это не относится к теме, я просто показал, что должно быть, если доводить конструкцию логическоезначение == 0 до логического завершения. Ну и я там ошибся, вы ведь сравнивали с единицей, а если сравнивать с нулём, надо это делать чётное число раз.

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


13/02/17

317
Varanasi
Пробую так,
Код:
fordiv(n,d, isok(d), print(d))
но комп ругается, слишком много аргументов.

Неужели внутри этого цикла нельзя устраивать проверку делителей или какие-то операции с ними? Или где-то нужны скобки?

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


11/01/06
5710
Aether, разделять операторы внутри тела цикла нужно ";", а не ",". Кроме того, вы возможно хотели использовать "if(... , ...)".

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


20/08/14
11867
Россия, Москва
maxal
Спасибо, не помнил про такой цикл.
(К сожалению во встроенной справке трудно найти нужное по смыслу если не знаешь точного названия.)

Aether
Хоть это уже и не нужно, но всё же: размер вектора v можно получить функцией n=matsize(v)[2] (кажется выдаёт размер матрицы по второй координате, но для обычных векторов работает правильно).
Добавление числа x к вектору v делается функцией v=concat(v,x).

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 810 ]  На страницу Пред.  1 ... 7, 8, 9, 10, 11, 12, 13 ... 54  След.

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



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

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


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

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