01.03.2011 - as a initial commit

This commit is contained in:
peri4
2011-03-01 06:07:16 +03:00
parent 3610ea9212
commit b21a0496cd
20 changed files with 1589 additions and 522 deletions

View File

@@ -28,5 +28,8 @@ Project Target=pip,pip
Working Directory=
isExecutable=false
[MakeBuilder]
Number Of Jobs=5
[Project]
VersionControlSupport=kdevgit

460
Makefile
View File

@@ -1,460 +0,0 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 2.8
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
#=============================================================================
# Special targets provided by cmake.
# Disable implicit rules so canoncical targets will work.
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
.SUFFIXES: .hpux_make_needs_suffix_list
# Suppress display of executed commands.
$(VERBOSE).SILENT:
# A target that is always out of date.
cmake_force:
.PHONY : cmake_force
#=============================================================================
# Set environment variables for the build.
# The shell in which to execute make rules.
SHELL = /bin/sh
# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake
# The command to remove a file.
RM = /usr/bin/cmake -E remove -f
# The program to use to edit the cache.
CMAKE_EDIT_COMMAND = /usr/bin/ccmake
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /home/peri4/pprojects/pip
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /home/peri4/pprojects/pip
#=============================================================================
# Targets provided globally by CMake.
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
/usr/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache
# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast
# The main all target
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /home/peri4/pprojects/pip/CMakeFiles /home/peri4/pprojects/pip/CMakeFiles/progress.marks
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start /home/peri4/pprojects/pip/CMakeFiles 0
.PHONY : all
# The main clean target
clean:
$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean
# The main clean target
clean/fast: clean
.PHONY : clean/fast
# Prepare targets for installation.
preinstall: all
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall
# Prepare targets for installation.
preinstall/fast:
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast
# clear depends
depend:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend
#=============================================================================
# Target rules for targets named pip
# Build rule for target.
pip: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 pip
.PHONY : pip
# fast build rule for target.
pip/fast:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/build
.PHONY : pip/fast
main.o: main.cpp.o
.PHONY : main.o
# target to build an object file
main.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/main.cpp.o
.PHONY : main.cpp.o
main.i: main.cpp.i
.PHONY : main.i
# target to preprocess a source file
main.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/main.cpp.i
.PHONY : main.cpp.i
main.s: main.cpp.s
.PHONY : main.s
# target to generate assembly for a file
main.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/main.cpp.s
.PHONY : main.cpp.s
piconfig.o: piconfig.cpp.o
.PHONY : piconfig.o
# target to build an object file
piconfig.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piconfig.cpp.o
.PHONY : piconfig.cpp.o
piconfig.i: piconfig.cpp.i
.PHONY : piconfig.i
# target to preprocess a source file
piconfig.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piconfig.cpp.i
.PHONY : piconfig.cpp.i
piconfig.s: piconfig.cpp.s
.PHONY : piconfig.s
# target to generate assembly for a file
piconfig.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piconfig.cpp.s
.PHONY : piconfig.cpp.s
piconsole.o: piconsole.cpp.o
.PHONY : piconsole.o
# target to build an object file
piconsole.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piconsole.cpp.o
.PHONY : piconsole.cpp.o
piconsole.i: piconsole.cpp.i
.PHONY : piconsole.i
# target to preprocess a source file
piconsole.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piconsole.cpp.i
.PHONY : piconsole.cpp.i
piconsole.s: piconsole.cpp.s
.PHONY : piconsole.s
# target to generate assembly for a file
piconsole.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piconsole.cpp.s
.PHONY : piconsole.cpp.s
piethernet.o: piethernet.cpp.o
.PHONY : piethernet.o
# target to build an object file
piethernet.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piethernet.cpp.o
.PHONY : piethernet.cpp.o
piethernet.i: piethernet.cpp.i
.PHONY : piethernet.i
# target to preprocess a source file
piethernet.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piethernet.cpp.i
.PHONY : piethernet.cpp.i
piethernet.s: piethernet.cpp.s
.PHONY : piethernet.s
# target to generate assembly for a file
piethernet.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piethernet.cpp.s
.PHONY : piethernet.cpp.s
pifile.o: pifile.cpp.o
.PHONY : pifile.o
# target to build an object file
pifile.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pifile.cpp.o
.PHONY : pifile.cpp.o
pifile.i: pifile.cpp.i
.PHONY : pifile.i
# target to preprocess a source file
pifile.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pifile.cpp.i
.PHONY : pifile.cpp.i
pifile.s: pifile.cpp.s
.PHONY : pifile.s
# target to generate assembly for a file
pifile.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pifile.cpp.s
.PHONY : pifile.cpp.s
pikbdlistener.o: pikbdlistener.cpp.o
.PHONY : pikbdlistener.o
# target to build an object file
pikbdlistener.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pikbdlistener.cpp.o
.PHONY : pikbdlistener.cpp.o
pikbdlistener.i: pikbdlistener.cpp.i
.PHONY : pikbdlistener.i
# target to preprocess a source file
pikbdlistener.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pikbdlistener.cpp.i
.PHONY : pikbdlistener.cpp.i
pikbdlistener.s: pikbdlistener.cpp.s
.PHONY : pikbdlistener.s
# target to generate assembly for a file
pikbdlistener.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pikbdlistener.cpp.s
.PHONY : pikbdlistener.cpp.s
piprotocol.o: piprotocol.cpp.o
.PHONY : piprotocol.o
# target to build an object file
piprotocol.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piprotocol.cpp.o
.PHONY : piprotocol.cpp.o
piprotocol.i: piprotocol.cpp.i
.PHONY : piprotocol.i
# target to preprocess a source file
piprotocol.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piprotocol.cpp.i
.PHONY : piprotocol.cpp.i
piprotocol.s: piprotocol.cpp.s
.PHONY : piprotocol.s
# target to generate assembly for a file
piprotocol.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piprotocol.cpp.s
.PHONY : piprotocol.cpp.s
piserial.o: piserial.cpp.o
.PHONY : piserial.o
# target to build an object file
piserial.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piserial.cpp.o
.PHONY : piserial.cpp.o
piserial.i: piserial.cpp.i
.PHONY : piserial.i
# target to preprocess a source file
piserial.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piserial.cpp.i
.PHONY : piserial.cpp.i
piserial.s: piserial.cpp.s
.PHONY : piserial.s
# target to generate assembly for a file
piserial.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/piserial.cpp.s
.PHONY : piserial.cpp.s
pistring.o: pistring.cpp.o
.PHONY : pistring.o
# target to build an object file
pistring.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pistring.cpp.o
.PHONY : pistring.cpp.o
pistring.i: pistring.cpp.i
.PHONY : pistring.i
# target to preprocess a source file
pistring.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pistring.cpp.i
.PHONY : pistring.cpp.i
pistring.s: pistring.cpp.s
.PHONY : pistring.s
# target to generate assembly for a file
pistring.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pistring.cpp.s
.PHONY : pistring.cpp.s
pithread.o: pithread.cpp.o
.PHONY : pithread.o
# target to build an object file
pithread.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pithread.cpp.o
.PHONY : pithread.cpp.o
pithread.i: pithread.cpp.i
.PHONY : pithread.i
# target to preprocess a source file
pithread.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pithread.cpp.i
.PHONY : pithread.cpp.i
pithread.s: pithread.cpp.s
.PHONY : pithread.s
# target to generate assembly for a file
pithread.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pithread.cpp.s
.PHONY : pithread.cpp.s
pitimer.o: pitimer.cpp.o
.PHONY : pitimer.o
# target to build an object file
pitimer.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pitimer.cpp.o
.PHONY : pitimer.cpp.o
pitimer.i: pitimer.cpp.i
.PHONY : pitimer.i
# target to preprocess a source file
pitimer.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pitimer.cpp.i
.PHONY : pitimer.cpp.i
pitimer.s: pitimer.cpp.s
.PHONY : pitimer.s
# target to generate assembly for a file
pitimer.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pitimer.cpp.s
.PHONY : pitimer.cpp.s
pivariable.o: pivariable.cpp.o
.PHONY : pivariable.o
# target to build an object file
pivariable.cpp.o:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pivariable.cpp.o
.PHONY : pivariable.cpp.o
pivariable.i: pivariable.cpp.i
.PHONY : pivariable.i
# target to preprocess a source file
pivariable.cpp.i:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pivariable.cpp.i
.PHONY : pivariable.cpp.i
pivariable.s: pivariable.cpp.s
.PHONY : pivariable.s
# target to generate assembly for a file
pivariable.cpp.s:
$(MAKE) -f CMakeFiles/pip.dir/build.make CMakeFiles/pip.dir/pivariable.cpp.s
.PHONY : pivariable.cpp.s
# Help Target
help:
@echo "The following are some of the valid targets for this Makefile:"
@echo "... all (the default if no target is provided)"
@echo "... clean"
@echo "... depend"
@echo "... edit_cache"
@echo "... pip"
@echo "... rebuild_cache"
@echo "... main.o"
@echo "... main.i"
@echo "... main.s"
@echo "... piconfig.o"
@echo "... piconfig.i"
@echo "... piconfig.s"
@echo "... piconsole.o"
@echo "... piconsole.i"
@echo "... piconsole.s"
@echo "... piethernet.o"
@echo "... piethernet.i"
@echo "... piethernet.s"
@echo "... pifile.o"
@echo "... pifile.i"
@echo "... pifile.s"
@echo "... pikbdlistener.o"
@echo "... pikbdlistener.i"
@echo "... pikbdlistener.s"
@echo "... piprotocol.o"
@echo "... piprotocol.i"
@echo "... piprotocol.s"
@echo "... piserial.o"
@echo "... piserial.i"
@echo "... piserial.s"
@echo "... pistring.o"
@echo "... pistring.i"
@echo "... pistring.s"
@echo "... pithread.o"
@echo "... pithread.i"
@echo "... pithread.s"
@echo "... pitimer.o"
@echo "... pitimer.i"
@echo "... pitimer.s"
@echo "... pivariable.o"
@echo "... pivariable.i"
@echo "... pivariable.s"
.PHONY : help
#=============================================================================
# Special targets to cleanup operation of make.
# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system

19
clean Executable file
View File

