Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Sparse Linear Algebra: fix subtraction bug gh-20 gh-18

  • Loading branch information...
commit e0c69362cb04531fe66baae4740f16fd17304802 1 parent be4d769
Christoph Ruegg cdrnet authored
69 src/Numerics/LinearAlgebra/Complex/SparseVector.cs
@@ -550,9 +550,74 @@ protected override void DoSubtract(Vector<Complex> other, Vector<Complex> result
550 550 return;
551 551 }
552 552
553   - for (var index = 0; index < Count; index++)
  553 + var otherSparse = other as SparseVector;
  554 + if (otherSparse == null)
  555 + {
  556 + base.DoSubtract(other, result);
  557 + return;
  558 + }
  559 +
  560 + var resultSparse = result as SparseVector;
  561 + if (resultSparse == null)
  562 + {
  563 + base.DoSubtract(other, result);
  564 + return;
  565 + }
  566 +
  567 + // TODO (ruegg, 2011-10-11): Options to optimize?
  568 +
  569 + if (ReferenceEquals(this, resultSparse))
  570 + {
  571 + int i = 0, j = 0;
  572 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  573 + {
  574 + if (i < NonZerosCount && j < otherSparse.NonZerosCount && _nonZeroIndices[i] == otherSparse._nonZeroIndices[j])
  575 + {
  576 + _nonZeroValues[i++] -= otherSparse._nonZeroValues[j++];
  577 + }
  578 + else if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] < otherSparse._nonZeroIndices[j])
  579 + {
  580 + _nonZeroValues[i] -= otherSparse.At(_nonZeroIndices[i]);
  581 + i++;
  582 + }
  583 + else
  584 + {
  585 + var otherValue = otherSparse._nonZeroValues[j];
  586 + if (otherValue != Complex.Zero)
  587 + {
  588 + InsertAtUnchecked(i++, otherSparse._nonZeroIndices[j], -otherValue);
  589 + }
  590 + j++;
  591 + }
  592 + }
  593 + }
  594 + else
554 595 {
555   - result.At(index, At(index) - other.At(index));
  596 + result.Clear();
  597 + int i = 0, j = 0, last = -1;
  598 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  599 + {
  600 + if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] <= otherSparse._nonZeroIndices[j])
  601 + {
  602 + var next = _nonZeroIndices[i];
  603 + if (next != last)
  604 + {
  605 + last = next;
  606 + result.At(next, _nonZeroValues[i] - otherSparse.At(next));
  607 + }
  608 + i++;
  609 + }
  610 + else
  611 + {
  612 + var next = otherSparse._nonZeroIndices[j];
  613 + if (next != last)
  614 + {
  615 + last = next;
  616 + result.At(next, At(next) - otherSparse._nonZeroValues[j]);
  617 + }
  618 + j++;
  619 + }
  620 + }
556 621 }
557 622 }
558 623
69 src/Numerics/LinearAlgebra/Complex32/SparseVector.cs
@@ -580,9 +580,74 @@ protected override void DoSubtract(Vector<Complex32> other, Vector<Complex32> re
580 580 return;
581 581 }
582 582
583   - for (var index = 0; index < Count; index++)
  583 + var otherSparse = other as SparseVector;
  584 + if (otherSparse == null)
  585 + {
  586 + base.DoSubtract(other, result);
  587 + return;
  588 + }
  589 +
  590 + var resultSparse = result as SparseVector;
  591 + if (resultSparse == null)
  592 + {
  593 + base.DoSubtract(other, result);
  594 + return;
  595 + }
  596 +
  597 + // TODO (ruegg, 2011-10-11): Options to optimize?
  598 +
  599 + if (ReferenceEquals(this, resultSparse))
  600 + {
  601 + int i = 0, j = 0;
  602 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  603 + {
  604 + if (i < NonZerosCount && j < otherSparse.NonZerosCount && _nonZeroIndices[i] == otherSparse._nonZeroIndices[j])
  605 + {
  606 + _nonZeroValues[i++] -= otherSparse._nonZeroValues[j++];
  607 + }
  608 + else if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] < otherSparse._nonZeroIndices[j])
  609 + {
  610 + _nonZeroValues[i] -= otherSparse.At(_nonZeroIndices[i]);
  611 + i++;
  612 + }
  613 + else
  614 + {
  615 + var otherValue = otherSparse._nonZeroValues[j];
  616 + if (otherValue != Complex32.Zero)
  617 + {
  618 + InsertAtUnchecked(i++, otherSparse._nonZeroIndices[j], -otherValue);
  619 + }
  620 + j++;
  621 + }
  622 + }
  623 + }
  624 + else
584 625 {
585   - result.At(index, At(index) - other.At(index));
  626 + result.Clear();
  627 + int i = 0, j = 0, last = -1;
  628 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  629 + {
  630 + if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] <= otherSparse._nonZeroIndices[j])
  631 + {
  632 + var next = _nonZeroIndices[i];
  633 + if (next != last)
  634 + {
  635 + last = next;
  636 + result.At(next, _nonZeroValues[i] - otherSparse.At(next));
  637 + }
  638 + i++;
  639 + }
  640 + else
  641 + {
  642 + var next = otherSparse._nonZeroIndices[j];
  643 + if (next != last)
  644 + {
  645 + last = next;
  646 + result.At(next, At(next) - otherSparse._nonZeroValues[j]);
  647 + }
  648 + j++;
  649 + }
  650 + }
