2014 dxdy logo

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

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




На страницу Пред.  1 ... 7, 8, 9, 10, 11, 12, 13 ... 55  След.

А вам пакет PARI/GP интересен?
Да 83%  83%  [ 58 ]
Нет 6%  6%  [ 4 ]
Не уверен(а) 11%  11%  [ 8 ]
Всего голосов : 70
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 00:10 
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 
Aether в сообщении #1194704 писал(а):
непонятно, зачем берется инкремент
Чтобы сделать из потенциального числа Мерсенна потенциальную степень двойки. Дальше как раз проверяется, степерь ли двойки получилась, как вы заметили.

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

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 00:34 
arseniiv в сообщении #1194706 писал(а):
Чтобы сделать из потенциального числа Мерсенна потенциальную степень двойки. Дальше как раз проверяется, степерь ли двойки получилась, как вы заметили.


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

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

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

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

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 00:46 
А, ну тут дело в том, что expr1; expr2 — это цельное выражение, и оно целиком является определением функции, притом так, что при вычислении функции её аргумент подставляется в это выражение, оно вычисляется, и его результат становится результатом функции. Логическое значение будет использоваться так, как используется результат функции в каком-то коде, куда она входит. Сам по себе он никуда не запишется. Например, если вы в интерактивной строке напишете ismn(3), то результат должен вывестись рядом же в консоль как и результат вычисления любого выражения, которое вы так введёте.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 00:59 
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 
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 
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 
Да, если даже (какой-то) язык считает логические значения целыми числами, в нём обычно все условные конструкции будут принимать эти целые числа без нужды в лишних сравнениях. А если представить, что для получения логического значения из логического же значения b надо сравнить последнее с нулём, то останавливаться на единственном сравнении рано, надо записать бесконечную в обе стороны строку сравнений …(…((b == 0) == 0)… == 0)… и даже после этого разочарованно помотать головой.

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 18:43 
Да, работает и без сравнения логической переменной с её значением. Сравнение было лишним, хотя с ним программа и работала.

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

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

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 18:51 
Аватара пользователя
Aether в сообщении #1194820 писал(а):
Как же определить длину вектора v=divisors(n), чтобы работать с его значениями в цикле?

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

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 18:53 
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 

(Оффтоп)

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

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 19:22 
Пробую так,
Код:
fordiv(n,d, isok(d), print(d))
но комп ругается, слишком много аргументов.

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

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 19:29 
Аватара пользователя
Aether, разделять операторы внутри тела цикла нужно ";", а не ",". Кроме того, вы возможно хотели использовать "if(... , ...)".

 
 
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение23.02.2017, 19:33 
maxal
Спасибо, не помнил про такой цикл.
(К сожалению во встроенной справке трудно найти нужное по смыслу если не знаешь точного названия.)

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

 
 
 [ Сообщений: 824 ]  На страницу Пред.  1 ... 7, 8, 9, 10, 11, 12, 13 ... 55  След.


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