Anonymní profil Petr – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Anonymní profil Petr – Programujte.comAnonymní profil Petr – Programujte.com

 

Příspěvky odeslané z IP adresy 89.177.163.–

C / C++ › Telefoní seznam
18. 12. 2019   #385094

#6 hlucheucho
Zadání nevypadá, že by mělo jít o čísla v mezinárodním formátu. I tak na ně stačí 40 bitů tj. 32+8 ;-).

C / C++ › Telefoní seznam
18. 12. 2019   #385091

#2 hlucheucho
Standardní tel. číslo 999 999 999 se v pohodě do 32 bitů vejde. Viz log10 999 999 999 / log10 2 = 29,90 bitů.

C / C++ › GPU Computing on OpenCL
9. 12. 2019   #384971

Naklonoval jsem do Visual Studia 2017 projekt z GitHubu, ale nikde nevidím *.sln Při pokusu vše znovu sestavit dostanu chybu:

Manually-specified variables were not used by the project: CMAKE_CXX_COMPILER

Připojen obrázek.

C / C++ › GPU Computing on OpenCL
9. 12. 2019   #384965

#2 gna
To je složitý jak ... Vůbec nechápu, jak program zkompilovat  .

C / C++ › GPU Computing on OpenCL
8. 12. 2019   #384963

Jak vyzkoušet příklady na stránce GPU Computing on OpenCL ve Visual Studiu 2017 v C++ ? Podporu pro CUDA mám naistalovanou.

Předpokládám, že ukázka potřebuje na začátku definovat nějakou hlavičku:
 

//CPU (Intel i7-5960X)
int sum()
{
    int sum = 0;
 
    const int* set = _gen_randoms;
 
    int i = 0;
    for(i = 0; i < N; ++i) {
        sum += set[i];
    }
 
    return sum;
}
C / C++ › Vyhodnocení EKG
11. 11. 2019   #384601

Představu mám zcela jasnou. Program by měl pomocí umělé inteligence analyzovat graf EKG. Výstupem by mělo být buď že je graf v pořádku, nebo podezření na nějaké poškození srdce.

Viz např. projekt Welcome to BrainFlow’s documentation! na Githubu. Projekt počítá s konkrétními HW snímači signálů, které pořizují záznam dat. Nemělo by být ale tak složité, převést data získaná jinak na vhodný formát a nechat je pak zpracovat programem.

C / C++ › Vyhodnocení EKG
8. 11. 2019   #384565
C / C++ › Vyhodnocení EKG
8. 11. 2019   #384563
C / C++ › Vyhodnocení EKG
8. 11. 2019   #384558

#7 peter
ale tebe mozna zajima AI s analyzou

Ano, o to mi přesně jde.

C / C++ › Vyhodnocení EKG
7. 11. 2019   #384548
C / C++ › Vyhodnocení EKG
6. 11. 2019   #384539

#2 Kit
To si nemyslím. Určitě to jde přes DNN a CUDA.

C / C++ › Vyhodnocení EKG
2. 11. 2019   #384501

Nemáte tip na program, který pomocí AI (DNN, CUDA) umí vyhodnotit záznam EKG případně zda se tím někdo u nás nezabývá ? Něco jako Yolo pro zpracování obrazu v reálném čase i když tady stačí zpracovat jednu stránku s grafy EKG v pdf.

C / C++ › low vs high level programování
24. 9. 2019   #384311

Já bych se toho nebál. Znalost mikrokontrolerů má určitě využití v průmyslu i jinde. I když nejsem nejmladší, přes měsícem jsem si pořídil Arduino Pro Mini ATMega328P 3.3V a modem Wisol (Sigfox) a rozchodil vlastní program na měření napětí autobaterie každou hodinu. Nyní jsem přešel na vyšší level a koupil si ATtiny202 (trochu mě vyděsila jeho "velikost" cca 4x4 mm a osm nožiček ????), debugger MPLAB SNAP a nahrál MPLAB X IDE vývojové prostředí. Určitě "nacpu" program z Arduina (8 kB) do ATtiny202 (max. 2 kB).

Na notebooku jsem si v C++ a x64 assembleru I7 udělal program, který načte TXT soubor o velikosti 4 GB nejednou do paměti a pak s ním pracuji. TXT soubor má 38 milionů řádků, které obsahují GPS souřadnice NOAA bójí. Neměl jsem problém data (převedené na int) v assembleru pomocí merge sort setřídit, indexovat a vyhledat hodnoty binárním hledáním včetně vynesení výsledku na mapu světu. Program během cca 3 sekund zpětně vyhledá nejpravděpodobnější místo, odkud se dostalo 12 nalezených trosek letu MH370, ve čtvercové síti souřadnic od 0° do 40°S a 80° až 108°E. Výsledkem je 4°-5°S a 80°-81°E.

Doporučuji zkusit navázat spolupráci formou brigády s nějakou firmou, která mikrokontrolery používá.

Abych jen neradil, stáhni si Visual Studio 2019 Community:
Compiling 64-bit Assembler Code in Visual Studio 2013
Introduction to x64 Assembly

C / C++ › Nenašly se knihovny tbb.dll…
12. 5. 2019   #383690

#1 Kevil
Vyřešeno, PATH neměl nastaveno cestu na adresář s knihovnami.

C / C++ › Nenašly se knihovny tbb.dll…
11. 5. 2019   #383686

Ve vlastnostech konfigurace projektu "Intel Performance Libraries" mám ve Visual Studiu 2017 nastaveno "Use Intel TBB" = Ne.

V Linker, Obecné mám v "Další adresáře knihoven" nastavenu cestu C:\Program Files (x86)\IntelSWTools\parallel_studio_xe_2019.0.045\compilers_and_libraries_2019\windows\tbb\lib\intel64\vc14

která obsahuje knihovny tbb.dll a tbb_debug.dll

Program se zkompiluje (konfigurace debug) v pohodě, ale při pokus o jeho spuštění (F5) dostanu hlášky:

Kód nejde spustit, protože se nenašel tbb.dll a tbb_debug.dll. Pokuste se tento problém vyřešit přeinstalací programu.

Při "Use Intel TBB" = Ano se chybové hlášky nezobrazí, program se spustí ale hned ukončí, u funkce fopen skončí s chybou, že nemůže načíst textový soubor

Jde o vzorový program YOLO v2 (darknet) s CUDA. Když jsem OpenCV dříve zkompiloval jen s CUDA a MKL bez TBB, tak šlapal jako hodinky.

V čem je problém ?

C / C++ › Nekompatibilní parametr typu
7. 1. 2019   #382710

#4 MilanL
Chtěl bych zkusit hledání velkých prvočísel. Našel jsem ale tip, jak na to celkem jednoduše. Vydám se asi cestou svých zkušeností s alokací několika GB paměti a x64 assembleru. Nebude to legrace pracovat s čísly, která mají více než 24 milionů číslic. P.S. Poslední nalezené provočíslo se vejde do 10 323 742 bytů.

Viz článek zde

C / C++ › Nekompatibilní parametr typu
6. 1. 2019   #382708

#2 gna
Nerozumím tvé odpovědi, v kódu jsem nic neměnil (je zkopírován z konce souboru xmp.docx v adresáři xmp/docs/ z odkazu výše) a přesto to hlásí výše zmíněné chyby.

C / C++ › Nekompatibilní parametr typu
6. 1. 2019   #382705

Chtěl bych vykoušet ukázkový příklad CUDA accelerated(X) Multi-Precision library viz odkaz zde

Na řádcích za //import a //export ale dostávám chybové hlášení:

Argument typu "uint32_t *" je nekompatibilní s parametrem typu "uint32_t"

Co s tím ?

#include "xmp.h"
#include <stdio.h>
#include <stdlib.h>
#include <C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\include\cuda_runtime_api.h>

#define XMP_CHECK_ERROR(fun) \
{                             \
  xmpError_t error=fun;     \
  if(error!=xmpErrorSuccess){ \
    if(error==xmpErrorCuda)   \
      printf("CUDA Error %s, %s:%d\n",cudaGetErrorString(cudaGetLastError()),__FILE__,__LINE__); \
    else  \
      printf("XMP Error %s, %s:%d\n",xmpGetErrorString(error),__FILE__,__LINE__); \
    exit(EXIT_FAILURE); \
  } \
}
int main() {
	int i, w;
	int N = 10000;
	int bits = 1024;
	xmpIntegers_t base, mod, exp, out;
	uint32_t *b, *m, *e, *o;
	uint32_t limbs = bits / 8 / sizeof(uint32_t);

	size_t bytes = N * bits / 8;
	b = (uint32_t*)malloc(bytes);
	o = (uint32_t*)malloc(bytes);
	m = (uint32_t*)malloc(bits / 8);
	e = (uint32_t*)malloc(bits / 8);

	xmpHandle_t handle;

	//allocate handle
	XMP_CHECK_ERROR(xmpHandleCreate(&handle));

	//allocate integers
	XMP_CHECK_ERROR(xmpIntegersCreate(handle, &base, bits, N));
	XMP_CHECK_ERROR(xmpIntegersCreate(handle, &out, bits, N));
	XMP_CHECK_ERROR(xmpIntegersCreate(handle, &exp, bits, 1));
	XMP_CHECK_ERROR(xmpIntegersCreate(handle, &mod, bits, 1));

	//initialize base, exp, and mod
	for (i = 0; i < N; i++) {
		for (w = 0; w < limbs; w++) {
			b[i*limbs + w] = rand();
		}
	}

	for (w = 0; w < limbs; w++) {
		m[w] = rand();
		e[w] = rand();
	}
	//make sure modulus is odd
	m[0] |= 1;

	//import
	XMP_CHECK_ERROR(xmpIntegersImport(handle, base, N, limbs, -1, sizeof(uint32_t), 0, 0, b));
	XMP_CHECK_ERROR(xmpIntegersImport(handle, exp, 1, limbs, -1, sizeof(uint32_t), 0, 0, e));
	XMP_CHECK_ERROR(xmpIntegersImport(handle, mod, 1, limbs, -1, sizeof(uint32_t), 0, 0, m));

	//call powm
	XMP_CHECK_ERROR(xmpIntegersPowm(handle, out, base, exp, mod, N));

	//export
	XMP_CHECK_ERROR(xmpIntegersExport(handle, o, N, &limbs, -1, sizeof(uint32_t), 0, 0, out));

	//use results here

	//free integers
	XMP_CHECK_ERROR(xmpIntegersDestroy(handle, base));
	XMP_CHECK_ERROR(xmpIntegersDestroy(handle, out));
	XMP_CHECK_ERROR(xmpIntegersDestroy(handle, exp));
	XMP_CHECK_ERROR(xmpIntegersDestroy(handle, mod));

	//free handle
	XMP_CHECK_ERROR(xmpHandleDestroy(handle));

	free(b);
	free(o);
	free(m);
	free(e);

	printf("done\n");
	return 0;
}
C / C++ › YOLO Object Detection, Nenač…
21. 10. 2018   #382016

#5 JerryM
Díky, nejsem z toho ale moc chytrej. Myslím, že to není potřeba nějak řešit. Sestavující program při kompilaci nevidí definici konstrukturu, který je definována v jiném souboru, ve finále by ale mělo být vše v pohodě.

C / C++ › YOLO Object Detection, Nenač…
20. 10. 2018   #382010

V modulu cuda.h mi to hlásí varování na řádku:

dim3 cuda_gridsize(size_t n);

warning C4190: cuda_gridsize má zadanou funkci C-linkage, ale vrací UDT dim3 nekompatibilní s jazykem C

Ve vectors_types.h je definováno:

struct __device_builtin__ dim3
{
    unsigned int x, y, z;
#if defined(__cplusplus)
    __host__ __device__ dim3(unsigned int vx = 1, unsigned int vy = 1, unsigned int vz = 1) : x(vx), y(vy), z(vz) {}
    __host__ __device__ dim3(uint3 v) : x(v.x), y(v.y), z(v.z) {}
    __host__ __device__ operator uint3(void) { uint3 t; t.x = x; t.y = y; t.z = z; return t; }
#endif /* __cplusplus */
};

typedef __device_builtin__ struct dim3 dim3;

V čem je problém ?

C / C++ › YOLO Object Detection, Nenač…
20. 10. 2018   #382009

#2 JerryM
Napadlo, ale nevěděl jsem, jak mu to poslat. Už jsem mu dotaz poslal.

C / C++ › YOLO Object Detection, Nenač…
18. 10. 2018   #381984

Na svém notebooku s W10, OpenCV 3.4.0, CUDA & CDNN a Visual Studio 2017 jsem si stáhl repozitář projektu YOLO v2 a úspěšně ho zkompiloval. Vše funguje jak má vč. rozpoznání objektů v demo videu:

darknet.exe detector demo data/voc.data yolo-voc.cfg yolo-voc.weights test.mp4 -i 0

Nechápu, proč se mi nedaří použí místo videa signál webcamery z notebooku:

darknet.exe detector demo data/voc.data yolo-voc.cfg yolo-voc.weights

U web kamery se na zlomek sekundy rozsvítí LEDka, že kamera naběhla, ale program vzápětí skončí s hláškou "Stream closed.: No error". Hláška je vidět v části demo.c viz níže

#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/version.hpp"
#ifndef CV_VERSION_EPOCH
#include "opencv2/videoio/videoio_c.h"
#endif
image get_image_from_stream(CvCapture *cap);

static char **demo_names;
static image **demo_alphabet;
static int demo_classes;

static float **probs;
static box *boxes;
static network net;
static image in   ;
static image in_s ;
static image det  ;
static image det_s;
static image disp = {0};
static CvCapture * cap;
static float fps = 0;
static float demo_thresh = 0;

static float *predictions[FRAMES];
static int demo_index = 0;
static image images[FRAMES];
static IplImage* ipl_images[FRAMES];
static float *avg;

void draw_detections_cv(IplImage* show_img, int num, float thresh, box *boxes, float **probs, char **names, image **alphabet, int classes);
image get_image_from_stream_resize(CvCapture *cap, int w, int h, IplImage** in_img);
IplImage* in_img;
IplImage* det_img;
IplImage* show_img;

void *fetch_in_thread(void *ptr)
{
    //in = get_image_from_stream(cap);
	in = get_image_from_stream_resize(cap, net.w, net.h, &in_img);
    if(!in.data){
        error("Stream closed.");
    }
    //in_s = resize_image(in, net.w, net.h);
	in_s = make_image(in.w, in.h, in.c);
	memcpy(in_s.data, in.data, in.h*in.w*in.c*sizeof(float));
	
    return 0;
}

Web kamera přitom v jiném projektu s krátkým kódem funguje v pohodě:

#include "opencv2/opencv.hpp"

using namespace cv;

int main(int, char**)
{
	VideoCapture cap(0); // open the default camera
	if (!cap.isOpened())  // check if we succeeded
		return -1;

	Mat edges;
	namedWindow("edges", 1);
	for (;;)
	{
		Mat frame;
		cap >> frame; // get a new frame from camera
		cvtColor(frame, edges, CV_BGR2GRAY);
		GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
		Canny(edges, edges, 0, 30, 3);
		imshow("edges", edges);
		if (waitKey(30) >= 0) break;
	}
	// the camera will be deinitialized automatically in VideoCapture destructor
	return 0;
}

Netušíte někdo, v čem může být problém ?

Python › YOLO Object Detection
9. 10. 2018   #381892

Programuji v C++ a x64 assembleru. Nemám ale zkušenosti s Pythonem. Poradí někdo, jak zprovoznit kód pro toto video ? Co je potřeba nainstalovat na notebook s Windows 10 ?

Python › Jak na expertní systém pro s…
8. 10. 2018   #381889

#6 Kit
Googlit umím také, ale nic konkrétního jsem nenašel. Předpokládám, že můj dotaz zodpoví někdo, kdo s tím má již nějaké zkušenosti. Rady typu: nastuduji si to či vygoogli jsou k ničemu... Sám bych si takto nedovolil někomu "radit".

Python › Jak na expertní systém pro s…
7. 10. 2018   #381887

#4 Kit
Nějaký příklad, jak to neprogramovat ?

Python › Jak na expertní systém pro s…
7. 10. 2018   #381885

#2 Kit
Přehled nemocí sice mám (cca 30 000), ale musím ještě někde sehnat jejich příznaky.

Python › Jak na expertní systém pro s…
6. 10. 2018   #381866

Nemá někdo tip, jak na to ? Jde mi o naprogramování systému, který by pomocí dotazů na příznaky nemoci byl schopen určit možnou nemoc/i. Ideálně by měl na základě odpovědí také umět poradit jaká další vyšetření provést.

