Commit 7c51885a authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧
Browse files

Add support for the combinatoric operators "comb" and "perm"

Thanks to Stephen Swanson for the idea and initial implementation.
parent 7ec50877
Pipeline #175024 skipped
......@@ -46,6 +46,7 @@ set(analitza_SRCS
commands/matrixcommands.cpp
commands/blockmatrixcommands.cpp
commands/matrixqueries.cpp
commands/combinatronics.cpp
)
if(EIGEN3_FOUND)
......
......@@ -43,6 +43,7 @@
#include "commands/matrixcommands.h"
#include "commands/blockmatrixcommands.h"
#include "commands/matrixqueries.h"
#include "commands/combinatronics.h"
#include <config-analitza.h>
#ifdef HAVE_EIGEN3
......@@ -176,6 +177,8 @@ void Analyzer::registerBuiltinMethods()
m_builtin.insertFunction(IsZeroMatrixCommand::id, IsZeroMatrixCommand::type, new IsZeroMatrixCommand);
m_builtin.insertFunction(IsIdentityMatrixCommand::id, IsIdentityMatrixCommand::type, new IsIdentityMatrixCommand);
m_builtin.insertFunction(IsDiagonalMatrixCommand::id, IsDiagonalMatrixCommand::type, new IsDiagonalMatrixCommand);
m_builtin.insertFunction(CombinationCommand::id, CombinationCommand::type, new CombinationCommand);
m_builtin.insertFunction(PermutationCommand::id, PermutationCommand::type, new PermutationCommand);
#ifdef HAVE_EIGEN3
m_builtin.insertFunction(EigenvaluesCommand::id, EigenvaluesCommand::type, new EigenvaluesCommand);
m_builtin.insertFunction(EigenvectorsCommand::id, EigenvectorsCommand::type, new EigenvectorsCommand);
......
/*************************************************************************************
* Copyright (C) 2022 Aleix Pol Gonzalez <aleixpol@kde.org> *
* Copyright (C) 2022 Stephen Swanson <stephen.swanson@mailbox.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#include "combinatronics.h"
#include <QCoreApplication>
#include "expression.h"
#include "list.h"
#include "value.h"
using namespace Analitza;
const QString CombinationCommand::id = QStringLiteral("comb");
const ExpressionType CombinationCommand::type = ExpressionType(ExpressionType::Lambda)
.addParameter(ExpressionType::Value)
.addParameter(ExpressionType::Value)
.addParameter(ExpressionType::Value);
Expression CombinationCommand::operator()(const QList<Expression>& args)
{
const auto a = args.constFirst().toReal().intValue();
const auto b = args.constLast().toReal().intValue();
// a=n b=r
uint n_factorial=1;
for(int i=a; i>1.; i--) {
n_factorial*=floor(i);
}
uint r_factorial=1;
for(int i=b; i>1.; i--) {
r_factorial*=floor(i);
}
uint rn = a - b;
uint rn_factorial=1;
for(int i=rn; i>1.; i--) {
rn_factorial*=floor(i);
}
uint res = n_factorial / (r_factorial * rn_factorial);
return Expression(Cn(res));
}
const QString PermutationCommand::id = QStringLiteral("perm");
const ExpressionType PermutationCommand::type = ExpressionType(ExpressionType::Lambda)
.addParameter(ExpressionType::Value)
.addParameter(ExpressionType::Value)
.addParameter(ExpressionType::Value);
Expression PermutationCommand::operator()(const QList<Expression>& args)
{
const auto a = args.constFirst().toReal().value();
const auto b = args.constLast().toReal().intValue();
// a=n b=r
if (b > a) {
return Expression(Cn(0));
} else {
uint n_factorial=1;
for(int i=a; i>1.; i--) {
n_factorial*=floor(i);
}
uint rn = a - b;
uint rn_factorial=1;
for(int i=rn; i>1.; i--) {
rn_factorial*=floor(i);
}
uint res = n_factorial / rn_factorial;
return Expression(Cn(res));
}
}
/*************************************************************************************
* Copyright (C) 2022 Aleix Pol Gonzalez <aleixpol@kde.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#ifndef COMBINATRONICS_H
#define COMBINATRONICS_H
#include "builtinmethods.h"
class CombinationCommand: public Analitza::FunctionDefinition
{
public:
virtual Analitza::Expression operator()(const QList< Analitza::Expression >& args) override;
static const QString id;
static const Analitza::ExpressionType type;
};
class PermutationCommand: public Analitza::FunctionDefinition
{
public:
virtual Analitza::Expression operator()(const QList< Analitza::Expression >& args) override;
static const QString id;
static const Analitza::ExpressionType type;
};
#endif // REALPOWER_H
/*************************************************************************************
* Copyright (C) 2010 by Aleix Pol <aleixpol@kde.org> *
* Copyright (C) 2022 Stephen Swanson <stephen.swanson@mailbox.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -212,6 +213,9 @@ void BuiltInTest::testCall_data()
QTest::newRow("lambdaarg") << (IN QStringLiteral("call:=(x,y)->x(y)") << QStringLiteral("car:=call(vehicle,4)") << QStringLiteral("tires(car)")) << "4";
QTest::newRow("ref") << (IN QStringLiteral("sum(readint(refint(x)) : x=1..10)")) << "55";
QTest::newRow("comb") << (IN QStringLiteral("comb(5,2)")) << "10";
QTest::newRow("perm") << (IN QStringLiteral("perm(5,2)")) << "20";
QTest::newRow("sum") << (IN QStringLiteral("sum(x : x@createlist(3))")) << "75";
QTest::newRow("sum2") << (IN QStringLiteral("f:=w->sum(x : x@w)") << QStringLiteral("f(createlist(3))")) << "75";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment