Aiuto per risolvere un problema con l'importazione di una funzione da una dll - pagina 9

 

М... Sì... che sfortuna... con programmazione C++ in Bilder... Amico, un sacco di errori di nuovo :'-(

:-) questa decomposizione di svd mi ha già consumato tanto tempo, e sembra che non ci sia una fine in vista.

Scusate la domanda immodesta, ma potreste fare il lavoro per un compenso N-esimo?

Ad essere onesti, mi sto stancando di combatterlo... Sono su questo forum dal 2 settembre, e quanto ho lottato prima... Oooh...

Naturalmente, studierò C++ in futuro, ma ci vorrà del tempo.

Spero davvero nel vostro aiuto.

 

Questa è la funzione di trasformazione singolare di Klot:

su https://www.mql5.com/ru/code/7359

>> void fastsingular( double X[],int n,int l,int s,double &Y[])

Non capisco bene che tipo di calcoli vuoi fare

con matrici bidimensionali.

.

Prova a descrivere il problema.

Se ha senso per me, vi aiuterò.

.

Ho bisogno di vedere passo dopo passo:

Riempi una matrice 3 per 3 con questo, mandalo a quello,

dovremmo ottenere qualcosa.

Passare a matrici più grandi è una questione di tecnica.

 
Scusate la mia domanda immodesta, ma sareste in grado di fare il lavoro per un compenso N-esimo? <br / translate="no">

Buona domanda :-).

 

OK, lasciatemi provare a spiegare...

Stavo guardando il codice MQL di Klot. All'inizio, quando ho trovato il link, ero molto felice, ma dopo aver capito il codice e aver pensato a quello che voglio, ho capito che non è esattamente quello che voglio...

È una ricerca basata sulla bisezione di eigennumeri. Dopo aver letto un po' di letteratura, ho capito che questo algoritmo è buono quando troviamo solo una parte di tutti gli autovalori possibili.

Ma se una matrice quadrata è abbastanza grande, diciamo 1000x1000, trovare tutti gli autovalori attraverso le bise è inefficiente ed è qui che entra in gioco il principio dei moderni algoritmi di decomposizione singolare - portare una matrice ad una forma bidiagonale seguita dalla sua diagonalizzazione tramite l'algoritmo QR. Questo è il testo che porto dal sito http://alglib.sources.ru/. Inoltre c'è la seguente frase: Questo semplice schema è abbastanza operativo, ma può essere migliorato per aumentare considerevolmente la velocità del programma. Lo schema dell'algoritmo migliorato descritto di seguito è quasi completamente preso in prestito dal pacchetto LAPACK (subroutine xGESVD). Descrizione completa dell'algoritmo: http://alglib.sources.ru/matrixops/general/svd.php

Cioè, per i miei compiti ho bisogno di un algoritmo veloce, che lavori con grandi matrici di 1000x1000 o anche più... e ho bisogno esattamente di TUTTI i valori singolari insieme ai vettori, cioè la decomposizione completa. Ecco perché ho scelto la libreria http://alglib.sources.ru/. Soprattutto, visto che c'è già del codice C++ già pronto. C'è un algoritmo di 300 linee, ma è più lento del codice di 3000 linee. All'inizio ho cercato di imparare a lavorare con le dll, in modo da poter compilare la mia dll, ma non ha funzionato. Poi ho provato a riscriverlo da C++ a MQL, ma mi sembrava anche abbastanza difficile capire l'algoritmo e tradurlo in un altro linguaggio. Dopo di che ho deciso di tornare a dll attraverso il forum e chiedere aiuto ai professionisti, perché questa versione sembra essere più universale, non credi? Inoltre, da quanto ho capito, MQL5 sta per essere rilasciato. Non si sa quale sarà la compatibilità con MQL4. Pertanto, sarebbe probabilmente meglio implementare l'idea attraverso una DLL. Mi piacerebbe conoscere la vostra opinione su questo argomento.

Poiché la dimensionalità della matrice quadrata sarà sconosciuta all'ingresso, suggerisco che la matrice bidimensionale sia implementata come una matrice unidimensionale, e una volta che la dimensionalità è nota, usare la funzione ArrayResize per riempirla. E questo sarebbe l'input. Poi viene convertito in ap::real_2d_array per l'input a rmatrixsvd. C'è un metodo:

void setbounds(int iLow1, int iHigh1, int iLow2, int iHigh2)
Allocazione della memoria per l'array. Questo rimuove il vecchio contenuto dell'array e libera la memoria che è stata allocata per esso, poi alloca una nuova area di memoria separata con la dimensione di (iHigh1-iLow1+1)*(iHigh2-iLow2+1) elementi.
La numerazione degli elementi nella nuova matrice per la prima dimensione inizia con iLow1 e finisce con iHigh1, analogamente per la seconda dimensione.
Il contenuto del nuovo array è indefinito.

Cioè, secondo me è un metodo molto conveniente, quando la dimensione dell'array non è conosciuta in anticipo né dalla 1a né dalla 2a dimensione.

Poi dovrebbe essere calcolata la funzione rmatrixsvd stessa che produce e dà i numeri singolari e i vettori singolari in matrici bidimensionali, che sono anche convertiti in matrici unidimensionali e già esportati in MQL per ulteriori elaborazioni.

Questo sembra essere tutto. Credo di non aver dimenticato nulla.

 

È chiaro che vuoi davvero lavorare con una variante difficile.

.

Avete detto che avete un caso di prova.

In cui devi riempire una matrice 3 per 3.

E voi conoscete il risultato.

.

Ora mi dirai cosa dovrebbe andare

alla funzione rmatrixsvd e cosa dovrebbe produrre.

.

Voglio numeri specifici.

 

Esempi

Anche se probabilmente è meglio usare il secondo esempio per controllare. Nel primo, si contano gli eigennumeri. Ma in linea di principio logicamente, se ci mettiamo una matrice 3x3, dovremmo ottenere radici di eigeni sulla diagonale, cioè valori singolari, in ordine decrescente

File:
jgdwni.rar  18 kb
 

Si potrebbe, in linea di principio, cercare altri esempi per controllare... Se questi esempi non vi soddisfano, cercherò altri esempi. Per essere sicuri che l'algoritmo funzioni correttamente...

 

Dalla descrizione di svd.cpp:

Parametri di uscita:
W - contiene valori singolari ordinati in ordine decrescente.
U - se UNeeded=0, non cambia. Vettori singolari di sinistra
non sono calcolati.
se UNeeded=1, contiene i vettori singolari di sinistra (il primo
min(M,N) colonne della matrice U). Un array con elementi numerati
[0..M-1, 0..Min(M,N)-1].
se UNeeded=2, contiene la matrice completa U. Un array con elementi numerati [0.
Matrice numerata di elementi [0..M-1, 0..M-1].
VT - se VTNeeded=0, non viene cambiato. I vettori singolari di destra
non sono calcolati.
se VTNeeded=1, contiene i vettori singolari di destra
(le prime righe min(M,N) della matrice V^T). L'array con numerazione
di elementi [0...min(M,N)-1, 0...N-1].
se VTNeeded=2, contiene la matrice completa V^T. Matrice con
numerando gli elementi [0..N-1, 0..N-1].

 
Si guardano tutti i materiali, le descrizioni, i codici... lo scopo del lavoro... e quanto finirai per prezzare il tuo lavoro e ne discuteremo con te. Mi piacerebbe quindi ottenere il codice sorgente oltre al dll finito e funzionante...
 
Ho grandi speranze per voi!