Jako odrazový můstek jsem našel
https://www.geeksforgeeks.org/…ntroduction/

C / C++ › Binární hledání
14. 9. 2018   #381675

#74 MilanL
Díky, díval jsem se na to, ale bohužel tam není nějaká praktická ukázka.

Pro představu nyní trvá mému programu 7 minut, než spočítá součin počtu bójí pro 9 míst s nalezenými troskami (+/- 0,5°) a cyklem, který projíždí oblast Indického oceánu po 1°x1° od 0° až 40° S a 80° až 108° E. Pro každou z 9 oblastí to představuje 41*29 čtverců = 1 189. V každém čtverci se z 20 000 bójí, které obsahují 35 mil. GPS souřadnic, hledá počet bójí, které se pohybovaly v místě nálezu jedné z devíti trosek a aktuálním čtvercem 1°x1°. Výsledkem je heat mapa 41*29, kde je v každém čtverci součin nalezených bójí (výchozí hodnotu jsem samozřejmě nastavil na 1). Nejvyšší hodnota 4 599 504 je ve čtverci 24 S 81 E (na jedno z devít míst nálezů tak v půměru doplulo 4 599 504 ^ (1/9) = 5,50 bójí) pak udává místo, které lze s nejvyšší pravděpodobností považovat za místo, odkud začalo svou dráhu všech devět trosek do míst svých nálezů.

C / C++ › Binární hledání
14. 9. 2018   #381663

#72 Jerry
Předpokládám, že se v tom DirextX12 vyznáš. Rady typu ať si to nastuduji od začátku jsou mi na nic. Takhle bych si nedovolil někomu "radit". Pokud sem neuvedeš krátké příklady, jak předat data do paměti, najít bóje pomocí dvou zadaných oblastí a jak je vykreslit, tak je hotovo. Pokud víš jak na to, tak to přece nemůže být žádná věda. Fakt to nebudu zkoumat, když dopředu nevím, zda DirectX12 potřebné funkce vůbec má. Odkaz na ukázku "How to use DrawLine in C++ (DirectX Graphics)" je o ničem...

C / C++ › Binární hledání
13. 9. 2018   #381656

#69 Jerry
Není mi jasný, jak mi DirectX2D zrychlí vykreslení trasy po úsečkách, když nyní používám jeden příkaz na vykreslení celé trasy (5 000 "úseček") pomocí GDI Polyline ?

Jak píšeš o tom zdrojáku, tak nemám problém s jakoukoliv velikostí, musí jít ale přeložit pomocí Visual Studio 2017. Nechápu proč má 60 000 řádků. Se zoomováním ve svém programu pomocí myši počítám taky, ale vidím to na max. 50 řádků :-).

Nepotřebuji použít nějaký hotový program, musím ale jasně vědět, jak danou funkci použít ideálně na příkladu. Nebráním se zkusit pro vyhledání bójí použít funkce grafické karty, ale vůbec netuším, jak jí předat údaje o 20 000 bójích a 35 mil. GPS souřadnic.

Pokud se v tom vyznáš, tak mi prosím napiš, jak mám data načíst do paměti grafické karty, najít podle dvou oblastí bóje, jejichž trasy prošla alespoň jednou oběma oblastmi a jak nalezené trasy bójí zobrazit.

C / C++ › Binární hledání
13. 9. 2018   #381652

#66 Jerry
Díky za snahu, ale v C++ jsem v podstatě začátečník. Na takové rozsáhlé projekty nemám. Pokud mi sem někdo nedá kód, jak ty bóje z dat najít (pomocí funkcí grafické karty) a vykreslit pomocí DirectX12, tak je hotovo.

Nemám problém vykreslit trasy pomocí GDI Polyline viz můj výsledek C++ a x64 assembler ;-)

https://image.ibb.co/d3hzx9/7_b_j.jpg

C / C++ › Binární hledání
13. 9. 2018   #381643

#61 Jerry
Díky, stáhl jsem, změnil odkaz na nejnovější SDK a a zkusil přeložit. Chybí tam Segment_1h:

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
#pragma once

// TODO: reference additional headers your program requires here

#include "c:\ROBOMAP Source Code\_common libs\Segment_1.h"

#include "Stepping.h"

#include "ProcessManagement.h"

#include "EstimatorProperties.h"

#include "StartPoseA.h"

#include "MapViewer2D.h"

#include "MapViewer_Settings.h"

#include "PenDialog.h"

#include "LSBViewer.h"

#include "RSResultsA.h"

#include "ContinualLocalizationjDE.h"

#include "Form1.h"

#include "ClassReg.h"

C / C++ › Binární hledání
13. 9. 2018   #381641

#60 Jerry
Program v odkazu nefunguje, překlad hlásí chyby.  Je v něm mj.

MessageBox(NULL, TEXT("This program requires Windows NT!"), "error", MB_ICONERROR);
C / C++ › Binární hledání
13. 9. 2018   #381636

#54 Jerry
S grafickou karotu nemám absolutně žádnou zkušenost. Pokud jsem dáš zdroják, jak na to, vyzkouším to.

Vyhledání bójí si lze vyzkoušet, odkaz na setříděný soubor podle Data, ID, LAT, LON jsem zde uvedl o několik příspěvků výše a zkusit najít bóje, které např. prošly oblastmi:

//Reunion +-1,5
    Laa1 = -19.416;
    Laa2 = -22.416;
    Loa1 = 54.149;
    Loa2 = 57.149;

a

// Druhá oblast
    lab1 = -11.0;
    lab2 = -12.0;
    lob1 = 84.0;
    lob2 = 85.0;

C / C++ › Binární hledání
13. 9. 2018   #381627

#52 Jerry
Jde mi o zobrazení úseček (tras bójí), které předtím vyhledám z 20 000 bójí (35 mil. GPS souřadnic).

C / C++ › Binární hledání
9. 9. 2018   #381541

#50 Jerry
Nechápu, co myslíš průhlednou barvou. Podstatné je podle zadané oblasti/í vybrat dané bóje a vynést jejich trasy. Hledá se z cca 20 000 bójí, jedna bóje může mít i 5 000 GPS souřadnic.

C / C++ › Binární hledání
8. 9. 2018   #381539

#45 Jerry
Se zobrazením není problém. Např. 7 tras bojí z nichž každá obsahuje v průměru 1 500 souřadnic se pomocí funkce

Polyline(hdc, apt, bodu);

vykreslí v C++ ihned. Časový problém byl ty bóje rychle najít a zvlášť opakovaně, když jsem ve dvou smyčkách projížděl celý Indický oceán po 1°x1°.

C / C++ › Binární hledání
8. 9. 2018   #381538

#47 MilanL
To, že ve čtverci 1°x1° hledám bóje, které jím prošly vůbec nesouvisí s nějakým "hrubým rozlišením". Jde prostě jen o to prohledal trasy bojí a vybrat z nich ty, které prošly daným čtvercem. Ve finále jsem pro 6 trosek našel ve čtverci 11° S 84° E nejvyšší součin (abych zřetelně viděl oblasti, kterými prošlo nejvíce bójí) počtu bójí = 1 600 (vyšší hodnotu u rovníku jsem nebral v úvahu, protože tímto čtvercem neprošly bóje ze všech šesti oblastí, kde se pak trosky našly – jejich souřadnice zde pak pro hledače napíšu). Danou oblastí prošlo 8 bójí, které pak doputovaly do blízkosti místa, kde se na ostrově Reunion našel flaperon, 5 bójí - kryt klapky, 2 bóje – vertikální kormidlo, 2 bóje – kryt motoru, 5 bójí – klapka křídla a 2 bóje – Mossel Bay.

Oceňuji vaši pomoc, více hlav více ví.

P.S. Převedená data včetně indexů máš v tom SRT souboru.

Výsledná "heat map" pro 6 oblastí, kde se našly trosky:
https://image.ibb.co/bZnQup/HMH370_Heat_Map.jpg

C / C++ › Binární hledání
8. 9. 2018   #381533

#42 MilanL
To rozlišení mám na jeden celý stupeň. Samozřejmě beru v úvahu, že jsou výchozí souřadnice vynásobené 1 000 krát.

C / C++ › Binární hledání
8. 9. 2018   #381531

#40 Jerry
Ano, postupuji přesně tak, jak jsi to popsal.