586 651 }
587 652 }
588 653
69 src/Numerics/LinearAlgebra/Double/SparseVector.cs
@@ -498,9 +498,74 @@ protected override void DoSubtract(Vector<double> other, Vector<double> result)
498 498 return;
499 499 }
500 500
501   - for (var index = 0; index < Count; index++)
  501 + var otherSparse = other as SparseVector;
  502 + if (otherSparse == null)
  503 + {
  504 + base.DoSubtract(other, result);
  505 + return;
  506 + }
  507 +
  508 + var resultSparse = result as SparseVector;
  509 + if (resultSparse == null)
  510 + {
  511 + base.DoSubtract(other, result);
  512 + return;
  513 + }
  514 +
  515 + // TODO (ruegg, 2011-10-11): Options to optimize?
  516 +
  517 + if (ReferenceEquals(this, resultSparse))
  518 + {
  519 + int i = 0, j = 0;
  520 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  521 + {
  522 + if (i < NonZerosCount && j < otherSparse.NonZerosCount && _nonZeroIndices[i] == otherSparse._nonZeroIndices[j])
  523 + {
  524 + _nonZeroValues[i++] -= otherSparse._nonZeroValues[j++];
  525 + }
  526 + else if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] < otherSparse._nonZeroIndices[j])
  527 + {
  528 + _nonZeroValues[i] -= otherSparse.At(_nonZeroIndices[i]);
  529 + i++;
  530 + }
  531 + else
  532 + {
  533 + var otherValue = otherSparse._nonZeroValues[j];
  534 + if (otherValue != 0.0)
  535 + {
  536 + InsertAtUnchecked(i++, otherSparse._nonZeroIndices[j], -otherValue);
  537 + }
  538 + j++;
  539 + }
  540 + }
  541 + }
  542 + else
502 543 {
503   - result.At(index, At(index) - other.At(index));
  544 + result.Clear();
  545 + int i = 0, j = 0, last = -1;
  546 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  547 + {
  548 + if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] <= otherSparse._nonZeroIndices[j])
  549 + {
  550 + var next = _nonZeroIndices[i];
  551 + if (next != last)
  552 + {
  553 + last = next;
  554 + result.At(next, _nonZeroValues[i] - otherSparse.At(next));
  555 + }
  556 + i++;
  557 + }
  558 + else
  559 + {
  560 + var next = otherSparse._nonZeroIndices[j];
  561 + if (next != last)
  562 + {
  563 + last = next;
  564 + result.At(next, At(next) - otherSparse._nonZeroValues[j]);
  565 + }
  566 + j++;
  567 + }
  568 + }
504 569 }
505 570 }
506 571
69 src/Numerics/LinearAlgebra/Single/SparseVector.cs
@@ -528,9 +528,74 @@ protected override void DoSubtract(Vector<float> other, Vector<float> result)
528 528 return;
529 529 }
530 530
531   - for (var index = 0; index < Count; index++)
  531 + var otherSparse = other as SparseVector;
  532 + if (otherSparse == null)
  533 + {
  534 + base.DoSubtract(other, result);
  535 + return;
  536 + }
  537 +
  538 + var resultSparse = result as SparseVector;
  539 + if (resultSparse == null)
  540 + {
  541 + base.DoSubtract(other, result);
  542 + return;
  543 + }
  544 +
  545 + // TODO (ruegg, 2011-10-11): Options to optimize?
  546 +
  547 + if (ReferenceEquals(this, resultSparse))
  548 + {
  549 + int i = 0, j = 0;
  550 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  551 + {
  552 + if (i < NonZerosCount && j < otherSparse.NonZerosCount && _nonZeroIndices[i] == otherSparse._nonZeroIndices[j])
  553 + {
  554 + _nonZeroValues[i++] -= otherSparse._nonZeroValues[j++];
  555 + }
  556 + else if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] < otherSparse._nonZeroIndices[j])
  557 + {
  558 + _nonZeroValues[i] -= otherSparse.At(_nonZeroIndices[i]);
  559 + i++;
  560 + }
  561 + else
  562 + {
  563 + var otherValue = otherSparse._nonZeroValues[j];
  564 + if (otherValue != 0.0)
  565 + {
  566 + InsertAtUnchecked(i++, otherSparse._nonZeroIndices[j], -otherValue);
  567 + }
  568 + j++;
  569 + }
  570 + }
  571 + }
  572 + else
532 573 {
533   - result.At(index, At(index) - other.At(index));
  574 + result.Clear();
  575 + int i = 0, j = 0, last = -1;
  576 + while (i < NonZerosCount || j < otherSparse.NonZerosCount)
  577 + {
  578 + if (j >= otherSparse.NonZerosCount || i < NonZerosCount && _nonZeroIndices[i] <= otherSparse._nonZeroIndices[j])
  579 + {
  580 + var next = _nonZeroIndices[i];
  581 + if (next != last)
  582 + {
  583 + last = next;
  584 + result.At(next, _nonZeroValues[i] - otherSparse.At(next));
  585 + }
  586 + i++;
  587 + }
  588 + else
  589 + {
  590 + var next = otherSparse._nonZeroIndices[j];
  591 + if (next != last)
  592 + {
  593 + last = next;
  594 + result.At(next, At(next) - otherSparse._nonZeroValues[j]);
  595 + }
  596 + j++;
  597 + }
  598 + }
534 599 }
535 600 }
536 601

0 comments on commit e0c6936

Please sign in to comment.
Something went wrong with that request. Please try again.