@@ -0,0 +1,19 @@
#! /bin/bash
VERBOSE=1 make clean
rm -vf ./lib/*
#for i in $( ls -1 ); do
# if [ "`ls -1 --file-type | grep $i | grep -o /`" = "/" ]; then
# cd $i
# rm -rvf ./CMakeFiles
# rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~
# cd ../
# fi
#done
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o
#cd ./include
#for i in $( ls -1 ); do
# if [ "`ls -1 --file-type $i | grep -v @`" = "" ]; then
# rm -v $i
# fi
#done

View File

@@ -1,10 +1,26 @@
#include "pip.h"
int main(int argc, char * argv[]) {
PIMathMatrix<3, 2> m0(1., 2., 3.,
4., 5., 6.);
PIMathMatrix<3, 2> m1(1., -2., 3.,
-4., 5., -6.);
m0 += m1;
cout << m0 << endl;
/*PIString s("I love Kusia! <3");
PIByteArray c(s.data(), s.size());
c.compressHuffman();
cout << s << endl << c << endl;
//c.decompressRLE(128);
cout << c << endl;*/
PIBitArray a(0xFFF00Fu);
//cout << a << endl;
a.setBit(31);
cout << a << endl;
a.push_back(true);
cout << a << endl;
a.push_front(true);
cout << a << endl;
a.push_front(false);
cout << a << endl;
a.pop_front();
cout << a << endl;
a.pop_front();
cout << a << endl;
a.pop_front();
cout << a << endl;
};

3
make.sh Executable file
View File

@@ -0,0 +1,3 @@
#! /bin/bash
cmake ./
make $@

84
pibitarray.h Normal file
View File