Amatérsky za zajímám o letecké katastrofy včetně záhady zmizení MH370. Mj. jsem v kontaktu s očitým svědkem pozorování hořícího "objektu" Mikem McKayem z Nového Zélandu. Po zadání souřadnic 6 nalezených trosek (vč. flaperonu na ostrově Reunion) a procházením Indického oceánu ve dvou vnořených cyklech po 1° od 0° do 40° S a od 80° do 108° E jsem pomocí programu zjistil jako nejpravděpodobnější místo původu nalezených trosek souřadnice 11° S a 84° E (v tomto čtverci jsem v součinu našel nejvíce bóji, kterou danou oblastí propluly a dostaly se do blízkosti míst nálezů všech trosek).  V cyklu 2x 35 mil. řádků trval výpočet jedné oblasti 1°x1° cca 2,5 sekundy. Půlením intervalu (25 porovnání) to bude určitě ihned. Jde o oblast rovníkových proudů, do které se podle mého názoru mohly trosky snadno dostat z pobřeží Vietnamu přes Sundskou úžinu mezi Sumatrou a Jávou. Let MH370 podle mě a podle všech dostupných informací havaroval v Jihočínském moři u pobřeží Vietnamu.

Dnes snad dokončím upravený program, který hledá data pomocí půlením intervalu, to již spolehlivě funguje. Nalezené bóje musím jen zkopírovat za sebe pro jejich předání C++, aby je vykreslil na mapě.

Někdo my také radil použít např. QGIS, grafický informační systém. Ten ale není stavěn na miliony řádků. I když jsem data převedl do tvaru jeho databáze, trvá pouhé otevření dat asi 10 minut… Dříve jsem používal Excel, kdy jsem textový soubor externě připojil pomocí PowerQuery v Excelu a zadáním podmínek hledání jsem dostal souřadnice do tabulky v Excelu. Jeden dotaz trval cca 3 minuty. Pak jsem souřadnice nalezených bójí převedl na jedné webové stránce z Excelu do KML a vynesl na Google Earth.

Přidávám ještě odkaz na převedená (DWORD) a setříděná data, popis pozic viz výše, v souboru je 22 797 bójí a má 35 702 067 řádků:
https://uloz.to/!XpZdcLPdtNC7/srt-180823-dat

A příklad výstupu mého programu (hledání), vynesení bójí ještě přes Excel a Google Earth:
https://image.ibb.co/f2mck9/MH370_6_1184.jpg

C / C++ › Binární hledání
7. 9. 2018   #381528

#35 Jerry
Se souborem se nemazlím. Na 1,5x ho celý načtu naráz (po 2 501 566 399 bytech) do alokované paměti 5 GB (VirtualAlloc) a pak s ním pracuji ;-).

C / C++ › Binární hledání
7. 9. 2018   #381527

#37 MilanL
Data jsem stáhl ze stránky http://www.aoml.noaa.gov/phod/gdp/index.php. Ty čtyři soubory *dat.gz jsem sloučil do jednoho a nahradil desetinné tečky čárkou. Na stránce ftp://ftp.aoml.noaa.gov/phod/pub/buoydata/ je jejich popis včetně struktury, soubor "header_buoydata.txt".

Když budeš potřebovat, mohu ti poslat odkaz na setříděný soubor podle LAT, LON, ID a data/času. Soubor je stejný, jako ten co máš, jen jsem na nevyužitá místo v řádku uložil DWORD hodnoty LAT, LON... a DWORD odkaz na řádek kde lze pomocí nepřímého odkazu přečíst setříděnou hodnotu. Příklad: na prvním (nultém) řádku setříděného souboru najdeš na pozicích 56 DWORD LAT (hodnota ASCII ze začátku řádku) a hned za ní, pozice 60 DWORD odkaz na řádek, kde je nejnižší hodnota LAT, vynásobením tohoto čísla 125 dostaneš č. řádku s nejnižší hodnotou LAT na pozici 56 DWORD.  Odkaz na další stejnou nebo vyšší hodnotu LAT je pak na dalším řádku atd. Dtto pro LON (64 + index 68), ID (72 + 76) a Datum/čas (80 + 84). Datum čas jsem převedl do DWORD na počet bitů 11+4+5+2 t.j. rok, měsíc, den a 1/4 dne. Tj. 7.9.2018 + 3*6 hodin je ve tvaru 0x3F149F.

C / C++ › Binární hledání
7. 9. 2018   #381515
C / C++ › Binární hledání
6. 9. 2018   #381513

#30 MilanL
V zápalu boje mě to nenapadlo zkomprimovat... sorry.

C / C++ › Binární hledání
6. 9. 2018   #381511

Nesetříděný textový soubor s daty 4 GB je ke stažení na https://uloz.to/!mQDfiGbQdDlP/bda-180823-dat

Pevné pozice, šířka sloupců: 8, 5, 7, 5, 10, 10, 80. Počet řádků 35 702 066.

č. bóje (ID), měsíc, den a 1/4 dne (GPS pozice odesílány každých 6 hodin), rok, LAT, LON, nepotřebná data

Pro začátek lze najít 7 bójí (čísla znám), které prošly oblastí:

LATa1 = -5,9;
LATa2 = -6,6;
LONa1 = 104,8;
LONa2 = 106,6

Mohu také případně nahrát soubor s ASCII údaji převedenými na DWORD + DWORD s nepřímým odkazem na setříděné hodnoty LAT, LON a ID. Ponechal jsem v něm ale také původní ASCII hodnoty.
 

C / C++ › Binární hledání
6. 9. 2018   #381510

#27 MilanL
Už ti nahrávám soubor 4 GB, se kterým pracuji. Za chvíli sem dám odkaz ke stažení a popíšu strukturu řádku, ať máš reálná data ;-).

C / C++ › Binární hledání
6. 9. 2018   #381496

#22 MilanL
Jasně vím o tom. To násobení má minimální vliv na celý program. Musím ještě upravit hledání ve druhé oblasti půlením a dám pak vědět, jak to běhá.

C / C++ › Binární hledání
6. 9. 2018   #381491

#20 MilanL
Program hledá čísla bójí, které se pohybovaly ve dvou čtvercových oblastech podle zadaných LAT/LON. Nevadí, že nějaká bóje oblast opustí a pak se do ní vrátí. Ve finále pak vynáším celou trasu bojí, které jsem našel (t.j. trasa dané bóje prošla oblastí 1 a 2). Při kreslení musím ještě přepočítat souřadnice na body na obrazovce a uložit trasu do pomocného vektoru pro funkci Polyline(hdc, *apt, cpt), to už dělám v C++.

Na třídění (soubor si pak uložím a nemusím data pokaždé třídit) používám Merge Sort. Celočíselné násobení 125 je velmi rychlé, vynásobení rcx 125 za pomoci násobků 2, posunů a sčítání je pomalejší:

	mov rax, rcx
	shl rcx, 2		; *4
	add rax, rcx
	shl rcx, 1		; *8
	add rax, rcx
	shl rcx, 1		; *16
	add rax, rcx
	shl rcx, 1		; *32
	add rax, rcx
	shl rcx, 1		; *64
	add rax, rcx
C / C++ › Binární hledání
6. 9. 2018   #381484

#17 MilanL
Takhle nějak to dělám ;-). Originální data jsou v textovém souboru s pevnou délkou sloupců. Souřadnice ve tvaru XXX,xxx převedu na DWORD vynásobením 1 000 a u záporné LAT přičtu 90 000 abych neřešil int se znaménkem, LON hodnoty jsou v rozsahu 0-360°. Za DWORD hodnotami LAT/LON mám pak další DWORD které nepřímo odkazují na řádek s hodnotou LAT/LON po setřídění. Řádek je dlouhý 125  bytů, na začátku ponechám v ASCII č. bóje a LAT/LON, tyto hodnoty mám pak uloženy v DWORD od pozice 56 (kde jsou v ASCI další údaje, které nepotřebuji). Hledám tedy v setříděné tabulce. Vlastní funkce pro hledání půlením intervalu pak reálně vypadá takto:

Najdi:											; r11=L, r12=P, r13=S, r14=pro porovnání, r15=hodnota,rcx=125, rbx=pozice; použit rax a rdx
mov r14, rax									; Hodnota pro porovnání
xor r11, r11									; L (příprava)
mov r12, 35702066								; řádků
dec r12											; pravý okraj pole menší o jedničku
mov rcx, 125									; Konstanta pro násobení
Najdi_W:
	mov rax, r11
	cmp rax, r12								; L <= P ?
	ja Najdi_E								    ; Ne, tj. konec
	add rax, r12
	shr rax, 1
	mov r13, rax								; r13=L+P/2
	imul ecx									; edx:eax = eax * ecx
	shl rdx, 32
	or rax, rdx									; sloučíme Hi edx a Lo eax
	add rax, rbx								; Přičteme pozici
	mov edx, [rsi+rax+4]					    ; Vyvedneme č. řádku s odkazem na IND hodnotu LAT/LON
	mov eax, edx
	imul ecx									; edx:eax = eax * ecx
	shl rdx, 32
	or rax, rdx									; sloučíme Hi edx a Lo eax
	add rax, rbx								; Přičteme pozici
	mov edx, [rsi+rax]					        ; IND hodnota LAT/LON
	cmp edx, r14d								; [stred] <= hodnota ?
	ja Najdi_D
	mov r15d, edx								; Nalezená hodnota	
Najdi_D:
	cmp r14d, edx								; hodnota > [stred]
	ja Najdi_P									; Ano
	mov r12, r13
	dec r12
	jmp Najdi_W
Najdi_P:
	mov r11, r13
	inc r11
	jmp Najdi_W
Najdi_E:
mov rax, r13
inc rax
call Get_IND_Value
cmp edx, r15d									; Hodnota řádek + 1 je stejná ?
ja Najdi_K										; Ne
	inc r13										; Ano, řádek = řádek + 1
	jmp Najdi_E
Najdi_K:
ret
C / C++ › Binární hledání
6. 9. 2018   #381482

Pro ošetření výskytu více stejných hodnat za sebou a nastavení indexu na poslední z nich zprava stačilo na konec programu půlení v assembleru přidat:

    mov rax, r13          ; V r13 nalezený řádek (index) zleva
    inc rax
    call Get_IND_Value    ; Vrátí hodnotu na řádku do r15d
    cmp edx, r15d         ; Hodnota řádek + 1 je stejná ?
    ja Najdi_K            ; Ne
        inc r13           ; Ano, řádek = řádek + 1
        jmp Najdi_E
    Najdi_K:
C / C++ › Binární hledání
5. 9. 2018   #381479

#14 MilanL
Dostal jsem tip, jak to správně udělat:

#include <iostream>
#include <algorithm>
 
int main() {
    int arr[] = {0, 2, 3, 5, 5, 6, 8, 8, 8, 9};
    auto beg = std::begin(arr);
    auto it = std::upper_bound( beg, std::end(arr), 8 );
    if( it == beg ) {
        std::cout << "no value less than 8 found" << std::endl;
        return 0;
    }
    std::cout << "index is " << std::distance( beg, it ) - 1 << std::endl;
    return 0;
}

Funguje to. Rád bych to naprogramoval v assembleru, kde nemohu použít speciální direktivy jako "upper_bound". Viz popis https://en.cppreference.com/w/cpp/algorithm/upper_bound

C / C++ › Binární hledání
5. 9. 2018   #381466

#10 Jerry
Na to, že se programováním vůbec neživím mi nepřipadá nějaký extrém se naučit základy C++ za cca 3 měsíce pro relativně náročný úkol. Program dělá to co potřebuji, jen se ho teď snažím urychlit. Oceňuji, že mi pomohly i některé rady zde ve fóru :-).

U GPS mi stačí x, y. Sférické souřadnice nepotřebuji.

C / C++ › Binární hledání
4. 9. 2018   #381462

#6 gna
Program dělá přesně to, co jsem chtěl. Najde první nejbližší nižší nebo stejnou zadanou hodnotu čísla vektoru (index) zleva. Jde o celá čísla.

C / C++ › Binární hledání
4. 9. 2018   #381461

#7 Jerry
Není mi jasné, k čemu bych měl Fibonacciho čísla použít. Pracuji s GPS souřadnicemi. Hledání čísel půlením intervalu je v sestříděném vektoru o 35 mil. čísel otázkou max. 25x porovnání (log 35 mil. / log 2). Dosud jsem (nesetříděná) čísla hledat ve dvou vnořených cyklech, které jsem procházel 2x 35 milionkrát. I tak to bylo v assembleru prakticky na stisk tlačítka. Půlením intervalu to nyní bude ihned. Potřebuji to pro real time vynášení tras pohybu bójí v moři volbou oblasti pohybem myši na obrazovce.

C / C++ › Binární hledání
3. 9. 2018   #381448

#3 gna
Takováto rada mi moc nepomůže. Už mi to ale funguje (najde index první hodnoty z více stejných hodnot zleva).
 

#include "pch.h"
#include <iostream>

int seznam[10]{0, 2, 3, 5, 5, 6, 8, 8, 8, 9};
int arr_size = sizeof(seznam) / sizeof(seznam[0]);


int main()
{
	for (int i = 0; i <= arr_size; i++)
	{
		printf("%i\n", seznam[i]);
	}
	printf("\n");

	int vlevo = 0;
	int vpravo = arr_size - 1;
	int stred = 0; 
	int hodnota = 8 ;
	bool nasel = false;
	int x = 0;
	int pozice = 0;
	
	

	//* Hledámě hodnotu v setříděném poli
 	while (vlevo <= vpravo) {
		stred = (vlevo + vpravo) / 2;
		if (seznam[stred] <= hodnota) {
			x = seznam[stred];
			pozice = stred;
		}
		if (hodnota > seznam[stred]) {
			vlevo = stred + 1;
		}
		else {
  			vpravo = stred - 1;
		}
	}
	printf("Nasel jsem %i na pozici %i\n", x, pozice);

}
C / C++ › Binární hledání
3. 9. 2018   #381447

#2 Jerry
On by se ten cyklus ale opakoval 35 milionkrát, tolik mám řádků ;-). Chaos v tom žádný není. Index 8ček je věcí, zda brát první 8ku zlava nebo zprava.

C / C++ › Binární hledání
2. 9. 2018   #381441

Jak upravit následující program, aby mi vrátil hodnotu indexu pole po zadání hodnoty = 7, která není v seznamu ? Jde mi vrácení nejvyšší hodnoty indexu pro zadanou hodnotu, kde je hodnota daného čísla v seznamu <= zadané hodnotě. Tj. pro hodnotu = 7 by měl program vrátit index 5 a pro hodnotu = 8 index 8. Data v seznamu jsou setříděna.

#include "pch.h"
#include <iostream>

int seznam[10]{0, 2, 3, 5, 5, 6, 8, 8, 8, 9};
int arr_size = sizeof(seznam) / sizeof(seznam[0]);


int main()
{
	for (int i = 0; i <= arr_size; i++)
	{
		printf("%i\n", seznam[i]);
	}
	printf("\n");

	int vlevo = 0;
	int vpravo = arr_size - 1;
	int stred = 0; 
	int hodnota = 3 ;
	bool nasel = false;

	//* Hledámě hodnotu v setříděném poli
	while (vlevo <= vpravo) {
		stred = (vpravo + vlevo) / 2;
		if (seznam[stred] == hodnota) {
			nasel = true;
			printf("%i\n", stred);
		}
		if (hodnota < seznam[stred]) {
			vpravo = stred - 1;
		}
		else {
 			vlevo = stred + 1;
		}
	}
}
C / C++ › Generování náhodných čísel
30. 8. 2018   #381406

Už jsem na to přišel. Problém byl v uniform_INT_distribution... ;-) Generátor jsem použil pro zkušební setřídění pole 35 mil. řádků v paměti.

random_device rd;  
	mt19937 gen(rd());
	uniform_int_distribution<> dist(0, 0x7FFFFFFF);  

	for (int i = 0; i < 10; ++i) {
		cout << dist(gen) << " ";
	}
C / C++ › Generování náhodných čísel
30. 8. 2018   #381405

#2 MilanL
Neleze z toho vůbec nic, překladač mi hlásí chybu, že musí být hodnoty rozsahu generovaných čísel float čísla. Na netu jsem našel "x" příkladů náhodného generátoru ale ani jeden pořádně nefunguje tak, jak bych potřeboval tj,  generovat kladná DWORD čísla v rozsahu 0 až 0x7FFFFFFF.

...requires one of float, double, or long double.

C / C++ › Generování náhodných čísel
29. 8. 2018   #381400

Nemohu přijít na to, proč mi to negeneruje int čísla v rozsahu 0 až 0x7FFFFFFF. 

random_device rd;
mt19937 gen(rd);
uniform_real_distribution<int> dis(0, INT_MAX);
for (int p = 0; p < 10; p++) {
	printf("%i\n", dis(gen));
}
C / C++ › Předání dynamické velikosti…
23. 8. 2018   #381357

#15 MilanL
Já jsem kdysi psal v assembleru grafické rutiny pro MOS 6502, Commodore 64 ;-)

C / C++ › Předání dynamické velikosti…
23. 8. 2018   #381355

#13 MilanL
Jasně to chápu, Samozřejmě není žádný problém to udělal ve verzi 32bitů.

C / C++ › Předání dynamické velikosti…
23. 8. 2018   #381349
C / C++ › Předání dynamické velikosti…
23. 8. 2018   #381343

#8 MilanL
Při práci s jednotlivými bity bych dal přednost to udělat v ASM voláním funkce z C++. Bylo by to jednodušší a s plnou kontrolou, co se děje :-).

C / C++ › Předání dynamické velikosti…
22. 8. 2018   #381334

Vyřešeno, stačilo vyhodit "static", díky radě na stackoverflow ;-)

const SIZE_T size_L = n1 *125;

Takhle to již funguje bez problémů.
 

C / C++ › Předání dynamické velikosti…
22. 8. 2018   #381330

#2 Radek Chalupa
Proměnná n1 je typu int, během programu se jeji hodnota mění. Jde o počet prvků levého pomocného pole pro třídění merge sort.

C / C++ › Předání dynamické velikosti…
22. 8. 2018   #381328

Potřebuji předat funkci VirtualAlloc požadovanou velikost paměti, kterou vypočítám pomocí proměnné. Parametr je ale typu SIZE_T dwSize

Toto nefunguje,  

static const SIZE_T size_L = n1 *125;
BYTE* L_adr = static_cast<BYTE*>(VirtualAlloc(NULL, size_L, MEM_COMMIT, PAGE_READWRITE));

size_L je bez ohledu na hodnotu int n1 vždy 125.

Pokud potřebuji alkovat pamět s konkrétní hodnotou tak to funguje

static const SIZE_T giga = 1024 * 1024 * 1024;
static const SIZE_T size = 8 * giga;
BYTE* ptr = static_cast<BYTE*>(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));

Jak do size_L dostat vypočítanou velikost potřebné velikosit paměti ?

C / C++ › Převod ASCII čísla v paměti…
20. 8. 2018   #381324

Už to funguje :-)
Funkce na převod

Int Prevod(__int64 ASCII_adresa, int ASCII_delka, int ASCI_pozice)
{
	*(BYTE *)(ASCII_adresa + ASCI_pozice + ASCII_delka) = 0x00;
	return atoi(reinterpret_cast<CHAR*>(ASCII_adresa + ASCI_pozice));
}

Cyklus pro úpravu 50 mil. řádků:

for (int i = 0; i < radku; i++)		//Cyklus pro úpravu dat
	{
		misto = adresa + (i * 125);		//Načteme ID
		x = Prevod(misto, 8, 0);
		*(DWORD *)(misto + 56) = x;		//a uložíme na pozici 56
	}
C / C++ › Převod ASCII čísla v paměti…
20. 8. 2018   #381322

#2 hlucheucho
Díky, tu nulu na konec mohu doplnit. Funkce by pak mohla vypadat takto: 

int Prevod(int pocet, __int64 misto)
{
	*(BYTE *)(misto + pocet) = 0x00;
	return stoi(*(CHAR*)((misto));
}


Visual Studio mi ale červeně podtrhlo "stoi" a ";" na konci řádku. Co je špatně ?

C / C++ › Převod ASCII čísla v paměti…
20. 8. 2018   #381317

Potřeboval bych poradit, jak převést ASCI čísla, kterámám uloženo v paměti, nejsou ukončeno \0 !!!  např. "   80766". Znám jeho délku a pozici prvního znaku v paměti. Jde mi funkci, kterou pak budu volat v cyklu.

int ASCI_na_cislo(int ASCIdelka, int ASCIpozice)
{
	return stoi(reinterpret_cast<string*>(adresa));
}

adresa je 64bit adresa na začátek paměti ke které je potřeba přičíst pozici prvního znaku (ASCIpozice).

Příklad volání funkce z Main:

x = ASCI_na_cislo(8, 0) 

Případně provést koverzi pomocí stringstream class nebo sscanf() ?

C / C++ › Jak odkázat na třídu POINT d…
13. 8. 2018   #381228

Tak už mi vykreslování pomocí Polyline chodí :-). Zádrhel byl v tom, že jsem chybně přepočítával souřadnice bodů na body na obrazovce a ještě jsem měl uloženo nejdříve Y a pak X ... Odkaz na body v paměti

reinterpret_cast<POINT*>(memory)

funguje v pohodě.

Body pak nenavazovaly na sebe a funkce Polyline to nemohla vykreslit. Díky všem za rady ;-).

C / C++ › Jak odkázat na třídu POINT d…
13. 8. 2018   #381224

#61 gna
Težko říct, co tím myslíš.

Překlepl jsem se. Myslel jsem:

*ptr = 7;	// Nevím jak tam zadat data, aby se místo čísla 7 ukládala proměnná "i"
C / C++ › Jak odkázat na třídu POINT d…
12. 8. 2018   #381213

#57 MilanL
Reálně potřebuji vyřešit ale tohle:

// Test.cpp : Zkouška přiřazení dvojic hodnot v paměti do třídy POINT
//

#include "stdafx.h"
#include <stdlib.h>

int main()
{
	void *memory = calloc(12, sizeof(int));	//Alokujeme pole pro 6 INT párů po 4 bytech
	int *ptr = (int *)memory;
	for (int i = 0; i < 12; i++)
	{
		*ptr = 7;							// Nevím jak tam zadata, aby se ukládala proměnná "i"
		printf("%i\n", *ptr);
		ptr++;								// Posun na začátek dalšího DWORD
	}
	// Tady by pak mělo být přiřazení uložených hodnot v paměti do třídy POINT (asi včetně počtu dvoji bodů tj. 6)
	free(memory);
	return 0;
}
C / C++ › Jak odkázat na třídu POINT d…
12. 8. 2018   #381212

#58 MilanL
Ano, byla tam chybka, na konci má být jen + 4.

C / C++ › Jak odkázat na třídu POINT d…
10. 8. 2018   #381193

#50 MilanL
Pánové, musí se na to úplně jinak. Dostal jsem radu:
 

As input, Polyline() takes a pointer to an array of POINTstructs, and the number of elements in the array.

POINT has two data members that are both of type LONG, so if you have an existing array of DWORD pairs in memory, you could simply type-cast that address to a POINT* pointer when you pass it to Polyline() (as DWORD and LONG have the same byte size in the Win32 API), eg:

DWORD *pairs = ...;
DWORD numPairs = ...;
...    
Polyline(hdc, reinterpret_cast<POINT*>(pairs), numPairs);

However, a safer approach is to simply allocate a separate POINT[] array in memory and copy the DWORD values into it, then pass that array to Polyline(), eg:

DWORD *pairs = ...;
DWORD numPairs = ...;
...    

POINT *points = new POINT[numPairs];
for(DWORD i = 0; i < numPairs; ++i)
{
    points[i].x = pairs[i*2];
    points[i].y = pairs[(i*2)+1];
}