@@ -0,0 +1,84 @@
#ifndef PIBITARRAY_H
#define PIBITARRAY_H
#include "piincludes.h"
class PIBitArray {
public:
inline PIBitArray(const int & size = 0) {resize(size);}
inline PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;}
inline PIBitArray(ushort val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline PIBitArray(uint val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline PIBitArray(ulong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline PIBitArray(ullong val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline PIBitArray(uchar * bytes, uint size) {resize(size * 8); memcpy(data(), bytes, size);}
inline uint bitSize() const {return size_;}
inline uint byteSize() const {return bytesInBits(size_);}
inline PIBitArray & resize(const uint & size) {size_ = size; data_.resize(bytesInBits(size_)); return *this;}
inline PIBitArray & clearBit(const uint & index) {data_[index / 8] &= ~(1 << (index % 8)); return *this;}
inline PIBitArray & setBit(const uint & index) {data_[index / 8] |= (1 << (index % 8)); return *this;}
inline PIBitArray & writeBit(const uint & index, const bool & value) {if (value) setBit(index); else clearBit(index); return *this;}
inline PIBitArray & writeBit(const uint & index, const uchar & value) {return writeBit(index, static_cast<bool>(value));}
inline PIBitArray & push_back(const bool & value) {resize(size_ + 1); writeBit(size_ - 1, value); return *this;}
inline PIBitArray & push_back(const uchar & value) {return push_back(static_cast<bool>(value));}
inline PIBitArray & insert(const uint & index, const bool & value) {
resize(size_ + 1);
uint fi = byteSize() - 1, si = index / 8, ti = index % 8;
uchar c = data_[si];
for (uint i = fi; i > si; --i) {
data_[i] <<= 1;
if ((0x80 & data_[i - 1]) == 0x80) data_[i] |= 1;
else data_[i] &= 0xFE;}
data_[si] &= (0xFF >> (7 - ti));
data_[si] |= ((c << 1) & (0xFF << (ti)));
if (value) data_[si] |= (1 << ti);
else data_[si] &= ~(1 << ti);
return *this;}
inline PIBitArray & insert(const uint & index, const uchar & value) {return push_back(static_cast<bool>(value));}
inline PIBitArray & push_front(const bool & value) {return insert(0, value);}
inline PIBitArray & push_front(const uchar & value) {return push_front(static_cast<bool>(value));}
inline PIBitArray & pop_back() {return resize(size_ - 1);}
inline PIBitArray & pop_front() {
if (size_ == 0) return *this;
uint fi = byteSize() - 1;
for (uint i = 0; i < fi; ++i) {
data_[i] >>= 1;
if ((1 & data_[i + 1]) == 1) data_[i] |= 0x80;
else data_[i] &= 0x7F;}
data_[fi] >>= 1;
resize(size_ - 1);
return *this;}
inline PIBitArray & append(const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) push_back(ba[i]); return *this;}
inline uchar * data() {return data_.data();}
inline uchar toUChar() {if (size_ == 0) return 0; return data_[0];}
inline ushort toUShort() {ushort t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
inline uint toUInt() {uint t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
inline ulong toULong() {ulong t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
inline ullong toULLong() {ullong t = 0; memcpy(&t, data(), piMin<uint>(byteSize(), sizeof(t))); return t;}
inline bool at(const uint & index) const {return (1 & (data_[index / 8] >> (index % 8))) == 1 ? true : false;}
inline bool operator [](const uint & index) const {return at(index);}
inline void operator +=(const PIBitArray & ba) {append(ba);}
inline bool operator ==(const PIBitArray & ba) const {if (bitSize() != ba.bitSize()) return false; for (uint i = 0; i < bitSize(); ++i) if (at(i) != ba[i]) return false; return true;}
inline bool operator !=(const PIBitArray & ba) const {return !(*this == ba);}
inline void operator =(const uchar & val) {resize(sizeof(val) * 8); data_[0] = val;}
inline void operator =(const ushort & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline void operator =(const uint & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline void operator =(const ulong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
inline void operator =(const ullong & val) {resize(sizeof(val) * 8); memcpy(data(), &val, sizeof(val));}
private:
inline uint bytesInBits(const uint & bits) const {return (bits + 7) / 8;}
PIVector<uchar> data_;
uint size_;
};
inline std::ostream & operator <<(std::ostream & s, const PIBitArray & ba) {for (uint i = 0; i < ba.bitSize(); ++i) {s << ba[i]; if (i % 8 == 7) s << ' ';} return s;}
#endif // PIBITARRAY_H

140
pibytearray.cpp Normal file
View File

@@ -0,0 +1,140 @@
#include "pibytearray.h"
int PIHuffman::nodeCompare(const void * f, const void * s) {
return (reinterpret_cast<node * >(const_cast<void * >(s))->freq -
reinterpret_cast<node * >(const_cast<void * >(f))->freq);
}
PIVector<uchar> PIHuffman::compress(const PIVector<uchar> & src) {
calcFrequencies(src);
return src;
}
void PIHuffman::calcFrequencies(const PIVector<uchar> & src) {
nodes.resize(256);
for (uint i = 0; i < 256; ++i) {
nodes[i].parent = nodes[i].right = nodes[i].left = 0;
nodes[i].freq = 0;
nodes[i].word.resize(1);
nodes[i].word[0] = static_cast<uchar>(i);
}
for (uint i = 0; i < src.size(); ++i)
nodes[src[i]].freq++;
std::qsort(nodes.data(), 256, sizeof(node), nodeCompare);
for (uint i = 255; i >= 0; --i)
if (nodes[i].freq > 0 && i < 255)
{nodes.remove(i + 1, 255 - i); break;}
for (uint i = 0; i < nodes.size(); ++i)
cout << string((char*)nodes[i].word.data(), 1) << ": " << nodes[i].freq << endl;
}
PIHuffman PIByteArray::huffman;
PIByteArray & PIByteArray::convertToBase64() {
base64HelpStruct hs;
PIByteArray t;
if (size() == 0) return *this;
uint sz = (size() / 3) * 3;
for (uint i = 0; i < sz; ++i) {
hs.byte0 = hs.byte1 = hs.byte2 = 0;
hs.byte0 = at(i);
hs.byte1 = at(++i);
hs.byte2 = at(++i);
t.push_back(base64Table[hs.ascii0]);
t.push_back(base64Table[hs.ascii1]);
t.push_back(base64Table[hs.ascii2]);
t.push_back(base64Table[hs.ascii3]);
}
hs.byte0 = hs.byte1 = hs.byte2 = 0; sz = size() % 3;
switch (sz) {
case 1:
hs.byte0 = back();
t.push_back(base64Table[hs.ascii0]);
t.push_back(base64Table[hs.ascii1]);
t.push_back('=');
t.push_back('=');
break;
case 2:
hs.byte0 = at(size() - 2); hs.byte1 = back();
t.push_back(base64Table[hs.ascii0]);
t.push_back(base64Table[hs.ascii1]);
t.push_back(base64Table[hs.ascii2]);
t.push_back('=');
break;
default: break;
}
*this = t;
return *this;
}
PIByteArray & PIByteArray::convertFromBase64() {
base64HelpStruct hs;
PIByteArray t;
uint sz = size();
if (sz == 0) return *this;
for (uint i = 0; i < sz; ++i) {
hs.byte0 = hs.byte1 = hs.byte2 = 0;
hs.ascii0 = base64InvTable[at(i)];
hs.ascii1 = base64InvTable[at(++i)];
hs.ascii2 = base64InvTable[at(++i)];
hs.ascii3 = base64InvTable[at(++i)];
t.push_back(hs.byte0);
t.push_back(hs.byte1);
t.push_back(hs.byte2);
}
if (back() == '=') t.pop_back();
if (sz > 1) if (at(sz - 2) == '=') t.pop_back();
*this = t;
return *this;
}
PIByteArray & PIByteArray::compressRLE(uchar threshold) {
PIByteArray t;
uchar fb, clen, mlen = 255 - threshold;
for (uint i = 0; i < size();) {
fb = at(i);
clen = 1;
while (at(++i) == fb) {
++clen;
if (clen == mlen)
break;
}
if (clen > 1) {
t.push_back(threshold + clen);
t.push_back(fb);
continue;
}
if (fb >= threshold) {
t.push_back(threshold + 1);
t.push_back(fb);
} else
t.push_back(fb);
}
*this = t;
return *this;
}
PIByteArray & PIByteArray::decompressRLE(uchar threshold) {
PIByteArray t;
uchar fb, clen;
for (uint i = 0; i < size(); ++i) {
fb = at(i);
if (fb >= threshold) {
clen = fb - threshold;
fb = at(++i);
for (uint j = 0; j < clen; ++j)
t.push_back(fb);
continue;
} else
t.push_back(fb);
}
*this = t;
return *this;
}

114
pibytearray.h Normal file
View File

@@ -0,0 +1,114 @@
#ifndef PIBYTEARRAY_H
#define PIBYTEARRAY_H
#include "pibitarray.h"
#pragma pack(push, 1)
static const char base64Table[64] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f};
static const char base64InvTable[256] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x3F,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,
0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE,
0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
#pragma pack(pop)
class PIByteArray;
class PIHuffman {
public:
PIVector<uchar> compress(const PIVector<uchar> & src);
private:
struct node {
int freq;
PIVector<uchar> word;
PIBitArray path;
node * parent;
node * right;
node * left;
};
static int nodeCompare(const void * f, const void * s);
void calcFrequencies(const PIVector<uchar> & src);
PIVector<node> nodes;
};
class PIByteArray: public PIVector<uchar> {
public:
PIByteArray() {;}
PIByteArray(const char * data, uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
PIByteArray(const uchar * data, uint size) {for (uint i = 0; i < size; ++i) push_back(data[i]);}
PIByteArray & convertToBase64();
PIByteArray & convertFromBase64();
PIByteArray & compressRLE(uchar threshold = 192);
PIByteArray & decompressRLE(uchar threshold = 192);
inline PIByteArray & compressHuffman() {*this = huffman.compress(*this); return *this;}
inline PIByteArray toBase64() {PIByteArray ba(*this); ba.convertToBase64(); return ba;}
inline PIByteArray fromBase64() {PIByteArray ba(*this); ba.convertFromBase64(); return ba;}
inline PIByteArray compressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.compressedRLE(threshold); return ba;}
inline PIByteArray decompressedRLE(uchar threshold = 192) {PIByteArray ba(*this); ba.decompressedRLE(threshold); return ba;}
inline void operator =(const PIVector<uchar> & d) {resize(d.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = d[i];}
private:
union base64HelpStruct {
struct {
uchar ascii0: 6;
uchar ascii1: 6;
uchar ascii2: 6;
uchar ascii3: 6;
};
struct {
uchar byte0;
uchar byte1;
uchar byte2;
};
};
static PIHuffman huffman;
};
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba) {for (uint i = 0; i < ba.size(); ++i) s << ba[i]; return s;}
#endif // PIBYTEARRAY_H

View File

@@ -8,6 +8,8 @@ PIConfig::PIConfig(const PIString & path, Flags<Mode> mode): PIFile(path, mode)
}
PIStringList PIConfig::getValue(const PIString & vname, const PIStringList & def, bool * exist) const {
return getValue(vname, def.join("%|%"), exist).split("%|%");}
bool PIConfig::getValue(const PIString & vname, const bool def, bool * exist) const {
return atob(getValue(vname, btos(def), exist));}
char PIConfig::getValue(const PIString & vname, const char def, bool * exist) const {
@@ -32,6 +34,8 @@ double PIConfig::getValue(const PIString & vname, const double def, bool * exist
return getValue(vname, dtos(def), exist).toDouble();}
void PIConfig::setValue(const PIString & name, const PIStringList & value, bool write) {
setValue(name, value.join("%|%"), "l", write);}
void PIConfig::setValue(const PIString & name, const char * value, bool write) {
setValue(name, PIString(value), "s", write);}
void PIConfig::setValue(const PIString & name, const bool value, bool write) {

View File

@@ -10,7 +10,8 @@ public:
~PIConfig() {;}
PIString getValue(const PIString & vname, const PIString & def = "", bool * exist = 0) const;
PIString getValue(const PIString & vname, const char * def = "", bool * exist = 0) const;
PIString getValue(const PIString & vname, const char * def = "", bool * exist = 0) const {return getValue(vname, PIString(def), exist);}
PIStringList getValue(const PIString & vname, const PIStringList & def = PIStringList(), bool * exist = 0) const;
bool getValue(const PIString & vname, const bool def = false, bool * exist = 0) const;
char getValue(const PIString & vname, const char def = 0, bool * exist = 0) const;
short getValue(const PIString & vname, const short def = 0, bool * exist = 0) const;
@@ -24,6 +25,7 @@ public:
double getValue(const PIString & vname, const double def = 0., bool * exist = 0) const;
void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
void setValue(const PIString & name, const PIStringList & value, bool write = true);
void setValue(const PIString & name, const char * value, bool write = true);
void setValue(const PIString & name, const bool value, bool write = true);
void setValue(const PIString & name, const char value, bool write = true);

76
pidir.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include "pidir.h"
PIDir::PIDir(const PIString & dir) {
path_ = dir.stdString();
dir_ = 0;
open();
}
bool PIDir::operator==(const PIDir & d) const {
return true;
}
bool PIDir::open() {
if (dir_ != 0)
if (!close())
return false;
dir_ = opendir(path_.c_str());
return (dir_ != 0);
}
bool PIDir::close() {
if (dir_ == 0) return true;
if (closedir(dir_) == 0) {
dir_ = 0;
return true;
}
return false;
}
PIString PIDir::absolutePath() {
//di;
return PIString();
}
PIDir PIDir::current() {
char rc[1024];
if (getcwd(rc, 1024) == 0) return PIString();
return PIDir(rc);
}
PIDir PIDir::home() {
return PIDir(getenv("HOME"));
}
PIDir PIDir::temporary() {
char * rc;
rc = tmpnam(0);
PIString s(rc);
return PIDir(s.left(s.findLast(PIDir::separator)));
}
bool PIDir::mkDir(const PIString & path) {
string s = path.stdString();
int ret = mkdir(s.c_str(), 16877);
if (ret == 0) return true;
printf("[PIDir] mkDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
return false;
}
bool PIDir::rmDir(const PIString & path) {
string s = path.stdString();
int ret = rmdir(s.c_str());
if (ret == 0) return true;
printf("[PIDir] rmDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
return false;
}

42
pidir.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef PIDIR_H
#define PIDIR_H
#include "pifile.h"
#include <sys/dir.h>
class PIDir
{
public:
PIDir() {dir_ = 0;}
PIDir(const PIString & dir);
~PIDir() {close();}
inline const bool isExists() {return (dir_ != 0);}
inline PIString path() {return PIString(path_);}
PIString absolutePath();
bool operator ==(const PIDir & d) const;
#ifdef WINDOWS
static const char separator = '\\';
#else
static const char separator = '/';
#endif
static PIDir current();
static PIDir home();
static PIDir temporary();
static bool mkDir(const PIString & path);
static bool rmDir(const PIString & path);
//static bool rmDir(const PIString & path);
private:
bool open();
bool close();
string path_;
DIR * dir_;
};
#endif // PIDIR_H

View File

@@ -1,9 +1,9 @@
#ifndef PIFILE_H
#define PIFILE_H
#include <fstream>
#include "piincludes.h"
#include "pistring.h"
#include <fstream>
using std::fstream;
@@ -52,6 +52,7 @@ public:
PIFile & operator <<(const char & v) {stream.write(&v, 1); return *this;}
//PIFile & operator <<(const string & v) {stream.write(v.c_str(), v.size()); return *this;}
PIFile & operator <<(const PIString & v) {stream.write(v.data(), v.size()); return *this;}
PIFile & operator <<(const PIByteArray & v) {stream.write((char * )v.data(), v.size()); return *this;}
PIFile & operator <<(const short & v) {stream << v; return *this;}
PIFile & operator <<(const int & v) {stream << v; return *this;}
PIFile & operator <<(const long & v) {stream << v; return *this;}

View File

@@ -12,7 +12,9 @@ public:
PIPoint() {x = y = 0;};
PIPoint(Type x_, Type y_) {set(x_, y_);}
inline void set(Type x_, Type y_) {x = x_; y = y_;}
inline PIPoint<Type> & set(Type x_, Type y_) {x = x_; y = y_; return *this;}
inline PIPoint<Type> & move(Type x_, Type y_) {x += x_; y += y_; return *this;}
inline PIPoint<Type> & move(const PIPoint<Type> & p) {x += p.x; y += p.y; return *this;}
inline double angleRad() const {return atan2(y, x);}
inline int angleDeg() const {return round(atan2(y, x) * 180. / M_PI);}
@@ -27,6 +29,9 @@ public:
inline bool operator !=(const PIPoint<Type> & p) const {return (x != p.x || y != p.y);}
};
template<typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIPoint<Type> & v) {s << '{' << v.x << ", " << v.y << '}'; return s;}
template<typename Type>
class PIRect {
public:
@@ -38,8 +43,10 @@ public:
PIRect() {x0 = y0 = x1 = y1 = 0;};
PIRect(Type x, Type y, Type w, Type h) {set(x, y, w, h);}
PIRect(const PIPoint<Type> & tl, const PIPoint<Type> & br) {set(tl.x, tl.y, br.x, br.y);}
PIRect(const PIPoint<Type> & p0, const PIPoint<Type> & p1, const PIPoint<Type> & p2) {set(piMin<Type>(p0.x, p1.x, p2.x), piMin<Type>(p0.y, p1.y, p2.y),
piMax<Type>(p0.x, p1.x, p2.x), piMax<Type>(p0.y, p1.y, p2.y));}
inline void set(Type x, Type y, Type w, Type h) {x0 = x; y0 = y; x1 = x + w; y1 = y + h;}
inline PIRect<Type> & set(Type x, Type y, Type w, Type h) {x0 = x; y0 = y; x1 = x + w; y1 = y + h; return *this;}
inline bool pointIn(Type x, Type y) const {return (x <= x1 && x >= x0 && y <= y1 && y >= y0);}
inline bool pointIn(const PIPoint<Type> & p) const {return pointIn(p.x, p.y);}
inline bool isEmpty() const {return (x1 - x0 == 0 && y1 - y0 == 0);}
@@ -51,8 +58,12 @@ public:
inline PIRect<Type> & scale(const PIPoint<Type> & p) {setWidth(width() * p.x); setHeight(height() * p.y); return *this;}
inline PIRect<Type> scaled(Type x, Type y) {PIRect<Type> r(*this); r.scale(x, y); return r;}
inline PIRect<Type> scaled(const PIPoint<Type> & p) {PIRect<Type> r(*this); r.scale(p); return r;}
//inline void unite(const PIRect<Type> & r) {;}
//inline PIRect<Type> & united(const PIRect<Type> & r) {unite(r); return *this;}
inline PIRect<Type> & normalize() {if (x0 > x1) piSwap<Type>(x0, x1); if (y0 > y1) piSwap<Type>(y0, y1); return *this;}
inline PIRect<Type> normalized() {PIRect<Type> r(*this); r.normalize(); return r;}
inline PIRect<Type> & unite(const PIRect<Type> & r) {x0 = piMin<Type>(x0, r.x0); y0 = piMin<Type>(y0, r.y0); x1 = piMax<Type>(x1, r.x1); y1 = piMax<Type>(y1, r.y1); return *this;}
inline PIRect<Type> united(const PIRect<Type> & rect) {PIRect<Type> r(*this); r.unite(rect); return r;}
inline PIRect<Type> & intersect(const PIRect<Type> & r) {x0 = piMax<Type>(x0, r.x0); y0 = piMax<Type>(y0, r.y0); x1 = piMin<Type>(x1, r.x1); y1 = piMin<Type>(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;}
inline PIRect<Type> intersected(const PIRect<Type> & rect) {PIRect<Type> r(*this); r.intersect(rect); return r;}
inline Type top() const {return y0;}
inline Type left() const {return x0;}
inline Type right() const {return x1;}
@@ -77,13 +88,24 @@ public:
inline void operator -=(const PIPoint<Type> & p) {translate(-p);}
inline void operator *=(Type p) {x0 *= p; x1 *= p; y0 *= p; y1 *= p;}
inline void operator /=(Type p) {x0 /= p; x1 /= p; y0 /= p; y1 /= p;}
inline void operator |=(const PIRect<Type> & r) {unite(r);}
inline void operator &=(const PIRect<Type> & r) {intersect(r);}
inline PIRect<Type> operator +(const PIPoint<Type> & p) {return PIRect<Type>(*this).translated(p);}
inline PIRect<Type> operator -(const PIPoint<Type> & p) {return PIRect<Type>(*this).translated(-p);}
inline PIRect<Type> operator |(const PIRect<Type> & r) {return PIRect<Type>(*this).united(r);}
inline PIRect<Type> operator &(const PIRect<Type> & r) {return PIRect<Type>(*this).intersected(r);}
};
template<typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIRect<Type> & v) {s << '{' << v.x0 << ", " << v.y0 << "; " << v.x1 - v.x0 << ", " << v.y1 - v.y0 << '}'; return s;}
typedef PIPoint<int> PIPointi;
typedef PIPoint<uint> PIPointu;
typedef PIPoint<float> PIPointf;
typedef PIPoint<double> PIPointd;
typedef PIRect<int> PIRecti;
typedef PIRect<uint> PIRectu;
typedef PIRect<float> PIRectf;
typedef PIRect<double> PIRectd;

View File

@@ -10,8 +10,16 @@
#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#ifndef QNX
# include <cstdio>
# include <cstdlib>
#else
# include <stdio.h>
# include <stdlib.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <vector>
@@ -51,6 +59,7 @@ public:
inline Type & at(uint index) {return (*this)[index];}
inline const Type * data(uint index = 0) const {return &(*this)[index];}
inline Type * data(uint index = 0) {return &(*this)[index];}
inline void fill(const Type & t) {vector<Type, Allocator>::assign(vector<Type, Allocator>::size(), t);}
inline void pop_front() {vector<Type, Allocator>::erase(vector<Type, Allocator>::begin());}
inline void push_front(const Type & t) {vector<Type, Allocator>::insert(vector<Type, Allocator>::begin(), t);}
inline void remove(uint num) {vector<Type, Allocator>::erase(vector<Type, Allocator>::begin() + num);}
@@ -58,6 +67,17 @@ public:
inline void insert(uint pos, const Type & t) {vector<Type, Allocator>::insert(vector<Type, Allocator>::begin() + pos, t);}
};
template<typename Type, typename Allocator = std::allocator<Type> >
class PIList: public list<Type, Allocator> {
public:
inline const Type * data(uint index = 0) const {return &(*this)[index];}
inline Type * data(uint index = 0) {return &(*this)[index];}
inline void fill(const Type & t) {list<Type, Allocator>::assign(list<Type, Allocator>::size(), t);}
inline void remove(uint num) {list<Type, Allocator>::erase(list<Type, Allocator>::begin() + num);}
inline void remove(uint num, uint count) {list<Type, Allocator>::erase(list<Type, Allocator>::begin() + num, list<Type, Allocator>::begin() + num + count);}
inline void insert(uint pos, const Type & t) {list<Type, Allocator>::insert(list<Type, Allocator>::begin() + pos, t);}
};
template<typename Enum>
class Flags {
private:
@@ -88,6 +108,11 @@ public:
inline int random() {return rand();}
#endif
template<typename Type> inline void piSwap(Type & f, Type & s) {Type t = f; f = s; s = t;}
template<typename Type> inline Type piMin(const Type & f, const Type & s) {return (f > s) ? s : f;}
template<typename Type> inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;}
template<typename Type> inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);}
template<typename Type> inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);}
inline bool atob(const string & str) { return str == "1" ? true : false;};
inline string btos(const bool num) { return num ? "0" : "1";};
inline string itos(const int num) {

382
pimath.cpp Normal file
View File

@@ -0,0 +1,382 @@
#include "pimath.h"
/*
* Fast Fourier Transformation
* ====================================================
* Coded by Miroslav Voinarovsky, 2002
* This source is freeware.
*/
// This array contains values from 0 to 255 with reverse bit order
static uchar reverse256[]= {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF,
};
//This is array exp(-2*pi*j/2^n) for n= 1,...,32
//exp(-2*pi*j/2^n) = complexd( cos(2*pi/2^n), -sin(2*pi/2^n) )
static complexd W2n[32] = {
complexd(-1.00000000000000000000000000000000, 0.00000000000000000000000000000000), // W2 calculator (copy/paste) : po, ps
complexd( 0.00000000000000000000000000000000, -1.00000000000000000000000000000000), // W4: p/2=o, p/2=s
complexd( 0.70710678118654752440084436210485, -0.70710678118654752440084436210485), // W8: p/4=o, p/4=s
complexd( 0.92387953251128675612818318939679, -0.38268343236508977172845998403040), // p/8=o, p/8=s
complexd( 0.98078528040323044912618223613424, -0.19509032201612826784828486847702), // p/16=
complexd( 0.99518472667219688624483695310948, -9.80171403295606019941955638886e-2), // p/32=
complexd( 0.99879545620517239271477160475910, -4.90676743274180142549549769426e-2), // p/64=
complexd( 0.99969881869620422011576564966617, -2.45412285229122880317345294592e-2), // p/128=
complexd( 0.99992470183914454092164649119638, -1.22715382857199260794082619510e-2), // p/256=
complexd( 0.99998117528260114265699043772857, -6.13588464915447535964023459037e-3), // p/(2y9)=
complexd( 0.99999529380957617151158012570012, -3.06795676296597627014536549091e-3), // p/(2y10)=
complexd( 0.99999882345170190992902571017153, -1.53398018628476561230369715026e-3), // p/(2y11)=
complexd( 0.99999970586288221916022821773877, -7.66990318742704526938568357948e-4), // p/(2y12)=
complexd( 0.99999992646571785114473148070739, -3.83495187571395589072461681181e-4), // p/(2y13)=
complexd( 0.99999998161642929380834691540291, -1.91747597310703307439909561989e-4), // p/(2y14)=
complexd( 0.99999999540410731289097193313961, -9.58737990959773458705172109764e-5), // p/(2y15)=
complexd( 0.99999999885102682756267330779455, -4.79368996030668845490039904946e-5), // p/(2y16)=
complexd( 0.99999999971275670684941397221864, -2.39684498084182187291865771650e-5), // p/(2y17)=
complexd( 0.99999999992818917670977509588385, -1.19842249050697064215215615969e-5), // p/(2y18)=
complexd( 0.99999999998204729417728262414778, -5.99211245264242784287971180889e-6), // p/(2y19)=
complexd( 0.99999999999551182354431058417300, -2.99605622633466075045481280835e-6), // p/(2y20)=
complexd( 0.99999999999887795588607701655175, -1.49802811316901122885427884615e-6), // p/(2y21)=
complexd( 0.99999999999971948897151921479472, -7.49014056584715721130498566730e-7), // p/(2y22)=
complexd( 0.99999999999992987224287980123973, -3.74507028292384123903169179084e-7), // p/(2y23)=
complexd( 0.99999999999998246806071995015625, -1.87253514146195344868824576593e-7), // p/(2y24)=
complexd( 0.99999999999999561701517998752946, -9.36267570730980827990672866808e-8), // p/(2y25)=
complexd( 0.99999999999999890425379499688176, -4.68133785365490926951155181385e-8), // p/(2y26)=
complexd( 0.99999999999999972606344874922040, -2.34066892682745527595054934190e-8), // p/(2y27)=
complexd( 0.99999999999999993151586218730510, -1.17033446341372771812462135032e-8), // p/(2y28)=
complexd( 0.99999999999999998287896554682627, -5.85167231706863869080979010083e-9), // p/(2y29)=
complexd( 0.99999999999999999571974138670657, -2.92583615853431935792823046906e-9), // p/(2y30)=
complexd( 0.99999999999999999892993534667664, -1.46291807926715968052953216186e-9), // p/(2y31)=
};
/*
* x: x - array of items
* T: 1 << T = 2 power T - number of items in array
* complement: false - normal (direct) transformation, true - reverse transformation
*/
void fft(complexd * x, int T, bool complement)
{
uint I, J, Nmax, N, Nd2, k, m, mpNd2, Skew;
uchar *Ic = (uchar*) &I;
uchar *Jc = (uchar*) &J;
complexd S;
complexd * Wstore, * Warray;
complexd WN, W, Temp, *pWN;
Nmax = 1 << T;
//first interchanging
for(I = 1; I < Nmax - 1; I++)
{
Jc[0] = reverse256[Ic[3]];
Jc[1] = reverse256[Ic[2]];
Jc[2] = reverse256[Ic[1]];
Jc[3] = reverse256[Ic[0]];
J >>= (32 - T);
if (I < J)
{
S = x[I];
x[I] = x[J];
x[J] = S;
}
}
//rotation multiplier array allocation
Wstore = new complexd[Nmax / 2];
Wstore[0] = complexd(1., 0.);
//main loop
for(N = 2, Nd2 = 1, pWN = W2n, Skew = Nmax >> 1; N <= Nmax; Nd2 = N, N += N, pWN++, Skew >>= 1)
{
//WN = W(1, N) = exp(-2*pi*j/N)
WN= *pWN;
if (complement)
WN = complexd(WN.real(), -WN.imag());
for(Warray = Wstore, k = 0; k < Nd2; k++, Warray += Skew)
{
if (k & 1)
{
W *= WN;
*Warray = W;
}
else
W = *Warray;
for(m = k; m < Nmax; m += N)
{
mpNd2 = m + Nd2;
Temp = W;
Temp *= x[mpNd2];
x[mpNd2] = x[m];
x[mpNd2] -= Temp;
x[m] += Temp;
}
}
}
delete[] Wstore;
if (complement)
{
for( I = 0; I < Nmax; I++ )
x[I] /= Nmax;
}
}
const char Solver::methods_desc[] = "Methods:\
\n -1 - Global settings\
\n 01 - Eyler 1\
\n 02 - Eyler 2\
\n 14 - Runge-Kutta 4\
\n 23 - Adams-Bashfort-Moulton 3\
\n 24 - Adams-Bashfort-Moulton 4\
\n 32 - Polynomial Approximation 2\
\n 33 - Polynomial Approximation 3\
\n 34 - Polynomial Approximation 4\
\n 35 - Polynomial Approximation 5";
Solver::Method Solver::method_global = Solver::AdamsBashfortMoulton_4;
void Solver::solve(double u, double h) {
switch (method) {
case Global:
switch (method_global) {
case Eyler1: solveEyler1(u, h); break;
case Eyler2: solveEyler2(u, h); break;
case RungeKutta_4: solveRK4(u, h); break;
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
case AdamsBashfortMoulton_3: solveABM3(u, h); break;
case AdamsBashfortMoulton_4: default: solveABM4(u, h); break;
case PolynomialApproximation_2: solvePA2(u, h); break;
case PolynomialApproximation_3: solvePA3(u, h); break;
case PolynomialApproximation_4: solvePA4(u, h); break;
case PolynomialApproximation_5: solvePA5(u, h); break;
}
break;
case Eyler1: solveEyler1(u, h); break;
case Eyler2: solveEyler2(u, h); break;
case RungeKutta_4: solveRK4(u, h); break;
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
case AdamsBashfortMoulton_3: solveABM3(u, h); break;
case AdamsBashfortMoulton_4: default: solveABM4(u, h); break;
case PolynomialApproximation_2: solvePA2(u, h); break;
case PolynomialApproximation_3: solvePA3(u, h); break;
case PolynomialApproximation_4: solvePA4(u, h); break;
case PolynomialApproximation_5: solvePA5(u, h); break;
}
step++;
}
void Solver::fromTF(const TransferFunction & TF) {
if (TF.vector_An.size() >= TF.vector_Bm.size())
size = TF.vector_An.size()-1;
else {
cout << "Solver error: {A} should be greater than {B}" << endl;
return;
}
if (size == 0) return;
step = 0;
times.fill(0.);
A.resize(size, size);
d.resize(size + 1); d.fill(0.);
a1.resize(size + 1); a1.fill(0.);
b1.resize(size + 1); b1.fill(0.);
X.resize(size); X.fill(0.);
F.resize(5);
for (uint i = 0; i < 5; ++i)
F[i].resize(size), F[i].fill(0.);
k1.resize(size); k1.fill(0.);
k2.resize(size); k2.fill(0.);
k3.resize(size); k3.fill(0.);
k4.resize(size); k4.fill(0.);
xx.resize(size); xx.fill(0.);
XX.resize(size); XX.fill(0.);
for (uint i = 0; i < size + 1; ++i)
a1[size - i] = TF.vector_An[i];
for (uint i = 0; i < TF.vector_Bm.size(); ++i)
b1[size - i] = TF.vector_Bm[i];
double a0 = a1[0];
a1 /= a0;
b1 /= a0;
d[0] = b1[0]; // Рассчитываем вектор d
for (uint i = 1; i < size + 1; ++i) {
sum = 0.;
for (uint m = 0; m < i; ++m)
sum += a1[i - m] * d[m];
d[i] = b1[i] - sum;
}
for (uint i = 0; i < size - 1; ++i) // Заполняем матрицу А
for (uint j = 0; j < size; ++j)
A[j][i] = (j == i + 1);
for (uint i = 0; i < size; ++i)
A[i][size - 1] = -a1[size - i];
for (uint i = 0; i < size; ++i)
d[i] = d[i + 1];
}
void Solver::solveEyler1(double u, double h) {
/*for (uint i = 0; i < size; ++i) {
* sum = 0.;
* for (uint j = 0; j < size; ++j)
* sum += A[j][i] * X[j];
* xx[i] = sum + d[i] * u;
}*/
F[0] = A * X + d * u;
X += F[0] * h;
moveF();
}
void Solver::solveEyler2(double u, double h) {
F[0] = A * X + d * u;
X += (F[0] + F[1]) * h / 2.;
moveF();
}
void Solver::solveRK4(double u, double h) {
k1 = A * X + d * u; xx = k1 * h / 2.; XX = X + xx;
k2 = A * (XX + k1 * h / 2.) + d * (u + xx[0]); xx = k2 * h / 2.; XX += xx;
k3 = A * (XX + k2 * h / 2.) + d * (u + xx[0]); xx = k3 * h; XX += xx;
k4 = A * (XX + k3 * h) + d * (u + xx[0]);
//cout << k1 << k2 << k3 << k4 << endl;
X += (k1 + k2 * 2. + k3 * 2. + k4) * h / 6.;
}
void Solver::solveABM2(double u, double h) {
F[0] = A * X + d * u;
XX = X + (F[0] * 3. - F[1]) * (h / 2.);
F[1] = A * XX + d * u;
X += (F[1] + F[0]) * (h / 2.);
moveF();
}
void Solver::solveABM3(double u, double h) {
F[0] = A * X + d * u;
XX = X + (F[0] * 23. - F[1] * 16. + F[2] * 5.) * (h / 12.);
F[2] = A * XX + d * u;
X += (F[2] * 5. + F[0] * 8. - F[1]) * (h / 12.);
moveF();
}
void Solver::solveABM4(double u, double h) {
F[0] = A * X + d * u;
XX = X + (F[0] * 55. - F[1] * 59. + F[2] * 37. - F[3] * 9.) * (h / 24.);
F[3] = A * XX + d * u;
X += (F[3] * 9. + F[0] * 19. - F[1] * 5. + F[2]) * (h / 24.);
moveF();
}
void Solver::solvePA(double u, double h, uint deg) {
F[0] = A * X + d * u;
M.resize(deg, deg);
Y.resize(deg);
pY.resize(deg);
for (uint k = 0; k < size; ++k) {
for (uint i = 0; i < deg; ++i) {
td = 1.;
ct = times[i];
for (uint j = 0; j < deg; ++j) {
M[j][i] = td;
td *= ct;
}
}
for (uint i = 0; i < deg; ++i)
Y[i] = F[i][k];
/// find polynom
//if (step == 1) cout << M << endl << Y << endl;
M.invert(&ok, &Y);
//if (step == 1) cout << Y << endl;
if (!ok) {
solveEyler2(u, h);
break;
}
/// calc last piece
x0 = 0.;
td = 1.;
t = times[0];
for (uint i = 0; i < deg; ++i) {
x0 += Y[i] * td / (i + 1.);
td *= t;
}
x0 *= t;
x1 = 0.;
td = 1.;
t = times[1];
for (uint i = 0; i < deg; ++i) {
x1 += Y[i] * td / (i + 1.);
td *= t;
}
x1 *= t;
lp = x0 - x1;
if (deg > 2) {
/// calc prev piece
x0 = 0.;
td = 1.;
dh = times[1] - times[2];
if (dh != 0. && step > 1) {
t = times[2];
for (uint i = 0; i < deg; ++i) {
x0 += Y[i] * td / (i + 1.);
td *= t;
}
x0 *= t;
ct = x1 - x0;
/// calc correction
ct -= pY[k];
}
/// calc final
X[k] += lp - ct;
pY[k] = lp;
} else {
X[k] += lp;
pY[k] = lp;
}
}
moveF();
}

630
pimath.h
View File

@@ -1,10 +1,14 @@
#ifndef PIMathATH_H
#define PIMathATH_H
#ifndef PIMATH_H
#define PIMATH_H
#include <cmath>
#include <complex>
#include <stdarg.h>
#include "piincludes.h"
#ifndef QNX
# include <cmath>
#else
# include <math.h>
#endif
using std::complex;
@@ -13,29 +17,35 @@ typedef complex<float> complexf;
typedef complex<double> complexd;
typedef complex<long double> complexld;
const double deg2rad = atan(1) / 45.;
const double rad2deg = 45. / atan(1);
const double deg2rad = atan(1.) / 45.;
const double rad2deg = 45. / atan(1.);
inline int pow2(int p) {return (int)1 << p;}
template<typename Type> inline int pimin(const Type & f, const Type & s) {return (f > s) ? s : f;}
template<typename Type> inline int pimax(const Type & f, const Type & s) {return (f < s) ? s : f;}
inline double sqr(const double & v) {return v * v;}
/// Vector
template<uint Cols, uint Rows, typename Type>
class PIMathMatrixT;
/// Vector templated
#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v)
template<uint Size, typename Type = double>
class PIMathVector {
typedef PIMathVector<Size, Type> _CVector;
class PIMathVectorT {
typedef PIMathVectorT<Size, Type> _CVector;
public:
PIMathVector() {resize(Size);}
PIMathVector(Type fval, ...) {resize(Size); c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl);}
PIMathVectorT() {resize(Size);}
PIMathVectorT(Type fval, ...) {resize(Size); c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl);}
PIMathVectorT(const PIVector<Type> & val) {resize(Size); PIMV_FOR(i, 0) c[i] = val[i];}
PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(Size); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];}
inline uint size() const {return Size;}
inline _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;}
inline _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;}
inline _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;}
inline Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * c[i]; return tv;}
inline _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;}
inline _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;}
inline Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;}
inline Type length() const {return sqrt(lengthSqr());}
inline Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;}
inline Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);}
@@ -43,10 +53,11 @@ public:
inline Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
inline Type angleDeg(const _CVector & v) const {return acos(angleCos(v)) * rad2deg;}
inline _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
inline void normalize() {Type tv = length(); if (tv == Type(1)) return; PIMV_FOR(i, 0) c[i] /= tv;}
inline _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
inline _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
inline bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;}
inline bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
inline Type & at(uint index) {return c[index];}
inline Type at(uint index) const {return c[index];}
inline Type & operator [](uint index) {return c[index];}
@@ -57,31 +68,46 @@ public:
inline void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];}
inline void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];}
inline void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;}
inline void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];}
inline void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;}
inline void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];}
inline _CVector operator -() {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;}
inline _CVector operator +(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;}
inline _CVector operator -(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;}
inline _CVector operator *(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;}
inline _CVector operator /(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;}
inline _CVector operator *(const _CVector & v) {if (Size < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;}
inline Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;}
inline operator PIMathMatrixT<1, Size, Type>() {return PIMathMatrixT<1, Size, Type>(c);}
inline Type distToLine(const _CVector & lp0, const _CVector & lp1) {
_CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this);
Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length();//, s = b.length() + c.length() - a.length();
return f;}
template<uint Size1, typename Type1> /// vector {Size, Type} to vector {Size1, Type1}
inline PIMathVectorT<Size1, Type1> turnTo() {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;}
private:
inline void resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value);}
PIVector<Type> c;
};
template<uint Size, typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathVector<Size, Type> & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;}
inline std::ostream & operator <<(std::ostream & s, const PIMathVectorT<Size, Type> & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;}
typedef PIMathVector<2u, int> PIMathVector2i;
typedef PIMathVector<3u, int> PIMathVector3i;
typedef PIMathVector<4u, int> PIMathVector4i;
typedef PIMathVector<2u, double> PIMathVector2d;
typedef PIMathVector<3u, double> PIMathVector3d;
typedef PIMathVector<4u, double> PIMathVector4d;
//template<uint Size0, typename Type0 = double, uint Size1 = Size0, typename Type1 = Type0> /// vector {Size0, Type0} to vector {Size1, Type1}
//inline operator PIMathVectorT<Size1, Type1>(const PIMathVectorT<Size0, Type0> & v) {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size0, Size1); for (uint i = 0; i < sz; ++i) tv[i] = v[i]; return tv;}
/// Matrix
typedef PIMathVectorT<2u, int> PIMathVectorT2i;
typedef PIMathVectorT<3u, int> PIMathVectorT3i;
typedef PIMathVectorT<4u, int> PIMathVectorT4i;
typedef PIMathVectorT<2u, double> PIMathVectorT2d;
typedef PIMathVectorT<3u, double> PIMathVectorT3d;
typedef PIMathVectorT<4u, double> PIMathVectorT4d;
/// Matrix templated
#define PIMM_FOR(c, r) for (uint c = 0; c < Cols; ++c) { for (uint r = 0; r < Rows; ++r) {
#define PIMM_FOR_WB(c, r) for (uint c = 0; c < Cols; ++c) for (uint r = 0; r < Rows; ++r) // without brakes
@@ -91,28 +117,33 @@ typedef PIMathVector<4u, double> PIMathVector4d;
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
template<uint Cols, uint Rows = Cols, typename Type = double>
class PIMathMatrix {
typedef PIMathMatrix<Cols, Rows, Type> _CMatrix;
typedef PIMathMatrix<Rows, Cols, Type> _CMatrixI;
typedef PIMathVector<Rows, Type> _CMCol;
typedef PIMathVector<Cols, Type> _CMRow;
class PIMathMatrixT {
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrix;
typedef PIMathMatrixT<Rows, Cols, Type> _CMatrixI;
typedef PIMathVectorT<Rows, Type> _CMCol;
typedef PIMathVectorT<Cols, Type> _CMRow;
public:
PIMathMatrix() {resize(Cols, Rows);}
PIMathMatrix(Type fval, ...) {resize(Cols, Rows); va_list vl; va_start(vl, fval); PIMM_FOR_I_WB(c, r) m[c][r] = (r + c == 0 ? fval : va_arg(vl, Type)); va_end(vl);}
PIMathMatrixT() {resize(Cols, Rows);}
PIMathMatrixT(Type fval, ...) {resize(Cols, Rows); va_list vl; va_start(vl, fval); PIMM_FOR_I_WB(c, r) m[c][r] = (r + c == 0 ? fval : va_arg(vl, Type)); va_end(vl);}
PIMathMatrixT(const PIVector<Type> & val) {resize(Cols, Rows); int i = 0; PIMM_FOR_I_WB(c, r) m[c][r] = val[i++];}
static _CMatrix identity() {_CMatrix tm = _CMatrix(); PIMM_FOR_WB(c, r) tm.m[c][r] = (c == r ? Type(1) : Type(0)); return tm;}
inline uint cols() const {return Cols;}
inline uint rows() const {return Rows;}
inline _CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[index][i]; return tv;}
inline _CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[i][index]; return tv;}
inline _CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[index][i] = v[i]; return *this;}
inline _CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[i][index] = v[i]; return *this;}
inline _CMatrix & swapRows(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[i][r0]; m[i][r0] = m[i][r1]; m[i][r1] = t;} return *this;}
inline _CMatrix & swapCols(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[c0][i]; m[c0][i] = m[c1][i]; m[c1][i] = t;} return *this;}
inline _CMatrix & fill(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] = v; return *this;}
//inline _CMatrix & set(Type fval, ...) {m[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) m[i] = va_arg(vl, Type); va_end(vl); return *this;}
//inline void normalize() {Type tv = length(); if (tv == Type(1)) return; PIMV_FOR(i, 0) m[i] /= tv;}
inline bool isSquare() const {return cols() == rows();}
inline bool isIdentity() const {PIMM_FOR_WB(c, r) if ((c == r) ? m[c][r] != Type(1) : m[c][r] != Type(0)) return false; return true;}
inline bool isNull() const {PIMM_FOR_WB(c, r) if (m[c][r] != Type(0)) return false; return true;}
inline Type & at(uint col, uint row) {return m[col][row];}
inline Type at(uint col, uint row) const {return m[col][row];}
inline PIVector<Type> & operator [](uint col) {return m[col];}
@@ -129,25 +160,534 @@ public:
inline _CMatrix operator -(const _CMatrix & sm) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] -= sm.m[c][r]; return tm;}
inline _CMatrix operator *(const Type & v) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] *= v; return tm;}
inline _CMatrix operator /(const Type & v) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] /= v; return tm;}
_CMatrix & toUpperTriangular(bool * ok = 0) {
if (Cols != Rows) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix smat(*this);
bool ndet;
uint crow;
Type mul;
for (uint i = 0; i < Cols; ++i) {
ndet = true;
for (uint j = 0; j < Rows; ++j) if (smat.m[i][j] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
for (uint j = 0; j < Cols; ++j) if (smat.m[j][i] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < Cols; ++i) {
crow = i;
while (smat.m[i][i] == Type(0))
smat.swapRows(i, ++crow);
for (uint j = i + 1; j < Rows; ++j) {
mul = smat.m[i][j] / smat.m[i][i];
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
}
if (i < Cols - 1) {
if (fabs(smat.m[i+1][i+1]) < Type(1E-100)) {
if (ok != 0) *ok = false;
return *this;
}
}
}
if (ok != 0) *ok = true;
m = smat.m;
return *this;
}
_CMatrix & invert(bool * ok = 0) {
if (Cols != Rows) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix mtmp = _CMatrix::identity(), smat(*this);
bool ndet;
uint crow;
Type mul, iddiv;
for (uint i = 0; i < Cols; ++i) {
ndet = true;
for (uint j = 0; j < Rows; ++j) if (smat.m[i][j] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
for (uint j = 0; j < Cols; ++j) if (smat.m[j][i] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < Cols; ++i) {
crow = i;
while (smat.m[i][i] == Type(0)) {
++crow;
smat.swapRows(i, crow);
mtmp.swapRows(i, crow);
}
for (uint j = i + 1; j < Rows; ++j) {
mul = smat.m[i][j] / smat.m[i][i];
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i];
}
//cout << i << endl << smat << endl;
if (i < Cols - 1) {
if (fabs(smat.m[i+1][i+1]) < Type(1E-100)) {
if (ok != 0) *ok = false;
return *this;
}
}
iddiv = smat.m[i][i];
for (uint j = i; j < Cols; ++j) smat.m[j][i] /= iddiv;
for (uint j = 0; j < Cols; ++j) mtmp.m[j][i] /= iddiv;
}
for (uint i = Cols - 1; i > 0; --i) {
for (uint j = 0; j < i; ++j) {
mul = smat.m[i][j];
smat.m[i][j] -= mul;
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mtmp.m[k][i] * mul;
}
}
if (ok != 0) *ok = true;
m = mtmp.m;
return *this;
}
inline _CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;}
inline _CMatrixI transposed() {_CMatrixI tm; PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;}
private:
inline void resize(uint cols, uint rows, const Type & new_value = Type()) {m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value);}
PIVector<PIVector<Type> > m;
};
template<uint Cols, uint Rows, typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrix<Cols, Rows, Type> & m) {s << '{'; PIMM_FOR_I(c, r) s << m[c][r]; if (c < Cols - 1 || r < Rows - 1) s << ", ";} if (r < Rows - 1) s << endl;} s << '}'; return s;}
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT<Cols, Rows, Type> & m) {s << '{'; PIMM_FOR_I(c, r) s << m[c][r]; if (c < Cols - 1 || r < Rows - 1) s << ", ";} if (r < Rows - 1) s << endl << ' ';} s << '}'; return s;}
typedef PIMathMatrix<2u, 2u, int> PIMathMatrix22i;
typedef PIMathMatrix<3u, 3u, int> PIMathMatrix33i;
typedef PIMathMatrix<4u, 4u, int> PIMathMatrix44i;
typedef PIMathMatrix<2u, 2u, double> PIMathMatrix22d;
typedef PIMathMatrix<3u, 3u, double> PIMathMatrix33d;
typedef PIMathMatrix<4u, 4u, double> PIMathMatrix44d;
/// Multiply matrices {CR x Rows0} on {Cols1 x CR}, result is {Cols1 x Rows0}
template<uint CR, uint Rows0, uint Cols1, typename Type>
inline PIMathMatrixT<Cols1, Rows0, Type> operator *(const PIMathMatrixT<CR, Rows0, Type> & fm,
const PIMathMatrixT<Cols1, CR, Type> & sm) {
PIMathMatrixT<Cols1, Rows0, Type> tm;
Type t;
for (uint j = 0; j < Rows0; ++j) {
for (uint i = 0; i < Cols1; ++i) {
t = Type(0);
for (uint k = 0; k < CR; ++k)
t += fm[k][j] * sm[i][k];
tm[i][j] = t;
}
}
return tm;
}
/// Multiply matrix {Cols x Rows} on vector {Cols}, result is vector {Rows}
template<uint Cols, uint Rows, typename Type>
inline PIMathVectorT<Rows, Type> operator *(const PIMathMatrixT<Cols, Rows, Type> & fm,
const PIMathVectorT<Cols, Type> & sv) {
PIMathVectorT<Rows, Type> tv;
Type t;
for (uint i = 0; i < Rows; ++i) {
t = Type(0);
for (uint j = 0; j < Cols; ++j)
t += fm[j][i] * sv[j];
tv[i] = t;
}
return tv;
}
typedef PIMathMatrixT<2u, 2u, int> PIMathMatrixT22i;
typedef PIMathMatrixT<3u, 3u, int> PIMathMatrixT33i;
typedef PIMathMatrixT<4u, 4u, int> PIMathMatrixT44i;
typedef PIMathMatrixT<2u, 2u, double> PIMathMatrixT22d;
typedef PIMathMatrixT<3u, 3u, double> PIMathMatrixT33d;
typedef PIMathMatrixT<4u, 4u, double> PIMathMatrixT44d;
template<typename Type>
class PIMathMatrix;
#undef PIMV_FOR
#undef PIMM_FOR
#undef PIMM_FOR_WB
#undef PIMM_FOR_I
#undef PIMM_FOR_I_WB
#undef PIMM_FOR_C
#undef PIMM_FOR_R
#endif // PIMathATH_H
/// Vector
#define PIMV_FOR(v, s) for (uint v = s; v < size_; ++v)
template<typename Type>
class PIMathVector {
typedef PIMathVector<Type> _CVector;
public:
PIMathVector(const uint size = 3) {resize(size);}
PIMathVector(const uint size, Type fval, ...) {resize(size); c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl);}
PIMathVector(const PIVector<Type> & val) {resize(val.size); PIMV_FOR(i, 0) c[i] = val[i];}
PIMathVector(const _CVector & st, const _CVector & fn) {resize(st.size()); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];}
inline uint size() const {return size_;}
inline _CVector & resize(uint size, const Type & new_value = Type()) {size_ = size; c.resize(size, new_value); return *this;}
inline _CVector resized(uint size, const Type & new_value = Type()) {_CVector tv = _CVector(*this); tv.resize(size, new_value); return tv;}
inline _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;}
inline _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;}
inline _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;}
inline _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;}
inline _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;}
inline _CVector & swap(uint fe, uint se) {piSwap<Type>(c[fe], c[se]); return *this;}
inline Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;}
inline Type length() const {return sqrt(lengthSqr());}
inline Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;}
inline Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);}
inline Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);}
inline Type angleRad(const _CVector & v) const {return acos(angleCos(v));}
inline Type angleDeg(const _CVector & v) const {return acos(angleCos(v)) * rad2deg;}
inline _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));}
inline _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;}
inline _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
inline bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;}
inline bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
inline Type & at(uint index) {return c[index];}
inline Type at(uint index) const {return c[index];}
inline Type & operator [](uint index) {return c[index];}
inline Type operator [](uint index) const {return c[index];}
inline void operator =(const _CVector & v) {c = v.c;}
inline bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;}
inline bool operator !=(const _CVector & v) const {return !(*this == c);}
inline void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];}
inline void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];}
inline void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;}
inline void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];}
inline void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;}
inline void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];}
inline _CVector operator -() {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;}
inline _CVector operator +(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;}
inline _CVector operator -(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;}
inline _CVector operator *(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;}
inline _CVector operator /(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;}
inline _CVector operator *(const _CVector & v) {if (size_ < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;}
inline Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;}
//inline operator PIMathMatrix<1, Size, Type>() {return PIMathMatrix<1, Size, Type>(c);}
inline Type distToLine(const _CVector & lp0, const _CVector & lp1) {
_CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this);
Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length();//, s = b.length() + c.length() - a.length();
return f;}
template<typename Type1>
inline PIMathVector turnTo(uint size) {PIMathVector<Type1> tv; uint sz = piMin<uint>(size_, size); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;}
private:
uint size_;
PIVector<Type> c;
};
template<typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathVector<Type> & v) {s << '{'; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << '}'; return s;}
typedef PIMathVector<int> PIMathVectori;
typedef PIMathVector<double> PIMathVectord;
/// Matrix
#define PIMM_FOR(c, r) for (uint c = 0; c < cols_; ++c) { for (uint r = 0; r < rows_; ++r) {
#define PIMM_FOR_WB(c, r) for (uint c = 0; c < cols_; ++c) for (uint r = 0; r < rows_; ++r) // without brakes
#define PIMM_FOR_I(c, r) for (uint r = 0; r < rows_; ++r) { for (uint c = 0; c < cols_; ++c) {
#define PIMM_FOR_I_WB(c, r) for (uint r = 0; r < rows_; ++r) for (uint c = 0; c < cols_; ++c) // without brakes
#define PIMM_FOR_C(v) for (uint v = 0; v < cols_; ++v)
#define PIMM_FOR_R(v) for (uint v = 0; v < rows_; ++v)
template<typename Type>
class PIMathMatrix {
typedef PIMathMatrix<Type> _CMatrix;
typedef PIMathVector<Type> _CMCol;
typedef PIMathVector<Type> _CMRow;
public:
PIMathMatrix(const uint cols = 3, const uint rows = 3) {resize(cols, rows);}
PIMathMatrix(const uint cols, const uint rows, Type fval, ...) {resize(cols, rows); va_list vl; va_start(vl, fval); PIMM_FOR_I_WB(c, r) m[c][r] = (r + c == 0 ? fval : va_arg(vl, Type)); va_end(vl);}
PIMathMatrix(const uint cols, const uint rows, const PIVector<Type> & val) {resize(cols, rows); int i = 0; PIMM_FOR_I_WB(c, r) m[c][r] = val[i++];}
static _CMatrix identity(const uint cols_, const uint rows_) {_CMatrix tm(cols_, rows_); PIMM_FOR_WB(c, r) tm.m[c][r] = (c == r ? Type(1) : Type(0)); return tm;}
inline uint cols() const {return cols_;}
inline uint rows() const {return rows_;}
inline _CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[index][i]; return tv;}
inline _CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[i][index]; return tv;}
inline _CMatrix & resize(const uint cols, const uint rows, const Type & new_value = Type()) {cols_ = cols; rows_ = rows; m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value); return *this;}
inline _CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[index][i] = v[i]; return *this;}
inline _CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[i][index] = v[i]; return *this;}
inline _CMatrix & swaprows_(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[i][r0]; m[i][r0] = m[i][r1]; m[i][r1] = t;} return *this;}
inline _CMatrix & swapcols_(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[c0][i]; m[c0][i] = m[c1][i]; m[c1][i] = t;} return *this;}
inline _CMatrix & fill(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] = v; return *this;}
//inline _CMatrix & set(Type fval, ...) {m[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) m[i] = va_arg(vl, Type); va_end(vl); return *this;}
//inline void normalize() {Type tv = length(); if (tv == Type(1)) return; PIMV_FOR(i, 0) m[i] /= tv;}
inline bool isSquare() const {return cols() == rows();}
inline bool isIdentity() const {PIMM_FOR_WB(c, r) if ((c == r) ? m[c][r] != Type(1) : m[c][r] != Type(0)) return false; return true;}
inline bool isNull() const {PIMM_FOR_WB(c, r) if (m[c][r] != Type(0)) return false; return true;}
inline Type & at(uint col, uint row) {return m[col][row];}
inline Type at(uint col, uint row) const {return m[col][row];}
inline PIVector<Type> & operator [](uint col) {return m[col];}
inline PIVector<Type> operator [](uint col) const {return m[col];}
inline void operator =(const _CMatrix & sm) {m = sm.m;}
inline bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;}
inline bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
inline void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];}
inline void operator -=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] -= sm.m[c][r];}
inline void operator *=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] *= v;}
inline void operator /=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] /= v;}
inline _CMatrix operator -() {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] = -m[c][r]; return tm;}
inline _CMatrix operator +(const _CMatrix & sm) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] += sm.m[c][r]; return tm;}
inline _CMatrix operator -(const _CMatrix & sm) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] -= sm.m[c][r]; return tm;}
inline _CMatrix operator *(const Type & v) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] *= v; return tm;}
inline _CMatrix operator /(const Type & v) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] /= v; return tm;}
_CMatrix & toUpperTriangular(bool * ok = 0) {
if (cols_ != rows_) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix smat(*this);
bool ndet;
uint crow;
Type mul;
for (uint i = 0; i < cols_; ++i) {
ndet = true;
for (uint j = 0; j < rows_; ++j) if (smat.m[i][j] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
for (uint j = 0; j < cols_; ++j) if (smat.m[j][i] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < cols_; ++i) {
crow = i;
while (smat.m[i][i] == Type(0))
smat.swaprows_(i, ++crow);
for (uint j = i + 1; j < rows_; ++j) {
mul = smat.m[i][j] / smat.m[i][i];
for (uint k = i; k < cols_; ++k) smat.m[k][j] -= mul * smat.m[k][i];
}
if (i < cols_ - 1) {
if (fabs(smat.m[i+1][i+1]) < Type(1E-100)) {
if (ok != 0) *ok = false;
return *this;
}
}
}
if (ok != 0) *ok = true;
m = smat.m;
return *this;
}
_CMatrix & invert(bool * ok = 0, _CMCol * sv = 0) {
if (cols_ != rows_) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix mtmp = _CMatrix::identity(cols_, rows_), smat(*this);
bool ndet;
uint crow;
Type mul, iddiv;
for (uint i = 0; i < cols_; ++i) {
ndet = true;
for (uint j = 0; j < rows_; ++j) if (smat.m[i][j] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
for (uint j = 0; j < cols_; ++j) if (smat.m[j][i] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < cols_; ++i) {
crow = i;
while (smat.m[i][i] == Type(0)) {
++crow;
smat.swaprows_(i, crow);
mtmp.swaprows_(i, crow);
if (sv != 0) sv->swap(i, crow);
}
for (uint j = i + 1; j < rows_; ++j) {
mul = smat.m[i][j] / smat.m[i][i];
for (uint k = i; k < cols_; ++k) smat.m[k][j] -= mul * smat.m[k][i];
for (uint k = 0; k < cols_; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i];
if (sv != 0) (*sv)[j] -= mul * (*sv)[i];
}
//cout << i << endl << smat << endl;
if (i < cols_ - 1) {
if (fabs(smat.m[i+1][i+1]) < Type(1E-100)) {
if (ok != 0) *ok = false;
return *this;
}
}
iddiv = smat.m[i][i];
for (uint j = i; j < cols_; ++j) smat.m[j][i] /= iddiv;
for (uint j = 0; j < cols_; ++j) mtmp.m[j][i] /= iddiv;
if (sv != 0) (*sv)[i] /= iddiv;
}
for (uint i = cols_ - 1; i > 0; --i) {
for (uint j = 0; j < i; ++j) {
mul = smat.m[i][j];
smat.m[i][j] -= mul;
for (uint k = 0; k < cols_; ++k) mtmp.m[k][j] -= mtmp.m[k][i] * mul;
if (sv != 0) (*sv)[j] -= mul * (*sv)[i];
}
}
if (ok != 0) *ok = true;
m = mtmp.m;
return *this;
}
inline _CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;}
inline _CMatrix transposed() {_CMatrix tm(rows_, cols_); PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;}
private:
uint cols_, rows_;
PIVector<PIVector<Type> > m;
};
template<typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrix<Type> & m) {s << '{'; for (uint r = 0; r < m.rows(); ++r) { for (uint c = 0; c < m.cols(); ++c) { s << m[c][r]; if (c < m.cols() - 1 || r < m.rows() - 1) s << ", ";} if (r < m.rows() - 1) s << endl << ' ';} s << '}'; return s;}
/// Multiply matrices {CR x Rows0} on {Cols1 x CR}, result is {Cols1 x Rows0}
template<typename Type>
inline PIMathMatrix<Type> operator *(const PIMathMatrix<Type> & fm,
const PIMathMatrix<Type> & sm) {
uint cr = fm.cols(), rows0 = fm.rows(), cols1 = sm.cols();
PIMathMatrix<Type> tm(cols1, rows0);
if (fm.cols() != sm.rows()) return tm;
Type t;
for (uint j = 0; j < rows0; ++j) {
for (uint i = 0; i < cols1; ++i) {
t = Type(0);
for (uint k = 0; k < cr; ++k)
t += fm[k][j] * sm[i][k];
tm[i][j] = t;
}
}
return tm;
}
/// Multiply matrix {Cols x Rows} on vector {Cols}, result is vector {Rows}
template<typename Type>
inline PIMathVector<Type> operator *(const PIMathMatrix<Type> & fm,
const PIMathVector<Type> & sv) {
uint c = fm.cols(), r = fm.rows();
PIMathVector<Type> tv(r);
if (c != sv.size()) return tv;
Type t;
for (uint i = 0; i < r; ++i) {
t = Type(0);
for (uint j = 0; j < c; ++j)
t += fm[j][i] * sv[j];
tv[i] = t;
}
return tv;
}
typedef PIMathMatrix<int> PIMathMatrixi;
typedef PIMathMatrix<double> PIMathMatrixd;
#undef PIMV_FOR
#undef PIMM_FOR
#undef PIMM_FOR_WB
#undef PIMM_FOR_I
#undef PIMM_FOR_I_WB
#undef PIMM_FOR_C
#undef PIMM_FOR_R
/*
Fast Fourier Transformation: direct (complement= false)
and complement (complement = true). 'x' is data source.
'x' contains 2^T items.
*/
void fft(complexd * x, int T, bool complement);
/// Differential evaluations
struct TransferFunction { // Для задания передаточной функции
PIVector<double> vector_Bm, vector_An;
};
// Класс, служащий для перевода передаточной функции в систему ОДУ первого порядка
// реализованы след. методы решения дифф. ур-ний:
// Эйлера
// Рунге-Кутта 4-го порядка
// Адамса-Бэшфортса-Моултона 2, 3, 4 порядков
class Solver
{
public:
enum Method {Global = -1,
Eyler1 = 01,
Eyler2 = 02,
EylerKoshi = 03,
RungeKutta_4 = 14,
AdamsBashfortMoulton_2 = 22,
AdamsBashfortMoulton_3 = 23,
AdamsBashfortMoulton_4 = 24,
PolynomialApproximation_2 = 32,
PolynomialApproximation_3 = 33,
PolynomialApproximation_4 = 34,
PolynomialApproximation_5 = 35
};
Solver() {times.resize(4); step = 0;}
void solve(double u, double h);
void fromTF(const TransferFunction & TF);
void setMethod(Method m) {method = m;}
void setTime(double time) {times.pop_back(); times.push_front(time);}
void solveEyler1(double u, double h);
void solveEyler2(double u, double h);
void solveRK4(double u, double h);
void solveABM2(double u, double h);
void solveABM3(double u, double h);
void solveABM4(double u, double h);
void solvePA(double u, double h, uint deg);
inline void solvePA2(double u, double h) {if (step > 0) solvePA(u, h, 2); else solvePA(u, h, 1);}
inline void solvePA3(double u, double h) {if (step > 1) solvePA(u, h, 3); else solvePA2(u, h);}
inline void solvePA4(double u, double h) {if (step > 2) solvePA(u, h, 4); else solvePA3(u, h);}
inline void solvePA5(double u, double h) {if (step > 3) solvePA(u, h, 5); else solvePA4(u, h);}
PIMathVectord X;
static Method method_global;
static const char methods_desc[];
private:
inline void moveF() {for (uint i = F.size() - 1; i > 0; --i) F[i] = F[i - 1];}
PIMathMatrixd A, M;
PIMathVectord d, a1, b1;
PIMathVectord k1, k2, k3, k4, xx;
PIMathVectord XX, Y, pY;
PIVector<PIMathVectord> F;
PIVector<double> times;
uint size, step;
Method method;
double sum, td, ct, lp, dh, t, x1, x0;
bool ok;
};
#endif // PIMATH_H

2
pip.h
View File

@@ -1,6 +1,6 @@
#include "pitimer.h"
#include "pivariable.h"
#include "piconsole.h"
#include "pigeometry.h"
#include "pimath.h"
#include "pidir.h"
#include "piprotocol.h"

View File

@@ -22,6 +22,13 @@ PIString & PIString::operator +=(const PIString & str) {
}
PIString & PIString::operator +=(const PIByteArray & ba) {
uint l = ba.size();
for (uint i = 0; i < l; ++i) push_back(ba[i]);
return *this;
}
bool PIString::operator ==(const PIString & str) const {
uint l = str.size();
if (size() != l) return false;
@@ -106,6 +113,20 @@ PIString & PIString::trim() {
}
PIStringList PIString::split(const PIString & delim) {
PIString ts(*this);
PIStringList sl;
int ci = ts.find(delim);
while (ci >= 0) {
sl << ts.left(ci);
ts.cutLeft(ci + delim.length());
ci = ts.find(delim);
}
if (ts.length() > 0) sl << ts;
return sl;
}
int PIString::find(const char str, const int start) {
for (int i = start; i < length(); ++i)
if (at(i) == str)

View File

@@ -1,7 +1,9 @@
#ifndef PISTRING_H
#define PISTRING_H
#include "piincludes.h"
#include "pibytearray.h"
class PIStringList;
class PIString: public PIVector<char>
{
@@ -11,6 +13,7 @@ public:
PIString(const char * str) {*this += str;}
PIString(const string & str) {*this += str;}
PIString(const PIString & str) {*this += str;}
PIString(const PIByteArray & ba) {*this += ba;}
PIString(const int len, const char c = ' ') {for (int i = 0; i < len; ++i) push_back(c);}
operator const char*() {return data();}
@@ -19,21 +22,25 @@ public:
inline const char operator [](const int pos) const {return at(pos);}
PIString & operator +=(const PIString & str);
PIString & operator +=(const PIByteArray & ba);
inline PIString & operator +=(const char & c) {push_back(c); return *this;}
PIString & operator +=(const char * str);
PIString & operator +=(const string & str);
bool operator ==(const PIString & str) const;
inline bool operator ==(const PIByteArray & ba) const {return *this == PIString(ba);}
inline bool operator ==(const char & c) const {return *this == PIString(c);}
inline bool operator ==(const char * str) const {return *this == PIString(str);}
inline bool operator ==(const string & str) const {return *this == PIString(str);}
bool operator !=(const PIString & str) const;
inline bool operator !=(const PIByteArray & ba) const {return *this != PIString(ba);}
inline bool operator !=(const char & c) const {return *this != PIString(c);}
inline bool operator !=(const char * str) const {return *this != PIString(str);}
inline bool operator !=(const string & str) const {return *this != PIString(str);}
PIString & operator <<(const PIString & str) {*this += str; return *this;}
inline PIString & operator <<(const PIString & str) {*this += str; return *this;}
inline PIString & operator <<(const PIByteArray & ba) {*this += ba; return *this;}
inline PIString & operator <<(const char & c) {*this += c; return *this;}
inline PIString & operator <<(const char * str) {*this += str; return *this;}
inline PIString & operator <<(const string & str) {*this += str; return *this;}
@@ -53,6 +60,7 @@ public:
PIString & trim();
const char * data() const {return stdString().c_str();}
string stdString() const {return (size() == 0) ? string() : string(&at(0), size());}
PIStringList split(const PIString & delim);
PIString toUpperCase() const;
PIString toLowerCase() const;
@@ -74,6 +82,7 @@ public:
long toLong() const {return atol(data());}
float toFloat() const {return (float)atof(data());}
double toDouble() const {return atof(data());}
inline PIByteArray toBase64() {return PIByteArray(data(), size()).toBase64();}
inline PIString & setNumber(const int value) {clear(); *this += itos(value); return *this;}
inline PIString & setNumber(const short value) {clear(); *this += itos(value); return *this;}
@@ -82,6 +91,7 @@ public:
inline PIString & setNumber(const double value) {clear(); *this += dtos(value); return *this;}
inline static PIString fromNumber(const int value) {return PIString(itos(value));}
inline static PIString fromNumber(const uint value) {return PIString(itos(value));}
inline static PIString fromNumber(const short value) {return PIString(itos(value));}
inline static PIString fromNumber(const long value) {return PIString(ltos(value));}
inline static PIString fromNumber(const float value) {return PIString(ftos(value));}
@@ -91,10 +101,12 @@ public:
inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;}
inline PIString operator +(const PIString & f, const PIByteArray & ba) {PIString s(f); s += ba; return s;}
inline PIString operator +(const PIString & f, const char & c) {PIString s(f); s.push_back(c); return s;}
inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;}
inline PIString operator +(const PIString & f, const string & str) {PIString s(f); s += str; return s;}
inline PIString operator +(const PIByteArray & ba, const PIString & f) {return PIString(ba) + f;}
inline PIString operator +(const char & c, const PIString & f) {return PIString(c) + f;}
inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;}
inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;}
@@ -102,4 +114,25 @@ inline PIString operator +(const string & str, const PIString & f) {return PIStr
char chrUpr(char c);
char chrLwr(char c);
class PIStringList: public PIVector<PIString>
{
public:
PIStringList() {;}
PIStringList(const PIString & str) {push_back(str);}
inline PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;}
inline PIStringList & operator <<(const PIString & str) {push_back(str); return *this;}
inline PIStringList & operator <<(const PIByteArray & ba) {push_back(ba); return *this;}
inline PIStringList & operator <<(const char & c) {push_back(PIString(c)); return *this;}
inline PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;}
inline PIStringList & operator <<(const string & str) {push_back(str); return *this;}
inline PIStringList & operator <<(const int & num) {push_back(PIString::fromNumber(num)); return *this;}
inline PIStringList & operator <<(const short & num) {push_back(PIString::fromNumber(num)); return *this;}
inline PIStringList & operator <<(const long & num) {push_back(PIString::fromNumber(num)); return *this;}
inline PIStringList & operator <<(const float & num) {push_back(PIString::fromNumber(num)); return *this;}
inline PIStringList & operator <<(const double & num) {push_back(PIString::fromNumber(num)); return *this;}
};
#endif // PISTRING_H