Polyline(hdc,

FYI, in your question you mention GDI+, but Polyline() is part of GDI, not GDI+. The GDI+ equivilent is Graphics::DrawLines(), but it requires an array of Pointclass objects instead of POINT structs. You can't safely type-cast a DWORD array to Point*, you would have to actually construct the individual Point objects (using the Point(int,int) constructor), similar to above, eg:

DWORD *pairs = ...;
DWORD numPairs = ...;
...    

Point *points = new Point[numPairs];
for(DWORD i = 0; i < numPairs; ++i)
    points[i] = Point(static_cast<INT>(pairs[i*2]), static_cast<INT>(pairs[(i*2)+1]));

Graphics *g = Graphics::FromHDC(hdc);
Pen pen(...);
g->DrawLines(&pen, points, numPairs);
delete g;

delete[] points;

Pomocí reinterpret_cast mi příkaz Polyline už začal něco kreslit, zatím blbě, musím zkontrolovat přepočet na správné pozice.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381187

#44 KIIV
Myslím, že není potřeba složitě nic generovat. Jde mi "jen" o správné přiřazení adresy v paměti struktuře bodů POINT apt včetně počtu párů (GDI+), aby mi funkce Polyline vykreslila trasu těch bodů.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381186

#37 MilanL
Stále bohužel nefunguje správné přiřazení bodů v paměti do apt. 

POINT	 apt[156];

Připojen obrázek.


takto to funguje správně. Tj. když v breaku najedu na apt, zobrazí se okno s adresou apt a následně 156 párů bodů x, y

Pokud ale použiju kód

bodu = *(DWORD *)(bsrc + 0x01719F0F6B + 4 * x + 4);
POINT *apt = (POINT*)(bsrc + 0x01719F0F6B + 8 * x + 8)[bodu];
for (int i = 0; i < bodu; i++)	// Naplníme pole pro vynášení bójí
	{
		if (apt[i].x > 180000)
		{
			apt[i].x = 960 - ((-1)*apt[i].x - 180000) / (float)180000 * 960;
		}
		else {
			apt[i].x = (float)apt[i].x / (float)180000 * 960 + 960;
		}
		if (apt[i].y > 90000)
		{
			apt[i].y = 540 - ((-1)*apt[i].y - 90000) / (float)90000 * 540;
		}
		else {
			apt[i].y = (float)apt[i].y / (float)90000 * 540 + 540;
		}
	}

POINT je špatně nastaven a data se zapisují mimo správnou paměť

Připojen obrázek.

I když z řádku vyhodím [body]. tj. počet bodů, nepřiřadí se 2 315 bodů správně a Polyline nic nevykreslí

Připojen obrázek.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381180

#38 KIIV
Nejradši mám teoretiky bez konkrétní rady... Soubor je textový.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381178

#37 MilanL
Díky, vyzkouším to a dám vědět ;-)

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381173

#30 MilanL
tam je něco v paměti na těch prvních 4 BYTEch?

Ano, to X je počet nalezených bóji DWORD, které se pohybovaly mezi dvěma zadanými oblastmi (ve tvaru čtverce). Dosud jsem postupoval tak, že mi program našel počet bójí a čísla bóji. Ta jsem pak zadal do dotazu PowerQuery v Excelu, ke kterému jsem měl externě připojený ten velký soubor. Výsledkem byly souřadnici bodů dané bóje v Excelu. Excelový soubor se souřadnicemi jsem pak pomocí https://www.earthpoint.us/ExcelToKml.aspx převedl na KML soubor a vynesl na Google Earth. V neplacené verzi je tam ale omezení jen na 200 bodů, počet bodů musím proti poměrně snížit. Bóje ale mohou obsahovat klidně 5 000 bodů. Výsledekm je pak např. takováto mapa.

Připojen obrázek.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381172

#32 KIIV
Nejsem žádný programátor, to jsem se v C++ potřeboval, jsem se z příkladů naučil za měsíc. Pokud by bylo možné vynést křivky rovnou z ASM udělal bych to (zavolat z ASM funkci Polyline v C++). Oproti C++ nemám s assemblerem žádný problém. Zkus v C++ hledat v 50 milionech řádcích ;-). Mapování souboru mi nepomůže, pokud načtu celý soubor do paměti, rychleji s ním pracovat nelze.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381166

#26 MilanL
Dal jsem tam:

	apt[0].x = -10127;
	apt[0].y = 73025;

to funguje. Nehlásí to žádnou chybu, data se správně uloží a apt odkazuje na správnou adresu paměti tj. na ty první dvě hodnoty. Viz screen shot obrazovky. Na adrese 0x000002360c3c0fb3 jsou správně uloženy obě hodnoty (DWORD) x= -10127 tj. 71 D8 FF FF a y=73025 tj. 41 1D 01 00. Teď ještě do apt nějak dostat počet bodů.
 

Připojen obrázek.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381165

#24 MilanL
nj, ale tam žádná data načtená nejsou, tak ti to nemůže nic vracet žádný počet vbojí, žádná ID nebo počty bodů a už vůbec ne data bodů

Data tam samozřejmě jsou, ukládá mi je tam ASM funkce a při breaku C++, výpis RAM paměti, je tam spolehlivě vidím. Díky za ukázku v C++ která ale nevystihuje podstatu věci tj. přístup na data ze skutečné RAM paměti. V programu by jsi musel použít VirtualAlloc, do paměti si zapsat nějaké hodnoty a pak ty hodnoty použít v POINT class.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381161

#21 MilanL
O to mi přesně jde. Nechápu, kam POINT apt[X] ukládá počet těch bodů. Žádnou extra proměnnou na to nemám a pokud použiji zkušebních 156 bodů tj.  

POINT apt[156]

, tak apt ví, že jde o 156 bodů.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381160

#20 MilanL
Offset 0x01719F0F6B  ? To je jednoduché. Pomocí VirtualAlloc alokuji 7 GB paměti do které načtu 6 GB soubor (to je těch 0x01719F0F6B), data pak ukládám za něj do zbylého 1 GB RAM.

C / C++ › Jak odkázat na třídu POINT d…
9. 8. 2018   #381156

#18 gna
Nějak se motáme v kruhu. Myslím, že jsem zcela jasně popsal, o co mi jde. Strukturu POINT potřebuji nastavit na má data v paměti a to včetně jejich počtu. Nejde jen úpravu souřadnic pro jejich vynesení do Full HD okna (1980 x 1080 bodů). Správné nastavení na data v paměti potřebuji pro jejich vykreslení pomocí funkce Polyline, která použivá parametr apt. Když na něj při ladění programu najedu, ukazuje počet bodů 156...

C / C++ › Jak odkázat na třídu POINT d…
8. 8. 2018   #381154

#16 MilanL
Ve výpočtech odkazů není chyba, zkontroloval jsem si to. Problém je, že nefungují odkazy na POINT do paměti podle pokynů výše:

INT32	LAT[156]{ -10127, -10291, -11002, -11149, -10807, -9789, -8948, -8328, -8183, -7918, -7259, -6590, -5993, -7324, -8584, -8876, -8603, -8262, -8858, -8326, -7710, -8189, -7419, -6292, -5564, -5227, -4379, -3494, -3382, -3298, -4022, -4732, -3894, -4604, -6124, -6672, -6904, -7157, -7512, -7987, -8552, -9248, -10438, -10727, -11218, -11566, -12788, -12717, -12070, -11746, -11839, -11238, -11477, -12224, -12864, -14048, -14053, -13786, -14131, -14516, -14395, -14562, -14536, -14487, -14604, -14514, -14833, -14992, -15294, -15153, -15899, -16565, -17287, -17540, -18308, -18508, -18127, -18594, -19131, -19656, -21120, -21738, -21998, -20052, -19360, -19651, -22041, -26186, -25980, -24102, -23168, -22478, -22066, -22263, -23992, -24398, -24821, -26567, -25563, -26156, -25605, -26105, -26391, -25959, -25354, -25366, -26465, -26772, -25812, -25405, -25293, -26805, -29343, -31190, -31647, -32224, -32780, -32636, -32124, -32648, -33977, -34820, -36280, -36874, -35570, -35237, -33215, -34272, -33742, -32777, -32337, -31360, -31185, -31081, -30244, -28997, -27578, -27596, -27393, -27207, -27258, -27371, -26831, -26142, -26505, -26753, -26752, -26340, -26319, -26206, -26212, -26476, -26642, -26790, -26789, -26490
	};
	INT32	LON[156]{ 73025, 73056, 72348, 71368, 70694, 70816, 69896, 69756, 68782, 67560, 66618, 66209, 66586, 66171, 65126, 63698, 62961, 62424, 62597, 63580, 64129, 64918, 66398, 67329, 67455, 68054, 70343, 72531, 74184, 76406, 78643, 80838, 83212, 84528, 86157, 87738, 88750, 89554, 90109, 90485, 90798, 91481, 90374, 88523, 86799, 84249, 83107, 81232, 80334, 78805, 77591, 76457, 75045, 73544, 72271, 71062, 69696, 68603, 67876, 67306, 66004, 64291, 62692, 61926, 61540, 61192, 61142, 61042, 61153, 61206, 60941, 60356, 59374, 58525, 57722, 57662, 56746, 55771, 55351, 54571, 54200, 54324, 53027, 51690, 50442, 49689, 48362, 46033, 41235, 41275, 41375, 40487, 39458, 38626, 39822, 40245, 40429, 40149, 39217, 38947, 39100, 36916, 38485, 36234, 38713, 40824, 41513, 41779, 41089, 40006, 38967, 38710, 36581, 36241, 35660, 34026, 34544, 32490, 31168, 30185, 29004, 26684, 23031, 15876, 15791, 15628, 13732, 12223, 11979, 12393, 12141, 11593, 10385, 8649, 8551, 9156, 7629, 6108, 6080, 5060, 4762, 4922, 4524, 3795, 3522, 3814, 3792, 2947, 2949, 2763, 2349, 2648, 2273, 1383, 775, 245
	};
	//POINT	 apt[156]{};
	POINT	 *apt = (POINT*)(bsrc + 0x01719F0F6B + 8 * x + 8)[*(DWORD *)(bsrc + 0x01719F0F6B + 4 * x + 4)];
	for (int i = 0; i < 156; i++)	// Naplníme pole pro vynášení bójí
	{
		apt[i].x = (float)LON[i] / (float)180000 * 960 + 960;
		apt[i].y = (float)abs(LAT[i]) / (float)90000 * 540 + 540;
	}

Těch 156 hodnot mám v C++ jen pro účely testování. Pokud program při ladění zastavím za blokem řádků výše a najedu kurozorem na řádek s POINT na apt (address of points structure) zobrazí se mi:

apt|0x0000000000000000 <NULL>

Pokud odzávorkuji řádek //POINT     apt[156]{}; a z řádku níže udělám komentář je vše v pořádku:

apt|0x00000093a04fe960 {{x=1349 y=600}, {x=1349 y=601}, {x=1345 y=606}, {x=1340 y=606}, {x=1337 y=604}, ...}

C / C++ › Jak odkázat na třídu POINT d…
7. 8. 2018   #381142

#11 Kevil
Upravil jsem na reálný kód:

POINT	 *apt = (POINT*)(bsrc + 0x01719F0F6B + 8 * x + 8)[*(DWORD *)(bsrc + 0x01719F0F6B + 4 * x + 4)];

kde údaje v závorkách ukazají na správné místo paměti, první je odkaz na souřadnice bodů a druhý odkaz na počet bodů = 2 315. Překlad proběhl bez závad, ale ve struktuře je místo počtu bodů 0, páry bodů proto nejsou  vidět.

Pro vysvětlení to x = 8 udává počet nalezených bojí, jejichž trasy chci pak pomocí Polyline vykreslit. Než se to podaří rozchodit, tak nyní pracuji pouze s daty první bóje. Data mám v paměti uložena ve tvaru DWORD od bsrc + x01719F0F6B + 4: počet bójí (8), ID bójí (8x), počet bodů pro bóji (ID=1, ID=2,...) a pak vlastní souřadnice bodů, nejdříve x1, y1, x2, y2... pro bóji ID=1 atd.
 

C / C++ › Jak odkázat na třídu POINT d…
7. 8. 2018   #381141

#10 gna
Nějak musí jít do toho POINT a funkce Polyline zadat počet bodů odkazem na proměnnou v paměti. Jde např. o 2 500 bodů. Funkce Polyline má syntaxi:


BOOL Polyline( HDC hdc, CONST POINT *apt, int cpt );
 

C / C++ › Jak odkázat na třídu POINT d…
7. 8. 2018   #381138

#7 KIIV

VirtualAlloc volám z C++ a adresu pak předám při volání ASM funkci (např. Funkce_Uprav). Alokuji 7 GB do kterých načtu 6 GB externí soubor s daty, který obsahuje 50 mil. řádků. Soubor musím načíst na 3x, nepodařilo se mi přijít na to, jak ho načíst najednou, to ale není žádný problém. načtení trvá cca 3 sekundy. Na notebooku mám 24 GB RAM. Část funkčního kódu pro alokaci RAM a načtení souboru:

_int64 FileSize(const wchar_t* name)
{
	WIN32_FILE_ATTRIBUTE_DATA fad;
	if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
		return -1; // error condition, could call GetLastError to find out more
	LARGE_INTEGER size;
	size.HighPart = fad.nFileSizeHigh;
	size.LowPart = fad.nFileSizeLow;
	return size.QuadPart;
}

VOID OnPaint(HDC hdc)
{
	delka = FileSize(fname); // 64 bitů
	zbyva_nacist = delka;
	printf("%lli\n\n", FileSize(fname));

	//* Zkusíme otevřít soubor pro čtení *//
	HANDLE handle = CreateFile(fname, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
	//if (handle == INVALID_HANDLE_VALUE)
	//	report_error("Unable to open input file!\n");

	//* Alokujeme pamět pro celý soubor *//
	static const SIZE_T giga = 1024 * 1024 * 1024;
	static const SIZE_T size = 7 * giga;
	BYTE* ptr = static_cast<BYTE*>(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
	/*if (ptr == nullptr) {
		std::cout << "Chyba pri alokaci pameti\n";
		return 1;
	}*/
	std::cout << "Pamet alokovana\n";
	BYTE* bsrc = ptr;

	//* Načteme soubor *//
	DWORD bytes_read;
	for (int i = 1; i <= 3; i++) {
		if (i < 3) {
			cti_znaku = cti_blok;
		}
		else
		{
			cti_znaku = delka - nacteno;
		}
		ReadFile(handle, ptr, cti_znaku, &bytes_read, nullptr);
		nacteno += bytes_read;
		ptr += bytes_read;
	}
	CloseHandle(handle);

	// Upravíme načtená data v poli
	adresa = (__int64)bsrc;
	__int64 result = Funkce_Uprav(adresa);
C / C++ › Jak odkázat na třídu POINT d…
7. 8. 2018   #381137

#6 gna
Díky, to je skoro přesně to, co jsem potřeboval. Teď mi to již ukazuje správně na data v paměti, ale chybí tam ještě, jak zadat počet bodů.

Původně jsem tam měl natvrdo: 

POINT apt[156];

teď mi sice apt odkazuje správně na data v paměti, použit reálný kód:

POINT	 *apt = (POINT*)(bsrc + 0x01719F0F6B + 8 * x + 8);

ale struktura POINT neví, kolik bodů tam je. Potřebuji ještě předat odkaz na DWORD v paměti s počtem bodů.

C / C++ › Jak odkázat na třídu POINT d…
7. 8. 2018   #381132

#3 gna
Ty složené závorky tam asi být nemusí, ale překladač s tím nemá problém.

Jak pracovat se strukturou buodů vím, o to mi nejde. Jak jsem psal z C++ volám vlastní funkci v x64 assembleru, která má data (x, y) připraví v paměti RAM. Pamět RAM si pro to alokuji pomocí funkce VirtualAlloc. Při vynášení bodů pomocí funkce

Polyline(hdc, apt, 156);

potřebuji v proměnné "apt", nastavit odkaz na místo v paměti RAM, kde mám data uložena. Jde tedy o to nějak "vnutit" proměnné apt adresu RAM paměti, kterou mám k dispozici.

C / C++ › Jak odkázat na třídu POINT d…
7. 8. 2018   #381127

v C++ potřebuji řádek
POINT apt[156]{}

nahradit odkazem na strukturu bodů vektoru, který mám uložen v paměti (z C++ volám vlastní funkci v assembleru) něčím jako:

POINT má_adresa_na_pole_bodů[*(DWORD *)(pocet)]
kde je "počet" pointer na adresu paměti s počtem bodů a "má_adresa_na_pole_bodů" je DWORDLONG pointer (64 bit) na začátek struktury bodů v paměti.

Jak na to ?
 

Petr
C / C++ › C++ Načtení velkého souboru…
22. 4. 2018   #220483

Díky, podívám se na to.

Petr
C / C++ › C++ Načtení velkého souboru…
21. 4. 2018   #220475

Potřebuji načíst najednou velký textový soubor 6,32 GB a zkopírovat z něj některé hodnoty v řádcích do pole o velikosti 50 mil. řádků s pevnou délkou 10 bytů (tj. 0,5 GB). S polem pak bude dále pracovat. V NB mám pamět 24 GB tak by s tím neměl být problém. V C++ jsem ale naprostý začátečník, uvítám např. odkaz, jak na to.

 

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý